SIFT、SURF、ORB、HOG、LBP、HAAR特征的原理概述及OpenCV代码实现

什么叫特征检测?就是检测图像中目标的特征呗,所谓特征,不管你怎么旋转目标,离目标远近,它的特征都应不变才对,这两个特性称为叫旋转不变性和尺度不变性。当然还有其它特征,如光照不一样,也不应该变化嘛,只是旋转不变性和尺度不变性是最基本的两个要求。

对特征的描述有很多种方法和算子,常见的有SIFT特征描述算子、SURF特征描述算子、ORB特征描述算子、HOG特征描述、LBP特征描述以及Harr特征描述。本文先介绍SIFT特征描述算子、SURF特征描述算子、ORB特征描述算子、HOG特征描述、LBP特征描述的原理及OpenCV代码袜现,当然我只能大概介绍,如果要了解详细原理,请查看相应的论文及资料。

代码链接:https://blog.csdn.net/amusi1994/article/details/79591205

参考文章:

机器视觉特征提取介绍:HOG、SIFT、SURF、ORB、LBP、HAAR

OpenCV-Python Feature2D 特征点检测(含SIFT/SURF/ORB/KAZE/FAST/BRISK/AKAZE)

图像特征描述SIFT、SURF、ORB、HOG、HAAR、LBP特征的原理概述

一、SIFT特征描述算子:尺度不变特征转换(Scale-invariant feature transform或SIFT)

SIFT是目前应用最广泛的关键点检测和描述算法(PS:具体是不是这样,博主也不清楚,只是资料上是这么写得,因为它的算法复杂度是很高的?这样也能用最字来描述么?那你让后面我要提到的ORB特征描述怎么想?),SITF算法首先被David.G.Lowe提出并发表在文章“Distinctive Image Features from Scale-Invariant Keypoints”中,其中Scale-Invariant的意思是尺度不变性,尺度不变性的概念我在本博文的第一段已经叙述了。SIFT特征提取充分利用了图像局部信息,它包含以下优点:

⑴SIFT特征具有旋转、尺度、平移、视角及亮度不变性,有利于对目标特征信息进行有效表达。

⑵SIFT特征对参数调整鲁棒性好,在进行特征描述时,根据场景需要可调整适宜的特征点数量,以便进行特征分析。

SIFT特征算法对图像局部特征点的提取主要包括4个步骤:疑似特征点检测、去除伪特征点、特征点梯度与方向匹配及特征描述向量生成。

SITF的缺点是如果不借助硬件加速或专门的图像处理器很难达到实现。

步骤1-疑似特征点检测

特征点在某些情况下是图像中的角点,然而由于SIFT特征需要特征点包含尺度及方向,因此需要建立相应的图像尺度空间,高斯函数是唯一可以产生尺度空间的核因子。让图像与高斯函数卷积可以实现多尺度操作(你可以联想前面介绍的图像缩放中的高斯金字塔来理解这一点)。对原始特征点作进一步过滤时不被滤掉的条件是:该点需要满足上下尺度平面集在进行差分高斯操作时对应的26个点中的极值,26个点分别是上平面对应的9个检测点,待检测平面邻域点8个,下平面对应的9个检测点。(PS:不需要完全看懂判断条件,因为你不懂原理是不可能看懂的)

步骤2-去除伪特征点

上一步骤得到的疑似特征点,高斯差分算子对边缘及噪声相对敏感,会产生伪边缘信息和伪极值响应信息。可以通过分析高斯差分算子的特性来去除因上述原因造成的伪特征点。具体怎么分析,我这里就不作介绍了,有需要了解的可以去查阅相关论文和资料。

步骤3-特征点梯度及方向分配

通过前面两步只实现了图像尺度不变性的特征提取,在这一部实现旋转不变性特征的提取。具体的计算方法我这里就不多说了,因为不是一两句话能说清楚的,没有学习过算法本身的话根本是理解不到的,所以大家如果要知道还不如去看算法提出的论文。

步骤4-特征描述:特征向量生成

特征描述通常是指把图像中的特征点的特征生成向量的过程。每个SIFT特征包含128维特征。具体这128维特征的结构为16×8=128

