opencv之AKAZE局部检测与匹配

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;
}

程序运行效果

在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值