C++ - 使用ORB进行OpenCV特征检测

4

我正在尝试使用OpenCV中的ORB进行特征提取和匹配,使用FLANN进行匹配,但是我得到了一个非常奇怪的结果。在加载我的2张图像并将它们转换为灰度图像后,这是我的代码:

// Initiate ORB detector
    Ptr<FeatureDetector> detector = ORB::create();

// find the keypoints and descriptors with ORB
    detector->detect(gray_image1, keypoints_object);
    detector->detect(gray_image2, keypoints_scene);

    Ptr<DescriptorExtractor> extractor = ORB::create();
    extractor->compute(gray_image1, keypoints_object, descriptors_object );
    extractor->compute(gray_image2, keypoints_scene, descriptors_scene );

// Flann needs the descriptors to be of type CV_32F
    descriptors_scene.convertTo(descriptors_scene, CV_32F);
    descriptors_object.convertTo(descriptors_object, CV_32F);

    FlannBasedMatcher matcher;
    vector<DMatch> matches;
    matcher.match( descriptors_object, descriptors_scene, matches );

    double max_dist = 0; double min_dist = 100;

    //-- Quick calculation of max and min distances between keypoints
    for( int i = 0; i < descriptors_object.rows; i++ )
    {
        double dist = matches[i].distance;
        if( dist < min_dist ) min_dist = dist;
        if( dist > max_dist ) max_dist = dist;
    }

    //-- Use only "good" matches (i.e. whose distance is less than 3*min_dist )
    vector< DMatch > good_matches;

    for( int i = 0; i < descriptors_object.rows; i++ )
    {
        if( matches[i].distance < 3*min_dist )
        {
            good_matches.push_back( matches[i]);
        }
    }


    vector< Point2f > obj;
    vector< Point2f > scene;


    for( int i = 0; i < good_matches.size(); i++ )
    {
        //-- Get the keypoints from the good matches
        obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
        scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
    }

    // Find the Homography Matrix
    Mat H = findHomography( obj, scene, CV_RANSAC );
    // Use the Homography Matrix to warp the images
    cv::Mat result;
    warpPerspective(image1,result,H,Size(image1.cols+image2.cols,image1.rows));
    cv::Mat half(result,cv::Rect(0,0,image2.cols,image2.rows));
    image2.copyTo(half);
    imshow( "Result", result );

这是我得到的奇怪结果的截图:截图

可能出了什么问题呢?

谢谢!


似乎是匹配不良的结果 - 计算出的转换导致“不现实”的结果。请查看示例中所做的匹配。 - PhilLab
我正在做完全相同的事情,不是吗?唯一的区别是他们的示例使用SurfDescriptorExtractor,这是不免费使用的,所以我不能使用它。 - YaronGh
但是您正在使用不同的图像 - 也许您的图像匹配效果不太好。通过imshow(“Good Matches”,img_matches);(参见示例)查看您的匹配情况。 - PhilLab
是的,你说得对,我尝试了另一组图像,它起作用了!我只是没有意识到奇怪的结果是由于特征匹配不良引起的。谢谢! - YaronGh
好的,我从我的评论中编译了一个答案。 - PhilLab
2个回答

2
您正在经历匹配结果不佳的问题:适合数据的单应矩阵不是“真实的”,因此会扭曲图像。
您可以使用imshow("Good Matches", img_matches);来调试您的匹配,就像示例中所做的那样。
有多种方法可以改善您的匹配:
  1. 使用crossCheck选项
  2. 使用SIFT比率测试
  3. cv::findHompgraphy中使用输出数组mask识别完全错误的单应计算
  4. ...等等...

0

ORB是二进制特征向量,无法与Flann一起使用。请改用Brute Force(BFMatcher)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接