网上有很多关于sift理论知识的介绍,在这里就不赘述了;
附上有关sift特征点提取的相关程序,需要注意的如下:
1. 使用opencv封装好的sift模块时, 需要加上
#include <opencv2/nonfree/nonfree.hpp>
2. SiftFeatureDetector 和 SiftDescriptorExtractor 意义不同,
SiftFeatureDetector 是为提取特征点位置和角度,一般保存到keypoint中,多用于在图中显现特征点;
SiftDescriptorExtractor是真正在后续实验中要用到的特征向量;
在程序中也会有专门讲解。
#include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/nonfree/nonfree.hpp> //sift算子需要用到的 #include <opencv2/legacy/legacy.hpp> #include <vector> using namespace std; using namespace cv; Mat cacSIFTFeatureAndCompare(Mat srcImage1, Mat srcImage2 ) { //灰度及归一化 Mat grayMat1, grayMat2; cvtColor(srcImage1, grayMat1, CV_BGR2GRAY); normalize(grayMat1, grayMat1, 0, 255, NORM_MINMAX); cvtColor(srcImage2, grayMat2, CV_BGR2GRAY); normalize(grayMat2, grayMat2, 0, 255, NORM_MINMAX); //定义sift描述子 SiftFeatureDetector detector; SiftDescriptorExtractor extractor;//特征提取器 //特征点检测 vector<KeyPoint>keypoint1; vector<KeyPoint>keypoint2; detector.detect(grayMat1, keypoint1);//提取到特征点的位置和角度,保存在keypoint detector.detect(grayMat2, keypoint2); //计算特征点描述子 Mat descriptions1, descriptions2; extractor.compute(grayMat1, keypoint1, descriptions1); extractor.compute(grayMat2, keypoint2, descriptions2);//做实验中要用到的 Mat src_description1, src_description2; drawKeypoints(srcImage1,keypoint1,src_description1); drawKeypoints(srcImage2,keypoint2,src_description2); imshow("pic1_descriptions", src_description1); imshow("pic2_descriptions", src_description2); //特征点匹配 匹配用到的是比较简单的匹配 vector<DMatch>matches; BruteForceMatcher<L2<float>>matcher; matcher.match(descriptions1,descriptions2,matches); //二分排序 int N = 80; nth_element(matches.begin(), matches.begin()+N-1,matches.end()); matches.erase(matches.begin()+N, matches.end()); //绘制检测结果 Mat matchMat; drawMatches(srcImage1,keypoint1,srcImage2,keypoint2,matches,matchMat); return matchMat; } int main() { Mat srcImage1 = imread("E:\\my\\pic_save\\angle_y1.jpg", 1); Mat srcImage2 = imread("E:\\my\\pic_save\\angle_x1.jpg", 1); Mat resSiftMatchMat = cacSIFTFeatureAndCompare(srcImage1,srcImage2); imshow("resSiftMatchMat", resSiftMatchMat); waitKey(0); return 0; }