OpenCV提供了类SiftFeatureDetector和SiftDescriptorExtractor来实现SIFT特征检测,具体怎么用,大家一看代码就知道了,这里就不再叙述了。值得注意的是,SIFT和下面要介绍的SURF的源代码都在OpenCV的nonfree模块中,意思是这是有知识版权保护的算法,如果要使用,可能要向原作者给版权费哦,在OpenCV的3.0.0版中,还没有SIFT和SURF算法,所以我只好换回到了2.4.13版,实现代码如下:

代码中用到的图像的下载链接为http://pan.baidu.com/s/1skUJo9B:

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84339444获取

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84339444获取

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84339444获取

运行结果如下图所示:

二、SURF特征描述算子:speeded-Up Robust Features

前面提到SITF的缺点是如果不借助硬件加速或专门的图像处理器很难达到实现,所以人们就要想办法对SITF算子进行改进,SURF算子便是对SIFT的改进,不过改进之后在算法的运行时间上还是没有质的飞跃,后文要介绍的ORB特征描述算子在运行时间上才是一种质的飞跃,后文会介绍ORB特征描述算子,说回来,这一部分咱们说SURF算子。

SURF特征描述子是Herbert Bay等人在2006年发表的论文“SURF:Speeded Up Robust Features”中提出的,正如我上一段所述,该算法对经典SIFT特征进行了改进,但是改进之后性能提升还是有限的。

SURF主要是把SIFT中的某些运算作了简化。SURF把SIFT中的高斯二阶微分的模板进行了简化,使得卷积平滑操作仅需要转换成加减运算,这样使得SURF算法的鲁棒性好且时间复杂度低。SURF最终成生的特征点特征向量的维度为64维。

 

OpenCV提供了类SurfFeatureDetector和SurfDescriptorExtractor来实现SURF特征检测,具体怎么用,大家一看代码就知道了,这里就不再叙述了。值得注意的是,SIFT和下面要介绍的SURF的源代码都在OpenCV的nonfree模块中,意思是这是有知识版权保护的算法,如果要使用,可能要向原作者给版权费哦,在OpenCV的3.0.0版中,还没有SIFT和SURF算法,所以我只好换回到了2.4.13版,实现代码如下:

代码中用到的图像的下载链接为http://pan.baidu.com/s/1skUJo9B:

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84341387获取 

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84341387获取

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84341387获取

运行结果如下图所示:

三、ORB特征描述(Oriented FAST and Rotated BRIEF)

ORB特征描述算法的运行时间远优于SIFT与SURF,可用于实时性特征检测。ORB特征基于FAST角点的特征点检测与描述技术,该算法是Ethan Rubleed 在论文“ORB:An efficient alternative to SIFT or SURF”中提出的。ORB特征具有尺度与旋转不变性,同时对噪声及透视仿射也具有不变性,良好的性能使得得用ORB在进行特征描述时的应用场景十分广泛。

ORB特征检测主要分为以下两个步骤。

步骤①方向FAST特征点检测

FAST角点检测是一种基于机器学习的快速角点特征检测算法,具有方向的FAST特征点检测是对兴趣点所在圆周上的16个像素点进行判断,若判断后的当前中心像素点为暗或亮,将瘊定其是否为角点。前面我已经写了一篇博文(moravec、harris、Shi-Tomasi角点检测的简介及OpenCV代码实现)介绍角点检测的常用方法,FAST角点检测相对于这些方法来说,计算的时间复杂度小,检测效果突出。FAST角点检测为加速算法实现,通常先对回周上的点集进行排序,排序使得其计算过程大大得到了优化。FAST对多尺度特性的描述是还是通过建立图像金字塔实现的,而对于旋转不变性即方向的特征则引入灰度质心法用于描述特征点的方向。

步骤②BRIEF特征描述

BRIEF描述子主要是通过随机选取兴趣点周围区域的若干点来组成小兴趣区域,将这些小兴趣区域的灰度二值化并解析成二进制码串,将串特征作为该特征点的描述子,BRIEF描述子选取关键点附近的区域并对每一位比较其强度大小,然后根据图像块中两个二进制点来判断当前关键点编码是0还是1.因为BRIEF描述子的所有编码都是二进制数的,这样就节省了计算机存储空间。

