【图像特征提取6】ORB特征点的描述----BRIEF描述子

(一)BRIEF描述子

           在ORB特征提取的第一步根据FAST角点检测算法检测出特征点(角点、兴趣点、关键点)之后,我们需要以某种方式来描述这些特征点的属性。对于这些特征点的描述算法,我们称之为特征点的描述子(Feature DescritorS).ORB特征提取算法采用BRIEF描述子来描述这些特征点的属性。
        BRIEF算法的核心思想是在关键点P的周围以一定的方式选取N个点对,然后把这N个点对的边角结果组合起来作为该关键点的描述子。具体来讲,可以分为以下几步:
        1)以关键点P为圆心,以R为半径huayuan
        2)在圆O内某一区域选取N个点对。这里为了方便说明,我们假设N=4,即我们在圆区域内选取4对点对,在实际应用中,我们可以选取512对点对。假设选取的4对点对分别为:P1(A,B),P2(A,B),P3(A,B),P4(A,B)
        3)我们定义操作T(P(A,B))为:                        1   ;   A>B
                                                       T(P(A,B))  =  

                                                                                      0  ;  A<=B

        4)分别对已经选取的点对进行T操作,将得到的结果进行组合。如下所示:

            那么,这个关键点最终的描述子为:1011

(二)理想特征点的描述子应该具备哪些属性呢?

       在现实生活中,我们从不同的距离、不同的方向、不同的角度、不同的光照条件下观察一个物体时,物体的大小、形状、亮度分布都会有所不同。但是,我们的大脑中依然可以判断它是同一个物体。理想的特征描述子就应该具备这样的性质。即对于大小、方向旋转、灰度亮度变化的图像中,同一特征点应该具有相似的特征描述子,我们将此称为描述子的可复现性。

         当我们以理想的方式计算图像中关键点的描述子的时候,同样的特征点,在不同的图像中应该具有相同的结果。即描述子对于光照、旋转、尺度具有一定的鲁棒性。

      上面我们用BRIEF算法得到的描述子并不具备以上这些性质。因此,我们得想办法改进我们的算法。ORB并没有解决尺度一致性的问题,OpenCv中实现的ORB算法采用图像金字塔来改善这方面的性能。ORB算法主要解决了BRIEF描述子不具有旋转不变性的问题。

       回顾一下BRIEF描述子的计算过程:在当前关键点P的周围以一定方式选取N个点对,组合这N个点对的T操作的结果,这个组合结果就为这个关键点最终的描述子。当我们选取点对的时候,是以当前关键点为原点,以水平方向为X轴,以垂直方向为Y轴建立坐标系。当图片发生旋转时,坐标系不变,同样的取点模式,取出来的点却不一样,计算得到的描述子也不一样,这是不符合我们要求的。因此,我们需要重新建立坐标系,使新的坐标系可以随着图片的旋转而旋转。这样我们以相同的取点模式取出来的点就具有一致性。

      打个比方,我们有一个印章,上面刻着一些直线。用这个印章在一张图片上盖一个章子,图片上的某个点被取出来。印章不变动的情况下,转动下图片,再盖一个章子,但是这次取出来的点对就和之前的不一样。为了使2次取出来的点一样,我们需要将章子也旋转同一个角度,再盖章。ORB在计算BRIEF描述子的时候,建立的坐标系是以关键点为圆心,以关键点和取点区域的形心的连线为X轴建立的2维坐标系 。在下图中,P为关键点。圆内为取点的区域,每个小格子代表一个像素。现在我们把这块圆心看做一块木板,木板上每个点的质量等于其对应的像素值。根据积分学的知识,我们可以求出这个密度不均匀木板的质心Q。计算公式如下所示,其中R为圆的半径。我们知道圆心是固定的,而且随着物体的旋转而旋转,当我们以PQ为坐标时,在不同的旋转角度下,我们以同一取点模式取出来的点是一致的,这就解决了旋转一致性的问题。




(三)特征点的匹配

            ORB算法最大的特点就是计算速度快。这首先得益于ORB算法使用FAST检测特征点,FAST的检测速度正如它的名字一样,是出了名的块。其次是,ORB使用了BRIEF算法计算的描述子,该描述子特有的2进制串的表现形式不仅节约了存储空间,而且大大缩短了匹配的时间。特征点之间如何匹配,我们可以举个例子进行说明,如下所示,我们有关键点A和B,并且A和B的描述子如下所示:
A:10101011
B:10101010
      我们可以设定一个阈值,比如相似度80%。当A和B的描述子的相似度大于80%的时候,我们就判定A和B是相同的特征点,即这两个点匹配成功。在这个例子中,A和B只有最后一位不同,相似度为87.5%,大于80%,因此,我们认为A和B是相互匹配的。我们将A和B进行异或操作,可以很轻松的计算出A和B的相似度。而异或操作可以借助硬件完成,并且具有很高的效率,这也加速了匹配的速度。

(四)ORB在OpenCv中的示例程序

/********************************************************************************************************
文件说明:
       ORB的特征检测与匹配
开发环境:
        Win7 + OpenCv2.4.8 + VS2012
时间地点:
        陕西师范大学 2017.3.17
作    者:
        九 月
*********************************************************************************************************/
#include <iostream>
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/features2d/features2d.hpp>

using namespace cv; 
using namespace std;


/********************************************************************************************************
函数描述:
         计算图像中的ORB特征及其特征点的匹配
*********************************************************************************************************/
bool cacORBFeatureAndCompare(cv::Mat srcImg_1,cv::Mat srcImg_2)
{
	//【1】图像中ORB关键点的检测
	std::vector<cv::KeyPoint>  keyPoints_1;
	std::vector<cv::KeyPoint>  keyPoints_2;

	cv::ORB  orb;
	orb.detect(srcImg_1,keyPoints_1);                          //【1】图像1中ORB关键点的检测
	orb.detect(srcImg_2,keyPoints_2);                          //【2】图像2中ORB关键点的检测

	//【2】计算特征向量(特征点的描述子)
	cv::Mat descriptorMat_1;                                   //【1】图像1的特征点描述子
	cv::Mat descriptorMat_2;                                   //【2】图像1的特征点描述子

	orb.compute(srcImg_1,keyPoints_1,descriptorMat_1);         //【1】计算图像1的特征向量
	orb.compute(srcImg_2,keyPoints_2,descriptorMat_2);         //【2】计算图像2的特征向量

	//【3】特征点的匹配
	cv::BFMatcher        matcher(NORM_HAMMING);
	std::vector<DMatch>  matches;
	matcher.match(descriptorMat_1,descriptorMat_2,matches);

	//【4】绘制匹配点集
	cv::Mat matchMat;
	cv::drawMatches(srcImg_1,keyPoints_1,srcImg_2,keyPoints_2,matches,matchMat);
	cv::imshow("matchMat",matchMat);
	cv::waitKey(0); 
	return true;
}

int main(int argc, char** argv) 
{ 
    cv::Mat srcImg_1 = imread("temp.jpg"); 
	if(srcImg_1.empty())
	{
		std::cout<<"【NOTICE】NO valid inout image_1 was given,please check the inoput image! "<<std::endl;
		std::system("pause");
		return -1;
	}
	cv::Mat srcImg_2 = imread("temp.jpg");
	if(srcImg_1.empty())
	{
		std::cout<<"【NOTICE】NO valid inout image_2 was given,please check the inoput image! "<<std::endl;
		std::system("pause");
		return -1;
	}
	//ORB特征点的检测和匹配
	cacORBFeatureAndCompare(srcImg_1,srcImg_2); 
    return 0; 
}



 


  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值