网上有很多关于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;
}