OpenCV提供了类ORB来实现ORB特征检测,代码如下:

代码中用到的图像的下载链接为http://pan.baidu.com/s/1skUJo9B:

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84346615获取

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84346615获取

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84346615获取

代码运行结果如下图所示:

四、方向梯度直方图HOG(Histogram of Oriented Gridients的简写)

方向梯度直方图(Histogram of Oriented Gradient,HOG)特征是Dalal于2005年针对行人检测问题提出的直方图特征,常应用于目标物体检测与特征分析,HOG特征描述在行人检测算法中性能表现优秀,结合SVM分类技术已广泛应用在图像识别与分析领域。HOG是通过计算和统计图像局部区域的梯度方向直方图来实现特征描述的。至于有没有旋转不变性和尺度不变性,博主暂且不知。

图像梯度方向直方图将图像划分成小部分连通区域,对这些划分出来的细胞单元各个像素点进行梯度方向的的直方图描述,最后级合成相应的特征描述器。梯度方向直方图特征提取步骤如下:

①归一化处理。归一化操作是为了提高图像特征描述对光照及环境变化的鲁棒性,降低图像局部的阴影、局部曝光过多及纹理失真,尽可能抵制噪声干扰。归一化处理操作是先将图像转换为灰度图像,再利用伽马校正实现。

②计算图像梯度。

③统计梯度方向。

④特征向量归一化。为克服光照不均匀变化及前景与背景的对比差异,需要对块内的特征向量进行归一化处理。

⑤生成特征向量。

OpenCV中提供了专门用于HOG特征检测的类HOGDescriptor,该类提供了多种成员函数方法,HOGDesciptor方法完成HOG初始化参数,行人检测默认参数实现方法getDefaultPeopleDetector,目标单尺度检测方法是detect,目标多尺度检测方法是detectMultiScale。在这篇博文中,不用OpenCV提供的这个现成的类实现HOG实现检测,等会儿贴出的代码是用户自己写的代码,以后有空再上使用类HOGDescriptor实现HOG检测的代码。下面说下等儿贴出的代码的实现思路(PS:思路只是作个大概描述,如果真要看懂,还是要先把原理搞清楚的)。

步骤① 在进行HOG特征描述实现时,需要完成对积分图的计算。首先对源图像进行水平与竖直方向的Sobel边缘检测;初始化直方图bins,将Sobel检测结果利用cartToPolar进行坐标转换,再将对应的矩阵角度进行分段变换;然后遍历图像,计算对应角度下的bins幅值,进而生成对应的区域积分图。这部分在代码中对应的函数名为CalculateIntegralHOG.
步骤② HOG特征计算。传统HOG特征计算的时间复杂度较高,在实际进行特征描述时一般采用积分直方图来代替,像素点(x,y)积分直方图为梯度图像中满足矩形区域所有像素点的梯度方向直方图。这部分在代码中对应的函数名为cacHOGinCell.

 

步骤③ 利用前面两步的结果生成相应的方向梯度直方图牲,绘制HOG特征图。

 

HOG特征提取算法流程如下图所示:

