OpenCV中ORB特征提取与匹配

Posted OpenCV学堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV中ORB特征提取与匹配相关的知识,希望对你有一定的参考价值。

OpenCV中ORB特征提取与匹配

FAST特征点定位

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

假设存在连续N个点满足

OpenCV中ORB特征提取与匹配

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

BRIEF特征描述子

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

OpenCV中ORB特征提取与匹配

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

OpenCV中ORB特征提取与匹配

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

旋转不变性

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

OpenCV中ORB特征提取与匹配

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

OpenCV中ORB特征提取与匹配

计算得到角度为:

OpenCV中ORB特征提取与匹配

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

OpenCV中ORB特征提取与匹配

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

 
   
   
 
  1. #include <opencv2/opencv.hpp>

  2. #include <iostream>

  3. #include <math.h>

  4. #define RATIO    0.4

  5. using namespace cv;

  6. using namespace std;

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

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

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

  10.    if (scene.empty()) {

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

  12.        return -1;

  13.    }

  14.    imshow("input image", scene);

  15.    vector<KeyPoint> keypoints_obj, keypoints_sence;

  16.    Mat descriptors_box, descriptors_sence;

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

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

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

  20.    vector<DMatch> matches;

  21.    // 初始化flann匹配

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

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

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

  25.    // 发现匹配

  26.    vector<DMatch> goodMatches;

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

  28.    float maxdist = 0;

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

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

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

  32.    }

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

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

  35.            goodMatches.push_back(matches[i]);

  36.    }

  37.    Mat dst;

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

  39.    imshow("output", dst);

  40.    waitKey(0);

  41.    return 0;

  42. }

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

OpenCV中ORB特征提取与匹配

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

 
   
   
 
  1. Ptr<DescriptorMatcher> matcher = makePtr<FlannBasedMatcher>

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

运行结果:


为学患无疑,疑则进也


关注【OpenCV学堂】

长按或者扫码下面二维码即可关注

+OpenCV学习群 376281510

进群暗号:OpenCV



以上是关于OpenCV中ORB特征提取与匹配的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV+Python特征提取算法与图像描述符之SIFT / SURF / ORB

特征提取与匹配基础矩阵单应矩阵极限约束

opencv ORB特征匹配

OpenCV——ORB特征检测与匹配

OpenCV.20190628

opencv2.4.10里怎么调用orb