2012-01-13 40 views
4

我知道已经有几个问题同题问在这里,但我找不到任何帮助。OpenCV的冲浪和离群值检测

所以我想比较2张图片,看看它们有多相似,我使用众所周知的find_obj.cpp演示来提取海浪描述符,然后为匹配使用flannFindPairs。

但你也知道这种方法不丢弃异常值,我想知道真正的积极匹配的号码,以便我可以计算这两个图像的相似程度。

我已经看到这个问题:Detecting outliers in SURF or SIFT algorithm with OpenCV和那里的家伙建议使用findFundamentalMat,但是一旦你得到了基本矩阵,我怎么能从矩阵中得到离群值/真正的正数呢?谢谢。

回答

5

下面是从descriptor_extractor_matcher.cpp样品可用一个片段从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); 

关键线,用于滤波在这里进行的:

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

其是测量之间的L2范数距离点(如果没有指定,则为3个像素,或用户定义的像素重投影错误数)。

希望有帮助!

+0

谢谢你的回答......我自认为是在C语言编写的,这片段是C++不能直接在find_obj.cpp使用此代码。然而,我已经在SURFFlannMatcher.cpp演示中尝试过了,它并没有给出好的结果。例如,如果我得到同一个对象,同一场景的两张图片,即几乎相同的图片但不同的分辨率,findHomography函数将只能找到异常值并且没有内部值...这很奇怪。 – user1148222 2012-01-19 15:21:26

1

您可以使用名为“ptpairs”矢量的大小,以决定如何在similiar照片是。 此向量包含匹配的关键点,所以他的大小/ 2是匹配的数量。 我认为你可以使用ptpairs的大小除以关键点的总数来设置适当的阈值。 这可能会给你一个他们之间的相似的估计。