SIFT特征:
SIFT是目前应用最广泛的关键检测和描述算法。关键点描述也称特征点描述,SIFT特征提取充分利用了图像局部信息。
主要包含了四个步骤:疑似特征点检测,去除伪关键点,关键点梯度和方向匹配及特征向量生成。
OpenCV中提供了sift特征描述及提取的类siftFeatureDetector,应用:ocv:class:SIFT来封装用于计算特征描述的子类,该类继承特征描述基类DescriptorExtrator。
应用DescriptorExtractor::create成员函数方法可以支持多种特征描述子操作,常见的描述子包括
"SIFT"---SiftDescriptorExtractor 是一种强制匹配
vector<DMatch> matches;
BruteForceMatcher<L2<float> > matcher;
//bruteForce匹配
matcher.match(descriptors1, descriptors2, matches);
建立一个<L2<float>>类型的匹配器,强制匹配两幅图特征点,将之保存在matches中。"SURF"---SurfDescriptorExtractor
"ORB"---OrbDescriptorExtractor
"BRIEF"---BriefDescriptorExtractor
程序实现:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat cacSIFTFeatureAndCompare(Mat srcImage1, Mat srcImage2)
{
CV_Assert(srcImage1.data != NULL && srcImage2.data != NULL);
//转换为灰度并归一化
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;//SIFT 函数实现的特征检测子封装类
SiftFeatureDetector extractor;//SIFT 来封装的用于计算特征描述子的类
//特征点检测
vector<KeyPoint> keypoints1;
detector.detect(grayMat1, keypoints1);
vector<KeyPoint> keypoints2;
detector.detect(grayMat2, keypoints2);
//计算特征点的描述子
Mat descriptors1;
extractor.compute(grayMat1, keypoints1, descriptors1);
Mat descriptors2;
extractor.compute(grayMat2, keypoints2, descriptors2);
//特征点匹配
vector<DMatch> matches;
BruteForceMatcher<L2<float> > matcher;
//bruteForce匹配
matcher.match(descriptors1, descriptors2, 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, keypoints1, srcImage2, keypoints2, matches, matchMat);
imshow("matchMat", matchMat);
return matchMat;
}
int main()
{
Mat srcImage1 = imread("D:\\Projects\\1.jpg");
if (!srcImage1.data)
return -1;
Mat srcImage2 = imread("D:\\Projects\\11.jpg");
if (!srcImage2.data)
return -1;
//SIFT特征描述
Mat resSiftMatchMat = cacSIFTFeatureAndCompare(srcImage1, srcImage2);
imshow("resSiftMatchMat", resSiftMatchMat);
waitKey(0);
return 0;
}
实现: