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

C++ - OpenCV feature detection with ORB

本文关键字:OpenCV 特征检测 进行 ORB 使用 C++      更新时间:2023-10-16

我正在尝试使用 ORB 进行检测和 FLANN 进行匹配,使用 OpenCV 提取和匹配特征,我得到了一个非常奇怪的结果。加载我的 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 );

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

可能有什么问题?

谢谢!

您正在经历错误匹配的结果:拟合数据的单应性不"真实",因此扭曲了图像。

您可以调试与imshow( "Good Matches", img_matches );的匹配,如示例中所示。

有多种方法可以改善匹配:

  1. 使用交叉检查选项
  2. 使用 SIFT 比率测试
  3. 使用 cv::findHompgraphy 中的 OutputArray mask 来识别完全错误的单应性计算
  4. 。等等...

ORB 是不适用于 Flann 的二进制特征向量。请改用蛮力(BFMatcher)。