前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV中ORB特征提取与匹配

OpenCV中ORB特征提取与匹配

作者头像
OpenCV学堂
发布2018-04-04 11:28:53
4.4K0
发布2018-04-04 11:28:53
举报

OpenCV中ORB特征提取与匹配

FAST特征点定位

ORB - (Oriented Fast and Rotated BRIEF)算法是基于FAST特征检测与BRIEF特征描述子匹配实现,相比BRIEF算法中依靠随机方式获取二值点对,ORB通过FAST方法,FAST方式寻找候选特征点方式是假设灰度图像像素点A周围的像素存在连续大于或者小于A的灰度值,选择任意一个像素点P,假设半径为3,周围16个像素表示如下:

假设存在连续N个点满足

则像素点P被标记为候选特征点、通常N取值为9、12,上图N=9。 为了简化计算,我们可以只计算1、9、5、13四个点,至少其中三个点满足上述不等式条件,即可将P视为候选点。

BRIEF特征描述子

得到特征点数据之后,根据BRIEF算法就可以建立描述子。选择候选特征点周围SxS大小的像素块、随机选择n对像素点,定义如下:

其中P(x)是图像模糊处理之后的像素值,原因在于高斯模糊可以抑制噪声影响、提供特征点稳定性,在实际代码实现中通常用均值滤波替代高斯滤波以便利用积分图方式加速计算获得更好的性能表现。常见滤波时候使用3x3~9x9之间的卷积核。滤波之后,根据上述描述子的生成条件,得到描述子表达式如下:

作者论文提到n的取值通常为128、256或者512。得到二进制方式的字符串描述子之后,匹配就可以通过XOR方式矩形,计算汉明距离。ORB特征提取跟纯BRIEF特征提取相比较,BRIEF方式采用随机点方式得最终描述子、而ORB通过FAST得到特征点然后得到描述子。

旋转不变性

ORB比BRIEF方式更加合理,同时具有旋转不变性特征与噪声抑制效果,ORB实现选择不变性特征,是通过对BRIEF描述子的特征点区域的计算得到角度方向参数。主要原理是使用几何距公式。图像的几何距计算公式如下:

其中n=p+q称为N阶距。得到中心坐标为:

计算得到角度为:

ORB算法根据角度参数提取BRIEF描述子,实现旋转不变性特征。随机ORB算法通过贪心算法进一步发现低相关性描述子作为最终二值字符串描述子输出。通常是256位的特征描述子,完整的ORB特征描述子算法流程图如下:

OpenCV中基于ORB特征对象匹配代码演示如下:

代码语言:javascript
复制
#include <opencv2/opencv.hpp>

#include <iostream>

#include <math.h>

#define RATIO    0.4

using namespace cv;

using namespace std;


int main(int argc, char** argv) {

    Mat box = imread("D:/vcprojects/images/box.png");

    Mat scene = imread("D:/vcprojects/images/box_in_scene.png");

    if (scene.empty()) {

        printf("could not load image...\n");

        return -1;

    }

    imshow("input image", scene);

    vector<KeyPoint> keypoints_obj, keypoints_sence;

    Mat descriptors_box, descriptors_sence;

    Ptr<ORB> detector = ORB::create();

    detector->detectAndCompute(scene, Mat(), keypoints_sence, descriptors_sence);

    detector->detectAndCompute(box, Mat(), keypoints_obj, descriptors_box);


    vector<DMatch> matches;

    // 初始化flann匹配

    // Ptr<FlannBasedMatcher> matcher = FlannBasedMatcher::create(); // default is bad, using local sensitive hash(LSH)

    Ptr<DescriptorMatcher> matcher = makePtr<FlannBasedMatcher>(makePtr<flann::LshIndexParams>(12, 20, 2));

    matcher->match(descriptors_box, descriptors_sence, matches);


    // 发现匹配

    vector<DMatch> goodMatches;

    printf("total match points : %d\n", matches.size());

    float maxdist = 0;

    for (unsigned int i = 0; i < matches.size(); ++i) {

        printf("dist : %.2f \n", matches[i].distance);

        maxdist = max(maxdist, matches[i].distance);

    }

    for (unsigned int i = 0; i < matches.size(); ++i) {

        if(matches[i].distance < maxdist*RATIO)

            goodMatches.push_back(matches[i]);

    }


    Mat dst;

    drawMatches(box, keypoints_obj, scene, keypoints_sence, goodMatches, dst);

    imshow("output", dst);


    waitKey(0);

    return 0;

}

在OpenCV中基于BRIEF与ORB特征实现FLANN对象匹配经常会遇到一个错误如下:

原因是BRIEF与ORB特征是二进制的CV_8U而SIFT与SURF特征数据是浮点数,FLANN默认的匹配是基于浮点数运算计算距离,所以导致了类型不支持错误,这个时候只要使用如下的方法重新构造一下FLANN指针,然后调用match方法即可。

代码语言:javascript
复制
Ptr<DescriptorMatcher> matcher = makePtr<FlannBasedMatcher>

                          (makePtr<flann::LshIndexParams>(12, 20, 2));

运行结果:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • OpenCV中ORB特征提取与匹配
  • FAST特征点定位
  • BRIEF特征描述子
  • 旋转不变性
  • OpenCV中基于ORB特征对象匹配代码演示如下:
    • 在OpenCV中基于BRIEF与ORB特征实现FLANN对象匹配经常会遇到一个错误如下:
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档