![394098c38ff47fabb9be4d7f30df2f7d.png](https://i-blog.csdnimg.cn/blog_migrate/d796512482131e7e521e2fa6d833d02a.jpeg)
一、Harris角点检测
- 基本原理
人眼对角点的识别常在一个局部小区域完成,这个区域内的像素的灰度积分为判断标准。
灰度变化平缓区域,窗口内像素灰度积分近似保持不变: Flat
边缘区域,仅沿边缘方向,灰度积分近似不变,沿其余任意方向,均剧烈变化: Edge
角点处,沿任意方向移动,灰度积分均会剧烈变化: Corner
![9132ff9e32aae8ca06bd8f1b5b4b0a3d.png](https://i-blog.csdnimg.cn/blog_migrate/730f4dc1b5dd3582b8c05a7391630cac.png)
灰度积分变化E(u,v)当u,v很小时经过推导得:
![7ff2326aa8b13edf05d7e9e74d33acac.png](https://i-blog.csdnimg.cn/blog_migrate/ff9edb9cf3ad856c449d3b314dfd8140.png)
![c8c0ad1f00a03e21d0f30e2bbb6ca1e0.png](https://i-blog.csdnimg.cn/blog_migrate/3cc36c226e92b5aee0b1e0e56c6a4290.png)
M为海森矩阵,M存在着两个特征值,由于E为常数时,第一个式子近似为椭圆,而M的两个特征值的导数的平方根为半长轴和半短轴,决定了椭圆的扁率和尺寸,进而:
边缘:一个特征值大,另一个特征值小->自相关函数值在某一方向上大,在其他方向上小
平面:两个特征值都小,且近似相等->自相关函数数值在各个方向上都小
角点:两个特征值都大,且近似相等->自相关函数在所有方向都增大
实际不必求这两个特征值,可以使用角点响应函数R:
![c7a1241aad7c799fa35c156f790725cb.png](https://i-blog.csdnimg.cn/blog_migrate/801cb21093721b94dc2527ffd818bf64.png)
其中k=0.04~0.06,为经验常数,判断依据如下:
边缘:R<0
平面:R>0
角点:|R|小
- 测试代码
import
核心函数是cv2.cornerHarris:
第一个参数为img:数据类型为 float32 的输入灰度图像
第二个参数为blockSize:角点检测中要考虑的领域大小,计算协方差矩阵时的窗口大小
第三个参数为ksize - Sobel:Sobel求导中使用的窗口大小,定义了角点检测的敏感度,取值为3~31的奇数
第四个参数为k:0.04~0.06,为经验常数
返回值为R构成的灰度图像
效果如下:
![061eb421cee97c8215ff2428331f8919.png](https://i-blog.csdnimg.cn/blog_migrate/ade3fc911a7e17a8ce84c7ecf315f0a7.jpeg)
二、FAST特征检测
1.定义
FAST角点定义为:若某像素与其周围邻域内足够多的像素点相差较大,则该像素可能是角点
2.特点
1)FAST只是一种特征点检测算法,并不涉及特征点的特征描述
2)算法的实时性非常好
3)缺点是不具有方向性和尺度不变性,受图像噪声以及设定的阈值影响很大
3.步骤
![1828bc68f4730edd8c04d08473645677.png](https://i-blog.csdnimg.cn/blog_migrate/ab0c44ff111acbff9559a0b3e05d86db.png)
1.以像素p为中心,半径为3的圆上有16个点(p1,,,p16)
2.定义一个阈值,计算p1、p9与中心p的像素差,若绝对值都小于阈值,则不可能为特征点;否则,当作候选点
3.若为候选点,计算p1、p5、p9、p13与中心的像素差,若至少有3个超过阈值,则继续作为候选,否则剔除
4.若仍为候选点,计算全部十六个点的像素差,若至少有9个超过阈值,则为特征点抑制
5.非极大值抑制:以特征点p为中心的邻域,若有多个特征点,判断每个点的FAST得分值——16个点的中心像素差绝对值总和,若p得分最大,则保留,否则抑制
4.代码实现
import
核心函数为cv2.FastFeatureDetector_create,创造FAST角点探测器:
第一个参数threshold,为步骤中的阈值,本程序取35
第二个参数nonmaxSuppression,为非极大值抑制,本程序开启
第三个参数type,检测器类型,共有三种5_8、7_12、9_16
kp = fast.detect(image, None):对image使用FAST检测器,把坐标结果存在kp,kp的内容如下:
[<KeyPoint 0x7fbb13cebde0>, ,,,,<KeyPoint 0x7fbb0a6afb10>, <KeyPoint 0x7fbb0a6afb40>, <KeyPoint 0x7fbb0a6afb70>, <KeyPoint 0x7fbb0a6afba0>, <KeyPoint 0x7fbb0a6afbd0>]
kp是一个列表,列表中的每个元素是opencv中定义的类:KeyPoint,该类中的属性包括:
1)pt(x,y):关键点的点坐标;
2)size():该关键点邻域直径大小;
3)angle:角度,表示关键点的方向,值为[零,三百六十),负值表示不使用。
4)response:响应强度
cv2.drawKeypoints能够在图片中标记出特征点,本程序标记成红色。
5.检测结果
![0d5afda039958ff0f9587370bcd961fd.png](https://i-blog.csdnimg.cn/blog_migrate/41cd18e439b696c61eae49e62d33da9a.jpeg)
从结果可以看出,非极大值抑制能有效的去除距离很近或重合的点。
三、SIFT(尺度不变)
SIFT全名为尺度不变特征变换,属于图像局部描述子,其特征对旋转、尺度缩放、亮度变化等保持不变性,同时还具有区分性、可扩展性、高速性等等。
- 步骤
1)构建尺度空间和DoG金字塔
尺度空间即试图在图像领域中模拟人眼观察物体的概念与方法,尺度从大到小,例如人眼去观察从一整棵树到一片树叶。
构建尺度空间时,SIFT算法利用高斯核函数进行滤波,使图像保存最多细节,经过滤波后细节特征逐渐减少来模拟大尺度情况下的特征表示,利用高斯核函数的原因有二:
高斯核函数是唯一的尺度不变核函数
DoG核函数可以近似LoG函数,而且尺度空间图像本质上就是当前图像与不同σ的核进行卷积的结果
尺度空间实现利用高斯金字塔:
高斯金字塔分成o组,原图像属于第一组,组之间进行降采样,即第二层图像的大小为第一组的1/4,金字塔的每组又分成s层,越向上的层,高斯模板的尺度σ越大,结果也越模糊,此外,高斯金字塔上一组图像的初始图像(底层图像)是由前一组图像的倒数第三张图像隔点采样得到的。
得到高斯金字塔后,需要将每组的上下两层相减,得到高斯差分图像,进而可以进行检测。
![d4701f472c6cd05b399ff6f19545ed6a.png](https://i-blog.csdnimg.cn/blog_migrate/7d50c02c57676fc96cba713763cbdfd7.png)
2)特征点检测
取一个像素点,周围3x3邻域的8个点以及其上下两层的对应邻域的9x2个点一共26个点,如果它是这26个点中的最大值或者最小值,则保留下来,当做初步的特征点。
随后采用3维线性插值法得到亚像素级的特征点,同时也去掉那些值小于一定阈值的点,增加极值使检测到的特征点数量减少,最终只有几个特征最强点会被检测出来。
![d451d84614ae12548e09313302099783.png](https://i-blog.csdnimg.cn/blog_migrate/5e9f575b2b7c746ee2e92a339a9cc86b.png)
3)计算主方向
为了保证旋转不变性,需要利用图像的局部特征为给每一个关键点分配一个基准方向。
对3σ邻域内取梯度,方向范围0~360度分成36个,其中每个10度,使用直方图统计邻域内像素的梯度和方向,直方图峰值方向代表了该特征点处邻域梯度的方向,也就是特征点的主方向。
同时为了增强匹配的鲁棒性,只保留峰值大于主方向峰值80%的方向作为该特征点的辅方向。
![1d855617d0735b2cb133397463454a72.png](https://i-blog.csdnimg.cn/blog_migrate/bc967c61afaa6ab008e498dfd8fdcfe8.png)
4)特征点描述
将特征点附近的邻域划分成4x4的子区域,每个子区域的大小与关键点方向分配时相同,从0~360度分成8个方向,每个45度。
将坐标轴旋转为特征点的方向,以确保旋转不变性,然后计算各个子区域的8个方向的梯度值。
最终得到了4x4x8=128维个梯度信息的特征向量。
![7210b1ef7cab5af16d017c854fcdfe8b.png](https://i-blog.csdnimg.cn/blog_migrate/1a195476c205dcd4fdd1ca9b167137c2.jpeg)
5)特征点匹配
分别对模板和观测图建立描述子集合,比较欧氏距离,可采取穷举法完成,但所花费的时间太多。所以一般采用kd树的数据结构来完成搜索。
- 代码实现
import
核心函数为cv.xfeatures2d.SIFT_create,参数包括:
nfeatures:特征点数目
nOctaveLayers:金字塔中每组的层数
contrastThreshold:过滤掉较差的特征点的对阈值,其越大,特征点越少
edgeThreshold:过滤掉边缘效应的阈值,其越大,特征点越多
sigma:金字塔第0层图像高斯滤波系数,也就是σ
cv.DescriptorMatcher_create进行特征子匹配,包括Brute-force暴力匹配和Flann-based快速最近邻匹配。
- 检测结果
![398e95063dc34f392f453ba39b85277e.png](https://i-blog.csdnimg.cn/blog_migrate/7944f91c4df4b3043b4188f4e2cdff7c.jpeg)
四、SURF
SURF改进了SIFT算法,提升了实时性,改进如下:
- 金字塔图像
SURF采用Hessian矩阵行列式近似值图像,而不是DOG图像。
利用盒子滤波器代替二阶高斯微分模板,通过积分图像的运用,减小了高斯核卷积的运算量。
![7e9433bab84cc34f2286c89949ab5d9f.png](https://i-blog.csdnimg.cn/blog_migrate/494d63f7ffdc25ec4374317cf61a8a28.png)
- 尺度空间
surf算法中,组间和组内图像的大小总是不变的,组间高斯模板的大小不同,组内高斯模板的大小相同,但尺度σ不同,由于不需要降采样,也降低了运算量。
![496036a96636d98c74f0145fb1c4ee4e.png](https://i-blog.csdnimg.cn/blog_migrate/b4b941c0d10d802cdf9708d068266639.png)
- 特征点定位
SURF与SIFT基本一致
- 计算主方向
SURF采用的是统计特征点圆形邻域内的harr小波特征。
在特征点的圆形邻域内,统计60度扇形内所有点的水平、垂直harr小波特征,给这些响应值赋高斯权重系数,使得靠近特征点的响应贡献大,而远离特征点的响应贡献小,然后扇形以一定间隔进行旋转并再次统计该区域内harr小波特征值之后,最后将值最大的那个扇形的方向作为该特征点的主方向。
![38e4fac6c84309179e8a94731bbc50d2.png](https://i-blog.csdnimg.cn/blog_migrate/a210b4bd23a1b7b485810f4a0b89b2f6.png)
- 特征描述子
SURF也是取一个4x4块,但统计的是水平方向和垂直方向的haar小波特征。
该haar小波特征为水平方向值之后、垂直方向值之后、水平方向绝对值之后以及垂直方向绝对值之和4个方向。
因此特征描述子4x4x4=64维,是SIFT描述子的1/2.
![5ddea2be568dcfcdc4f4726277f06fb3.png](https://i-blog.csdnimg.cn/blog_migrate/44ef0385612c43c8d2d12b5751631b71.png)
- 特征点匹配
SURF,与Sift特征点匹配类似,也是通过计算两个特征点间的欧式距离来确定匹配度,欧氏距离越短,代表两个特征点的匹配度越好。
除此之外,Surf还加入了Hessian矩阵迹的判断。如果两个特征点的矩阵迹正负号相同,代表这两个特征具有相同方向上的对比度变化;但如果两个特征点的矩阵迹正负号不同,说明这两个特征点的对比度变化方向是相反的,即使欧氏距离为0,也直接予以排除。
核心函数cv.xfeatures2d.SURF_create(),与SIFT不同的参数为:
hessianThreshold:默认100 ,特征点检测的阈值,其越高,监测的点越少 extended:默认False,扩展描述符标志,True表示使用扩展的128个元素描述符,False表示使用64个元素描述符。 upright:默认False,垂直向上或旋转的特征标志,True表示不计算特征的方向,False-计算方向。
注:
SIFT和SURF算法由于版权原因,在部分版本的OPENCV中无法使用。
可以将opencv-python和opencv-contrib-python降至3.4.1.15。