opencv sift需要在2版本,3不行。
步骤
整体步骤
1)原图像—->特征点检测(位置,角度,层)——->特征点描述(16*8维的特征向量)—–>原图目标的特征点集
2)目标图像–>特征点检测——->特征点描述—–>目标图的特征点集
3)两幅图片的特征点集合进行:特征点匹配——–>匹配点矫正
opencv算法步骤
1)读入两幅图片
2)特征点检测
生成一个SiftFeatureDetector的对象,用SIFT特征的探测器来探测一帧图片中SIFT点的特征、然后将特征存到一个KeyPoint
类型的vector中。
KeyPoint:
angle:角度,表示关键点的方向,通过Lowe大神的论文可以知道,为了保证方向不变形,SIFT算法通过对关键点周围邻域进行梯度运算,求得该点方向。-1为初值。
class_id:当要对图片进行分类时,我们可以用class_id对每个特征点进行区分,未设定时为-1,需要靠自己设定-
octave:代表是从金字塔哪一层提取的得到的数据。
pt:关键点点的坐标
response:响应程度,代表着该关键点是该点角点的程度。
size:该点直径的大小
3)特征点描述
对图像所有KEYPOINT提取其特征向量,通过SiftDescriptorExtractor
提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。
4、对两幅图的特征向量进行匹配,得到匹配值。
代码
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include<opencv2/legacy/legacy.hpp>
#include "opencv2/nonfree/features2d.hpp" //SurfFeatureDetector实际在该头文件中
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat src = imread("1.jpg", 1);
Mat src2 = imread("2.jpg", 1);//旋转后
if (!src.data||!src2.data)
{
cout << " --(!) Error reading images " << endl;
}
//1--初始化SIFT检测算子
int minHessian = 40;
SiftFeatureDetector detector(minHessian);
//2--使用SIFT算子检测特征点
vector<KeyPoint> kp1,kp2;
detector.detect(src, kp1);
detector.detect(src2, kp2);
//--绘制特征点
Mat keypointImg, keypointImg2;
drawKeypoints(src, kp1, keypointImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
imshow("SIFT kp1", keypointImg);
cout << "keypoint1 number: " << kp1.size() << endl;
drawKeypoints(src, kp2, keypointImg2, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
imshow("SIFT kp2", keypointImg2);
cout << "keypoint2 number: " << kp2.size() << endl;
//3--特征向量提取
SiftDescriptorExtractor extractor;
Mat descriptor1, descriptor2;
extractor.compute(src, kp1, descriptor1);
extractor.compute(src2, kp2, descriptor2);
//imshow("desc", descriptor1);
//cout << endl << descriptor1 << endl;
//4--特征匹配
BruteForceMatcher<L2<float>> matcher;
vector<DMatch> matches;
Mat img_matches;
matcher.match(descriptor1, descriptor2, matches);
//--绘制匹配
drawMatches(src, kp1, src2, kp2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);
return 0;
}
匹配效果一般。安倍匹配还可以(可能秋田犬的缘故),默克尔鼻子跑墙上去了..