Я хочу получить только качественные очки - PullRequest
0 голосов
/ 02 июля 2018

В настоящее время я работаю над сопоставлением функций в реальном времени с использованием OpenCV3.4.0, c ++ в QT creator.

Мой код соответствует функциям между первым кадром, полученным веб-камерой, и текущим кадром, введенным с веб-камеры.

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);

Но код возвращает так много совпадающих точек, что я не могу различить, какая из них соответствует какой.

Итак, есть ли способы получить только качественные сопоставленные точки?

А как я могу получить пиксельные координаты каждой совпавшей точки в QT создателе так же, как MATLAB?

1 Ответ

0 голосов
/ 04 июля 2018

Итак, есть ли способы получить только качественные совпадающие точки?

Бьюсь об заклад, есть много разных методов. Я использую, например, тест на симметрию. Поэтому совпадения от img1 до img2 также должны существовать при сопоставлении с img2 до img1. Я использую тест Улучшение соответствия характерных точек с 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;
            }
        }
    }
}

Как говорит Андраш Ковач в ответе, вы также можете рассчитать фундаментальную матрицу с помощью RANSAC для устранения выбросов с помощью cv::findFundamentalMat.

И как я могу получить пиксельные координаты каждой совпавшей точки в QT создателе так же, как MATLAB?

Надеюсь, я правильно понял, что вы хотите, чтобы координаты точек совпадали. Я извлекаю координаты точек после симметрии. Координаты находятся внутри ключевых точек.

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>>
    }

Вы можете сделать то же самое с вашими matches, keypoints1 и keypoint2.

...