采用Lowe‘s的算法选出优秀匹配点。
#include "highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/legacy/legacy.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat image01 = imread("C:\\Users\\Administrator\\Desktop\\1_A.jpg", 1);
Mat image02 = imread("C:\\Users\\Administrator\\Desktop\\1_B.jpg", 1);
imshow("p1", image01);
imshow("p2", image02);
//灰度图转换
Mat image1, image2;//声明表示图像的向量
cvtColor(image01, image1, CV_RGB2GRAY);//将彩色图像灰度化,输出为image1
cvtColor(image02, image2, CV_RGB2GRAY);
//提取特征点
SiftFeatureDetector siftDetector(800);//构造SIFT特征检测器,Hessian矩阵阈值,在这里调整精度,值越大点越少,越精准
vector<KeyPoint> keyPoint1, keyPoint2;//特征点的向量
siftDetector.detect(image1, keyPoint1);//检测SIFT特征
siftDetector.detect(image2, keyPoint2);
//特征点描述,为下边的特征点匹配做准备
SiftDescriptorExtractor SiftDescriptor;//构造SIFT描述子提取器
Mat imageDesc1, imageDesc2;//声明表示图像的向量
SiftDescriptor.compute(image1, keyPoint1, imageDesc1);//提取SIFT描述子
SiftDescriptor.compute(image2, keyPoint2, imageDesc2);
FlannBasedMatcher matcher;//构造匹配器
vector<vector<DMatch> > matchePoints;//匹配点的向量
vector<DMatch> GoodMatchePoints;//更好匹配点的向量
//不太明白
vector<Mat> train_desc(1, imageDesc1);
matcher.add(train_desc);
matcher.train();
matcher.knnMatch(imageDesc2, matchePoints, 2);
cout << "total match points: " << matchePoints.size() << endl;//一共的匹配点数
// Lowe's algorithm,获取优秀匹配点
for (int i = 0; i < matchePoints.size(); i++)
{
if (matchePoints[i][0].distance < 0.6 * matchePoints[i][1].distance)//如果最近的距离除以次近的距离得到的比率ratio少于某个阈值T,则接受这一对匹配点
{
GoodMatchePoints.push_back(matchePoints[i][0]);
}
}
Mat first_match;
drawMatches(//使用函数 drawMatches来绘制检测到的匹配点
image02, keyPoint2, //第一幅图像及其特征点
image01, keyPoint1, //第二幅图像及其特征点
GoodMatchePoints, //匹配结果
first_match//生成的图像
);
imshow("first_match ", first_match);
imwrite("C:\\Users\\Administrator\\Desktop\\first_match.jpg", first_match);
waitKey();
return 0;
}
输入图像:
输出图像:
匹配点明显减少