计算机视觉
图像处理

尺度不变特征变换匹配算法SIFT(2)

SIFT算法
      在10月初,草草学习了一下SIFT(可以戳这里查看),主要是调用opencv函数库了的函数进行了实践,而并没有深入了解SIFT描述子的原理以及opencv中相关函数的用法和参数说明。本篇blog作为LZ的小笔记,记录一下opencv中相关函数的说明,对于SIFT特征的原理后续将花时间继续了解。
C++代码   环境:vs2010+opencv2.3.1+win7 ×64
这部分代码还是使用上一篇SIFT的代码,本篇重在了解一些函数和数据结构。
  1. #include <opencv2/opencv.hpp>
  2. #include <istream>
  3. using namespace std;
  4. using namespace cv;
  5. int main()
  6. {
  7.     //read the two input images
  8.     Mat image1 = imread(“image1.jpg”);
  9.     Mat image2 = imread(“image2.jpg”);
  10.     //if failed
  11.     if(image1.empty()||image2.empty())
  12.     {
  13.         cout<<“error,the image is not exist”<<endl;
  14.         return -1;
  15.     }
  16.     //difine a sift detector
  17.     SiftFeatureDetector siftDetector;
  18.     //store key points
  19.     vector<KeyPoint> keypoint1,keypoint2;
  20.     //detect image with SIFT,get key points
  21.     siftDetector.detect(image1,keypoint1);
  22.     Mat outImage1;
  23.     //draw key points at the out image and show to the user
  24.     drawKeypoints(image1,keypoint1,outImage1,Scalar(255,0,0));
  25.     imshow(“original_image1”,image1);
  26.     imshow(“sift_image1”,outImage1);
  27.     Mat outImage2;
  28.     siftDetector.detect(image2,keypoint2);
  29.     drawKeypoints(image2,keypoint2,outImage2,Scalar(255,0,0));
  30.     imshow(“sift_image2.jpg”,outImage2);
  31.     //imwrite(“sift_result2.jpg”,outImage2);
  32.     //store 10 keypoints in order to watch the effect clearly
  33.     vector<KeyPoint> keypoint3,keypoint4;
  34.     for(int i=0;i<10;i++)
  35.     {
  36.         keypoint3.push_back(keypoint1[i]);
  37.         keypoint4.push_back(keypoint2[i]);
  38.     }
  39.     // difine a sift descriptor extractor
  40.     SiftDescriptorExtractor extractor;
  41.     //store the descriptor of each image
  42.     Mat descriptor1,descriptor2;
  43.     BruteForceMatcher<L2<float>> matcher;
  44.     vector<DMatch> matches;
  45.     Mat img_matches;
  46.     //compute the descriptor of each image
  47.     extractor.compute(image1,keypoint3,descriptor1);
  48.     extractor.compute(image2,keypoint4,descriptor2);
  49.     //match
  50.     matcher.match(descriptor1,descriptor2,matches);
  51.     //show the result
  52.     drawMatches(image1,keypoint3,image2,keypoint4,matches,img_matches,Scalar(255,0,0));
  53.     imshow(“matches”,img_matches);
  54.     //store the match_image
  55.     //imwrite(“matches.jpg”,img_matches);
  56.     waitKey(0);
  57.     return 0;
  58. }
opencv相关函数和数据结构说明
1.drawMatcher():Draws the found matches of keypoints from two images.
参考:http://docs.opencv.org/2.4/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html
C++: void drawMatches(const Mat& img1, const vector<KeyPoint>& keypoints1, const Mat& img2, const  vector<KeyPoint>& keypoints2, const vector<vector<DMatch>>& matches1to2,    Mat& outImg, const Scalar& matchColor=Scalar::all(-1),  const Scalar& singlePointColor=Scalar::all(-1),   const vector<vector<char>>& matchesMask=vector<vector<char> >(), int flags=DrawMatchesFlags::DEFAULT )
  • img1 – First source image.
  • keypoints1 – Keypoints from the first source image.
  • img2 – Second source image.
  • keypoints2 – Keypoints from the second source image.
  • matches1to2 – Matches from the first image to the second one, which means that keypoints1[i] has a corresponding point in keypoints2[matches[i]] .
  • outImg – Output image. Its content depends on the flags value defining what is drawn in the output image. See possible flags bit values below.
  • matchColor – Color of matches (lines and connected keypoints). If matchColor==Scalar::all(-1) , the color is generated randomly.
  • singlePointColor – Color of single keypoints (circles), which means that keypoints do not have the matches. If singlePointColor==Scalar::all(-1) , the color is generated randomly.
  • matchesMask – Mask determining which matches are drawn. If the mask is empty, all matches are drawn.
  • flags – Flags setting drawing features. Possible flags bit values are defined by DrawMatchesFlags.

2.DMatch:Class for matching keypoint descriptors: query descriptor index, train descriptor index, train image index, and distance between descriptors.

可参考:http://docs.opencv.org/master/d4/de0/classcv_1_1DMatch.html

  1. <span style=”font-family:Microsoft YaHei;”>       struct DMatch
  2.        {
  3.               //三个构造函数
  4.            DMatch(): queryIdx(-1), trainIdx(-1),imgIdx(-1),distance(std::numeric_limits<float>::max()) {}
  5.            DMatch(int  _queryIdx, int  _trainIdx, float  _distance ) :
  6.                             queryIdx( _queryIdx),trainIdx( _trainIdx), imgIdx(-1),distance( _distance) {}
  7.            DMatch(int  _queryIdx, int  _trainIdx, int  _imgIdx, float  _distance ) :
  8.                    queryIdx(_queryIdx), trainIdx( _trainIdx), imgIdx( _imgIdx),distance( _distance) {}
  9.            intqueryIdx;  //此匹配对应的查询图像的特征描述子索引
  10.            inttrainIdx;   //此匹配对应的训练(模板)图像的特征描述子索引
  11.            intimgIdx;    //训练图像的索引(若有多个)
  12.            float distance;  //两个特征向量之间的欧氏距离,越小表明匹配度越高。
  13.            booloperator < (const DMatch &m) const;
  14.        };</span>

一般使用Brute-force descriptor matcher进行匹配,结果并不具有可读性(戳这里看图),那么这里请留意匹配的结果保存在了vector<DMatch>定义的动态数组matches中,这就意味着我们可以对匹配结果进行一系列操作,比如再drawMatches()函数前添加一句:matches.erase(matches.begin()+25,matches.end()); 既可以选择最新的25个匹配结果。

转载注明来源:CV视觉网 » 尺度不变特征变换匹配算法SIFT(2)

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

0不错 1超赞 0无聊 0扯淡 0不解 0路过

评论 抢沙发

评论前必须登录!