AKAZE局部匹配介绍
- AOS构造尺度空间
- Hessian矩阵特征点检测
- 方向指定基于一阶微分图像
- 描述子生成
AKAZE与KAZE的区别带K是快速的
与SIFT/SURF比较
- 更加稳定
- 非线性尺度空间
- AKAZE速度更加快
- 比较新的算法,只有在opencv新版本中才有
- KAZE是日语音译过来的 , KAZE与SIFT、SURF最大的区别在于构造尺度空间,KAZE是利用非线性方式构造,得到的关键点也就更准确(尺度不变性 );
代码演示
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
#define PIC_PATH "/work/opencv_pic/"
#define PIC_NAME "box.png"
#define PIC_PATH1 "/work/opencv_pic/"
#define PIC_NAME1 "box_in_scene.png"
int main(void)
{
Mat subimg,mainimg;
//获取完整的图片路径及名称
string pic1 = string(PIC_PATH)+string(PIC_NAME);
string pic2 = string(PIC_PATH1)+string(PIC_NAME1);
//打印图片路径
cout << "subimg path is :"<<pic1<<endl;
cout << "mainimg path is :"<<pic2<<endl;
//读取图片
subimg = imread(pic1,IMREAD_GRAYSCALE);
mainimg = imread(pic2,IMREAD_GRAYSCALE);
//判断图片是否存在
if(subimg.empty() || mainimg.empty())
{
cout<<"pic is not exist!!!!"<<endl;
return -1;
}
//显示图片
#if 0
namedWindow("subimg pic",WINDOW_AUTOSIZE);
imshow("subimg pic",subimg);
namedWindow("mainimg pic",WINDOW_AUTOSIZE);
imshow("mainimg pic",mainimg);
#endif
Mat kpimg;
Ptr<AKAZE> detector = AKAZE::create();
vector<KeyPoint> keypoints_sub;
vector<KeyPoint> keypoints_main;
Mat descript_sub,descript_main;
detector->detectAndCompute(subimg,Mat(),keypoints_sub,descript_sub);
detector->detectAndCompute(mainimg,Mat(),keypoints_main,descript_main);
//这里使用暴力匹配与flann匹配都可以 flann匹配时注意调整以下参数否则会报错
//FlannBasedMatcher matcher(new flann::LshIndexParams(20,10,2));
BFMatcher matcher;
vector<DMatch> matches;
matcher.match(descript_sub,descript_main,matches);
Mat akazeimg;
drawMatches(subimg,keypoints_sub,mainimg,keypoints_main,matches,akazeimg);
namedWindow("akazeimg display",WINDOW_AUTOSIZE);
imshow("akazeimg display",akazeimg); //匹配点过多
//优化匹配点 寻找最优匹配
float maxdist = 0;
float mindist = 1000;
//通过逐步收敛的办法查找到最大值最小值
for(int i=0;i<descript_sub.rows;i++)
{
float distance = matches[i].distance;
cout<<"distance: "<<distance<<endl;
if(distance>maxdist)
maxdist = distance;
if(distance<mindist)
mindist = distance;
}
//将最大值 最小值打印出来
cout<<"maxdist: "<<maxdist<<endl;
cout<<"mindist: "<<mindist<<endl;
vector<DMatch> goodmatches; //定义最优的距离点集合
for(int i=0;i<descript_sub.rows;i++)
{
float distance = matches[i].distance;
if(distance<=1.3*mindist)
{
//将查找到的最小距离添加到goodmatches中
goodmatches.push_back(matches[i]);
}
}
Mat goodmatchimages;
//绘制匹配点 点数大大减少
drawMatches(subimg,keypoints_sub,mainimg,keypoints_main,goodmatches,goodmatchimages);
imshow("goodmatchimages",goodmatchimages);
waitKey(0);
destroyAllWindows();
return 0;
}