利用opencv实现sift matching

来源:互联网 发布:龙卷风中心知乎 编辑:程序博客网 时间:2024/05/16 09:52

实际上在opencv的example里有一个matcher_simple.cpp的文件就实现了SURF的匹配。在做sift matching的时候只要把surf改成sift就可以了。接下来还是先上源码

#include <stdio.h>#include <core/core.hpp>#include <features2d/features2d.hpp>#include <highgui/highgui.hpp>#include <nonfree/nonfree.hpp>using namespace cv;int main(int argc, char ** argv){Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);Mat img1_mask = imread(argv[3], CV_LOAD_IMAGE_GRAYSCALE);SiftFeatureDetector detector;vector<KeyPoint> keypoints1, keypoints2;detector.detect(img1, keypoints1, img1_mask);detector.detect(img2, keypoints2);SiftDescriptorExtractor extractor;Mat descriptors1, descriptors2;extractor.compute(img1, keypoints1, descriptors1);extractor.compute(img2, keypoints2, descriptors2);BFMatcher matcher(NORM_L2);vector<DMatch> matches;matcher.match(descriptors1, descriptors2, matches);namedWindow("matches", 1);Mat img_matches;drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);imshow("matches", img_matches);waitKey(0);return 0;}

在这里的SiftFeatureDetector和SiftDescriptorExtractor如果我们去看源码的话会发觉都是typedef SIFT。而detect和compute两个方法一个是用来检测key point,另一个是用来计算找到的keypoint的descriptors。这里不再多说。

对于BFMatcher,这里用的是L2 norm,当然这个是看个人的需求的。这里需要多说的一点就是,假设我不想要在图上画,而是要将对应的点保存起来,比如说保存成txt模式要怎么办?这里的每个DMatch都代表了一对对应点的match信息,而DMatch类里的queryIdx和trainIdx分别代表了第一个点集和第二个点集中对应的下标。也就是说keypoints1下标为queryIdx的点和keypoints下标为trainIdx的点是对应的。所以如果要保存对应信息可以在之前的代码最后就加入以下代码段:

FILE *fp = fopen("matches.txt", "w");vector<DMatch>::iterator itr;for (itr = matches.begin(); itr!= matches.end(); itr++){Point p1 = keypoints1[(*itr).queryIdx].pt;Point p2 = keypoints2[(*itr).trainIdx].pt;fprintf(fp, "x1=%d y1=%d x2=%d y2=%d distance=%f\n", p1.x, p1.y, p2.x, p2.y, (*itr).distance);}fclose(fp);


原创粉丝点击