Definition of OpenCV Surf and Outliers

I know that there are already several questions with the same question that I asked here, but I could not find any help.

So, I want to compare 2 images to see how similar they are, and I use the famous find_obj.cpp demo to retrieve surf descriptors, and then I use flannFindPairs for matching.

But, as you know, this method does not reject outliers, and I would like to know the number of true positive matches so that I can understand how similar these two images are.

I already saw this question: Detecting outliers in a SURF or SIFT algorithm with OpenCV , and the guy there suggests using findFundamentalMat, but as soon as you get the fundamental matrix, how can I get the outliers / true positive value from this matrix? Thanks.

+4
source share
2 answers

Here is a snippet from descriptor_extractor_matcher.cpp sample available from OpenCV:

if( !isWarpPerspective && ransacReprojThreshold >= 0 ) { cout << "< Computing homography (RANSAC)..." << endl; vector<Point2f> points1; KeyPoint::convert(keypoints1, points1, queryIdxs); vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, trainIdxs); H12 = findHomography( Mat(points1), Mat(points2), CV_RANSAC, ransacReprojThreshold ); cout << ">" << endl; } Mat drawImg; if( !H12.empty() ) // filter outliers { vector<char> matchesMask( filteredMatches.size(), 0 ); vector<Point2f> points1; KeyPoint::convert(keypoints1, points1, queryIdxs); vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, trainIdxs); Mat points1t; perspectiveTransform(Mat(points1), points1t, H12); double maxInlierDist = ransacReprojThreshold < 0 ? 3 : ransacReprojThreshold; for( size_t i1 = 0; i1 < points1.size(); i1++ ) { if( norm(points2[i1] - points1t.at<Point2f>((int)i1,0)) <= maxInlierDist ) // inlier matchesMask[i1] = 1; } // draw inliers drawMatches( img1, keypoints1, img2, keypoints2, filteredMatches, drawImg, CV_RGB(0, 255, 0), CV_RGB(0, 0, 255), matchesMask #if DRAW_RICH_KEYPOINTS_MODE , DrawMatchesFlags::DRAW_RICH_KEYPOINTS #endif ); #if DRAW_OUTLIERS_MODE // draw outliers for( size_t i1 = 0; i1 < matchesMask.size(); i1++ ) matchesMask[i1] = !matchesMask[i1]; drawMatches( img1, keypoints1, img2, keypoints2, filteredMatches, drawImg, CV_RGB(0, 0, 255), CV_RGB(255, 0, 0), matchesMask, DrawMatchesFlags::DRAW_OVER_OUTIMG | DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); #endif } else drawMatches( img1, keypoints1, img2, keypoints2, filteredMatches, drawImg ); 

Key lines for filtering are done here:

 if( norm(points2[i1] - points1t.at<Point2f>((int)i1,0)) <= maxInlierDist ) // inlier matchesMask[i1] = 1; 

Which measures the distance of the L2 norm between points (either 3 pixels, if nothing is specified, or a user-defined number of errors when reproducing pixels).

Hope this helps!

+5
source

you can use a vector size called "ptpairs" to decide how similar the pictures are. this vector contains matching key points, so its size / 2 is the number of matches. I think you can use the ptpairs size divided by the total number of key points to set the appropriate threshold. this will probably give you an assessment of the similarities between the two.

+1
source

Source: https://habr.com/ru/post/917512/


All Articles