c++ Opencv sift位置检测

c++ Opencv sift Positiondetection

本文关键字:检测 位置 sift Opencv c++      更新时间:2023-10-16

我使用ubuntu和代码是在c++与opencv。我测试了一下,以检测图片的某些部分。它工作得很好,但现在我想在我的大局中找到自己的位置。下面是代码:

#include...
using namespace cv;
int main(int argc, char** argv) {

Mat img = imread("/home/ubuntu/workspace2/sift/src/inputklein.jpg",CV_LOAD_IMAGE_GRAYSCALE);

 while(1){
             Mat img2 =imread("/home/ubuntu/workspace2/sift/src/input.jpeg",CV_LOAD_IMAGE_GRAYSCALE);   //frame
             //initialize SIFT
             // Create smart pointer for SIFT feature detector.
             SIFT sift;
             vector<KeyPoint> key_points;
             vector<KeyPoint> key_points2;
             //-- Step 1: Detect the keypoints using SURF Detector
             int minHessian = 100;
             SurfFeatureDetector detector( minHessian );
             detector.detect( img, key_points );
             detector.detect( img2, key_points2 );
             //-- Step 2: Calculate descriptors (feature vectors)
             SurfDescriptorExtractor extractor;
             Mat descriptors1;
             Mat descriptors2;
             extractor.compute( img, key_points, descriptors1 );
             extractor.compute( img2, key_points2, descriptors2 );

             //-- Step 3: Matching descriptor vectors using FLANN matcher
              FlannBasedMatcher matcher;
              std::vector< DMatch > matches;
              matcher.match( descriptors1, descriptors2, matches );
              double max_dist = 20; double min_dist = 10;

              //-- Quick calculation of max and min distances between keypoints
                for( int i = 0; i < descriptors1.rows; i++ )
                { double dist = matches[i].distance;
                  if( dist < min_dist ) min_dist = dist;
                  if( dist > max_dist ) max_dist = dist;
                }
               //std::cout<<"Max dist :"<< max_dist ;
               //std::cout<<"Min dist :"<< min_dist ;
               //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
                //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
                //-- small)
                //-- PS.- radiusMatch can also be used here.
                std::vector< DMatch > good_matches;
                for( int i = 0; i < descriptors1.rows; i++ )
                { if( matches[i].distance <= max(2*min_dist, 0.02) )
                  { good_matches.push_back( matches[i]); }
                }
                //-- Draw only "good" matches
                Mat img_matches;
                drawMatches( img, key_points, img2, key_points2,
                             good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
                             vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

              //std::cout<<key_points[1].pt.x<<"n";
              //std::cout<<key_points2[1].pt.y<<"n";

   //-- 3. Apply the classifier to the frame

         cv::imshow( "test", img_matches ); //img_matches
        waitKey(30);
 }
return 0;
}

好的,但是我怎样才能得到关键点最多的位置呢?谁能给我点提示,我应该怎么理解它?我发现我可以用这样的东西:"key_points[1].pt.x"或y,但我不是必须检查每个x,y位置吗?下一个是:good_matches[1]。queryIdx,但这里是相同的问题。我怎样才能找到它呢?

  • 对我来说,一个大问题是,为什么只有一个循环过行?难道它不应该是一排一排的吗?在我的目的地,它应该像在一个数组(x,y),我检查每个位置,如果它是相同的…(有问题没有简单的数据类型…)

  • 在哪里我可以找到/或如何drawMatches(例如)的代码的位置。正常情况下,我会尝试"Open Declaration"(使用Eclipse、c++),但我只看到头文件,而不是真正的函数。我需要代码,希望我可以改变所有没有opencv,或者也许我可以做循环…所以我必须了解如何读取和使用矢量DMatch…

  • 谢谢你的帮助。最好的祝福,

    如果我理解得好,你会找到关键点位置并对它们进行分类。要知道关键点的位置,你需要在关键点向量上画一个圆圈,并将位置保存在矩阵中。

    然后当你可以比较这个关键点的位置与图像区域(无论你想要什么),并根据它们在图像中的区域对它们进行分类。

    Mat pointsInFirstAreaRight, pointInFirstAreaLeft;
        for (int i = 0; i < 2; i++){
               for(vector<DMatch>::const_iterator it = keypoints[i].begin(); it!= keypoints[i].end(); ++it){
                     // Get the position of keypoints
                     float x = [it->queryIdx].pt.x;
                     float y = [it->queryIdx].pt.y;
                     //If the point detected are in the 20 first pixels   
                     if ( (x < 20) && (y > 20) )
                     {
                           //Classify this point in this area
                           if ( i == 0)
                           pointsInFirstAreaRight.push_back(Point2f(x, y));
                           else if (i == 1)
                           pointsInFistAreaLeft.push_back(Point2f(x, y));
                      }
              }
         }
    

    关于sift函数,它可以同时进行检测和提取。我在代码中这样使用它:

    >  SIFT sift;
    >         
    >         /* get keypoints on the images */
    >         sift(imagenI, Mat(), keypoints[0], descriptors[0]);
    >         sift(imagenD, Mat(), keypoints[1], descriptors[1]);
    

    ,然后我检测关键点,提取点的描述符。

    那么我只需要做匹配。

    我希望能帮到你。