我只想获得高质量的特征点

时间:2018-07-02 04:12:10

标签: c++ opencv feature-extraction feature-detection

我目前正在使用QT Creator中的c ++ OpenCV3.4.0进行实时功能匹配。

我的代码使网络摄像头获得的第一帧与网络摄像头当前输入的帧之间的功能匹配。

Mat frame1, frame2, img1, img2, img1_gray, img2_gray;
int n = 0;
VideoCapture cap1(0);
namedWindow("Video Capture1", WINDOW_NORMAL);
namedWindow("Reference img", WINDOW_NORMAL);
namedWindow("matches1", WINDOW_NORMAL);

moveWindow("Video Capture1",50, 0);
moveWindow("Reference img",50, 100);
moveWindow("matches1",100,100);



while((char)waitKey(1)!='q'){
       //raw image saved in frame
       cap1>>frame1;

       n=n+1;
       if (n ==1){
           imwrite("frame1.jpg",  frame1);
           cout<<"First frame saved as 'frame1'!!"<<endl;
       }
       if(frame1.empty())
       break;


       imshow("Video Capture1",frame1);

       img1 = imread("frame1.jpg");
       img2 = frame1;

       cvtColor(img1, img1_gray, cv::COLOR_BGR2GRAY);
       cvtColor(img2, img2_gray, cv::COLOR_BGR2GRAY);

       imshow("Reference img",img1);

       // detecting keypoints
       int minHessian = 400;
       Ptr<Feature2D> detector = xfeatures2d::SurfFeatureDetector::create();
       vector<KeyPoint> keypoints1, keypoints2;
       detector->detect(img1_gray,keypoints1);
       detector->detect(img2_gray,keypoints2);

       // computing descriptors
       Ptr<DescriptorExtractor> extractor = xfeatures2d::SurfFeatureDetector::create();
       Mat descriptors1, descriptors2;
       extractor->compute(img1_gray,keypoints1,descriptors1);
       extractor->compute(img2_gray,keypoints2,descriptors2);

       // matching descriptors
       BFMatcher matcher(NORM_L2);
       vector<DMatch> matches;
       matcher.match(descriptors1, descriptors2, matches);

       // drawing the results

       Mat img_matches;
       drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
       imshow("matches1", img_matches);

但是代码返回了很多匹配点,以至于我无法分辨出哪一个匹配。

那么,有什么方法只能获取高质量的匹配点吗?

如何像MATLAB一样在QT创建器中获取每个匹配点的像素坐标?

1 个答案:

答案 0 :(得分:0)

  

那么,有什么方法只能获取高质量的匹配点吗?

我敢打赌,有很多不同的方法。我正在使用例如对称测试。因此,从img2到img1匹配时,还必须存在从img1到img2的匹配。我正在测试Improve matching of feature points with OpenCV。那里显示了其他多项测试。

void symmetryTest(const std::vector<cv::DMatch> &matches1,const std::vector<cv::DMatch> &matches2,std::vector<cv::DMatch>& symMatches)
{
    symMatches.clear();
    for (vector<DMatch>::const_iterator matchIterator1= matches1.begin();matchIterator1!= matches1.end(); ++matchIterator1)
    {
        for (vector<DMatch>::const_iterator matchIterator2= matches2.begin();matchIterator2!= matches2.end();++matchIterator2)
        {
            if ((*matchIterator1).queryIdx ==(*matchIterator2).trainIdx &&(*matchIterator2).queryIdx ==(*matchIterator1).trainIdx)
            {
                symMatches.push_back(DMatch((*matchIterator1).queryIdx,(*matchIterator1).trainIdx,(*matchIterator1).distance));
                break;
            }
        }
    }
}

就像安德拉斯·科瓦奇(AndrásKovács)所说,您也可以使用cv::findFundamentalMat使用RANSAC计算基本矩阵以消除异常值。

  

如何像MATLAB一样在QT Creator中获取每个匹配点的像素坐标?

我希望我能正确理解您想要的同源点的点坐标是否匹配。我在symmetryTest之后提取点的坐标。 坐标在关键点之内。

for (size_t rows = 0; rows < sym_matches.size(); rows++) {

        float x1 = keypoints_1[sym_matches[rows].queryIdx].pt.x;
        float y1 = keypoints_1[sym_matches[rows].queryIdx].pt.y;        

        float x2 = keypoints_2[sym_matches[rows].trainIdx].pt.x;
        float y2 = keypoints_2[sym_matches[rows].trainIdx].pt.y;

        // Push the coordinates in a vector e.g. std:vector<cv::Point2f>>
    }

您可以对matcheskeypoints1keypoint2进行同样的操作。