HOG特征计算实现代码如下(代码中用到的图像下载链接为https://pan.baidu.com/s/1dFhVUpF):

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84346758获取

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84346758获取

代码请访问博文https://blog.csdn.net/lehuoziyuan/article/details/84346758获取

 

运行结果如下图所示:

五、局部二值模式LBP(Local Binary Patterns,局部二值模式)

LBP(Local Binary Pattern),局部二值模式是一种描述图像局部纹理的特征算子,该算子是由T.Ojala等人于1994年首次提出的,后经过发展改进可应用于图像特征分析,该算子具有旋转不变性与灰度不变性等显著优点。LBP特征描述的是一种灰度范围内的图像处理操作技术,针对的是输入源为8位或16位的灰度图像。LBP特征是高效的图像特征分析方法,经过改进与发展已经应用于多个领域之中,特别是人脸识别、表情识别、行人检测领域已经取得了成功。LBP牲征将窗口中心点与邻域点的关系进行比较,重新编码形成新特征以消除对外界场景对图像的影响,因此一定程度上解决了复杂场景下(光照变换)特征描述问题。

LBP算法根据窗口领域的不同分为经曲LBP和圆形LBP两种。下面分别介绍:

①经典LBP

经典LBP的算子窗口为3×3的正方形窗口,以窗口中心像素为阈值,将其相邻8领域像素灰度与中心像素值比较,若中心像素值小于周围像素值,则该中心像素位置被标记为1,否则为0(显然这种规则下,对于中心点大于或等于这两种情况,算法无法区分,后续经过改进引入LBP+与LBP-因子用来区分这两种情况)。图像经过这种遍历操作后,图像就被二值化了,每一个窗口中心的8邻域点都可以由8位二进制数来表示,即可产生256种LBP码,这个LBP码值可以用来反映窗口的区域纹理信息。LBP具体在生成的过程中,先将愿意图像划分为若干个子区域,子区域窗口可根据原图像的尺寸进行调整,而不一定非得为3×3的正方形窗口。一般对于512×640的图像,子区域窗口区域选取大小为16×16.

②圆形LBP

经典LBP用正方形8-领域来描述图像的纹理特征,其缺点是难以满足不同尺寸和频率的需求。Ojala等人对经典LBP进行了改进,提出了将3×3的正方形窗口领域扩展到任意圆形领域。由于圆形LBP采样点在圆形边界上,那么必然会导致部分计算出来的采样点坐标不是整数,因此这里就需要对得到的坐标像素点值进行处理,常用的处理方法是最近邻插值或双线性插值。

OpenCV中提供了模板类LBP来实现LBP算法,LBP的相关操作存放在facerec.cpp中。这里我们不使用LBP类来实现LBP算法,因为经典LBP算法实现起来很简单,于是自己写代码,以后有缘再补充使用OpenCV的LBP类来实现LBP算法的代码。

六、HAAR (哈尔特征)
Haar特征分为三类:边缘特征,线性特征,中心特征和对角线特征,组合成特征模板。(白色矩形像素减去黑色矩形像素和。)采用积分图加速运算 
参考: 
http://blog.csdn.net/zouxy09/article/details/7929570/ 
http://blog.csdn.net/zouxy09/article/details/7922923

七、Harris角点

基本原理:人眼对角点的识别通常是在一个局部的小区域或小窗口完成的。

角点定义:窗口向任意方向的移动都导致图像灰度的明显变化。

如果这个特定的窗口在图像各个方向上移动时,窗口内图像的灰度没有发生变化,那么窗口内就不存在角点;如果窗口在某一个方向移动时,窗口内图像的灰度发生了较大的变化,而在另一些方向上没有发生变化,那么,窗口内的图像可能就是一条直线的线段。

平坦区域(左):任意方向移动,无灰度变化

边缘(中):沿着边缘方向移动,无灰度变化

角点(右):沿任意方向移动,明显灰度变化

八、FAST 

前面已经介绍了很多图像特征检测算子,我们可以用LoG或者DoG检测图像中的Blobs(斑点检测),可以根据图像局部的自相关函数来求得Harris角点(Harris角点),后面又提到了两种十分优秀的特征点及它们的描述方法SIFT特征与SURF特征。SURF特征算是为了提高运算效率对SIFT特征的一种近似,虽然在有些实验环境中已经达到了实时,但是我们实践工程应用中,特征点的提取与匹配只是整个应用算法中的一部分,所以我们对于特征点的提取必须有更高的要求,从这一点来看前面介绍的的那些特征点方法都不可取。

      为了解决这个问题,Edward Rosten和Tom Drummond在2006年发表的“Machine learning for high-speed corner detection”文章中提出了一种FAST特征,并在2010年对这篇论文作了小幅度的修改后重新发表。FAST的全称为Features From Accelerated Segment Test。Rosten等人将FAST角点定义为:若某像素点与其周围领域内足够多的像素点处于不同的区域,则该像素点可能为角点。也就是某些属性与众不同,考虑灰度图像,即若该点的灰度值比其周围领域内足够多的像素点的灰度值大或者小,则该点可能为角点。(FAST主要用于角点检测)

算法步骤:

(1)从图片中选取一个像素P,下面我们将判断它是否是一个特征点。我们首先把它的亮度值设为Ip。

(2)设定一个合适的阈值t。

(3)考虑以该像素点为中心的一个半径为3像素的离散化的Bresenham圆,则圆边界上有16个像素。

(4)现在,如果在这个大小为16个像素的圆上有n个连续的像素点,它们的像素值要么都比Ip+t大,要么都比Ip−t小,那么它就是一个角点。n的值可以设置为12或者9,实验证明选择9可能会有更好的效果。

上面的算法中,对于图像中的每一个点,我们都要去遍历其邻域圆上的16个点的像素,效率较低。我们下面提出了一种高效的测试(high-speed test)来快速排除一大部分非角点的像素。该方法仅仅检查在位置1,9,5和13四个位置的像素,首先检测位置1和位置9,如果它们都比阈值暗或比阈值亮,再检测位置5和位置13。如果P是一个角点,那么上述四个像素点中至少有3个应该必须都大于Ip+t或者小于Ip−t,因为若是一个角点,超过四分之三圆的部分应该满足判断条件。如果不满足,那么p不可能是一个角点。对于所有点做上面这一部分初步的检测后,符合条件的将成为候选的角点,我们再对候选的角点,做完整的测试,即检测圆上的所有点。

简单的说:FAST特征检测算法定义基于特征点周围的图像灰度值,检测候选特征点周围一圈的像素值,如果候选点周围领域内有足够多的像素点与该候选点的灰度值差别够大,则认为该候选点为一个特征点。为了获得更快的结果,还采用了额外的加速办法,如果测试了候选点周围每隔90°角的4个点,应该至少有3个和候选点的灰度值差足够大,否则则不用再计算其他点,直接认为该候选点不是特征点。候选点周围的圆的选取半径是一个很重要的参数,这里我为了简单高效,采用半径为3,共有16个周边像素需要比较。


九、BRIEF

我们已经知道SIFT特征采用了128维的特征描述子,由于描述子用的浮点数,所以它将会占用512 bytes的空间。类似地,对于SURF特征,常见的是64维的描述子,它也将占用256bytes的空间。如果一幅图像中有1000个特征点(不要惊讶,这是很正常的事),那么SIFT或SURF特征描述子将占用大量的内存空间,对于那些资源紧张的应用,尤其是嵌入式的应用,这样的特征描述子显然是不可行的。而且,越占有越大的空间,意味着越长的匹配时间。 但是实际上SFIT或SURF的特征描述子中,并不是所有维都在匹配中有着实质性的作用。我们可以用PCA、LDA等特征降维的方法来压缩特征描述子的维度。还有一些算法,例如LSH,将SIFT的特征描述子转换为一个二值的码串,然后这个码串用汉明距离进行特征点之间的匹配。这种方法将大大提高特征之间的匹配,因为汉明距离的计算可以用异或操作然后计算二进制位数来实现,在现代计算机结构中很方便。下面来们提取一种二值码串的特征描述子。

 BRIEF提供了一种计算二值串的捷径,而并不需要去计算一个类似于SIFT的特征描述子。它需要先平滑图像,然后在特征点周围选择一个Patch,在这个Patch内通过一种选定的方法来挑选出来nd个点对。然后对于每一个点对(p,q),我们来比较这两个点的亮度值,如果I(p)>I(q),则这个点对生成了二值串中一个的值为1,如果I(p)<I(q),则对应在二值串中的值为-1,否则为0。所有nd个点对,都进行比较之间,我们就生成了一个nd长的二进制串。

 对于nd的选择,我们可以设置为128, 256或512, 这三种参数在OpenCV中都有提供,但是OpenCV中默认的参数是256,这种情况下,非匹配点的汉明距离呈现均值为128比特征的高斯分布。一旦维数选定了,我们就可以用汉明距离来匹配这些描述子了。值得注意的是,对于BRIEF,它仅仅是一种特征描述符,它不提供提取特征点的方法。所以,如果你必须使一种特征点定位的方法,如FAST、SIFT、SURF等。总体来说,BRIEF是一个效率很高的提取特征描述子的方法,同时,当图像发生很大的平面内的旋转,它有着很好的识别率。

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术工厂 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读