mask - OpenCV: How to get inlier points using findHomography()/findFundamental() and RANSAC -
opencv not provide ransac-function per se or @ least in such form can call , done (e.g. cv::ransac(...)
). functions/methods able use ransac have flag enables it. not useful if want else inliers ransac computes after have estimated homography/fundamental matrix example create nice plot in octave or similar software/library of points, apply additional algorithms on remaining set of filtered matches etc.
after matching 2 images 1 gets vector of matches. along have of course 2 sets of keypoints (one each image) used in matching process. using matches , keypoints create 2 vectors of points (e.g. cv::point2f points
) , pass these findhomography()
. this , this posts discovered how inliers marked using mask, pass function. each row inside mask relates inlier/outlier. unable figure out how use row-index information 2 sets of points. looking @ opencv's source code didn't me far. in findfundamental()
(similar findhomography()
when comes signature , mask-part) use compresspoints()
, seems somehow combine 2 sets have input (source , destination points) one. while testing in order determine nature of mask tried 2 sets of matched points (converted cv::keypoints
cv::point2f
- standard procedure). each set contains 300 points in total have 600 points. returned mask contains 300 rows (values not important topic @ hand).
edit: while writing discovered answer (see below) decided post question anyway in case needs information possible , in compact form. note still need 1 of opencv's function, support ransac. if have set of points no intention of computing homography or fundamental matrix, not way , dare unable find useful in opencv's api can avoid obstacle therefore need use external library.
the solution quite trivial. know each row in our mask gives information if have inlier or outlier. have 2 sets of points input how row containing single value represent 2 points? nature of sort of indexing appeared in mind while thinking how 2 sets of points appear in findhomography() (in case computing homography between 2 images). both sets have equal number of points in them because of simple fact extracted matches between our pair of images. means row in our mask actual index of points in 2 sets , index in vector of matches 2 images. have managed manually refer small subset of matched points based on , results expected. important don't alter order of matches , 2d points have extracted them using keypoints referenced in each cv::dmatch
. below can see simple example single pair of inliers.
for(int = 0; < matchesobjectscene.size(); ++i) { // extract points keypoints based on matches pointsobject.push_back(keypointsobject.at(matchesobjectscene.at(i).queryidx).pt); pointsscene.push_back(keypointsscene.at(matchesobjectscene.at(i).trainidx).pt); } // compute homography using ransac cv::mat mask; cv::mat h = cv::findhomography(pointsobject, pointsscene, cv_ransac, ransacthreshold, mask);
in example above if print inlier
int maskrow = 10; std::cout << "points: object(" << pointsobject.at(maskrow).x << "," << pointsobject.at(maskrow).y << ") - scene(" << pointsscene.at(maskrow).x << "," << pointsscene.at(maskrow).y << ")" << std::endl;
and again time using our keypoints (can done extracted 2d points)
std::cout << "points (via match-set): object(" << keypointsobject.at(matchescurrentobject.at(maskrow).queryidx).pt.x << "," << keypointsobject.at(matchescurrentobject.at(maskrow).queryidx).pt.y << ") - scene(" << keypointsscene.at(matchescurrentobject.at(maskrow).trainidx).pt.x << "," << keypointsscene.at(matchescurrentobject.at(maskrow).trainidx).pt.y << ")" << std::endl;
we same output:
points: object(462,199) - sscene(485,49) points (via match-set): object(462,199) - scene(485,49)
to actual inlier have check if current row in mask contains 0 or non-zero value:
if((unsigned int)mask.at<uchar>(maskrow)) // store match or keypoints or points somewhere can access them later
Comments
Post a Comment