OpenCV-Python教程:38.FAST角点检测算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV-Python教程:38.FAST角点检测算法相关的知识,希望对你有一定的参考价值。
参考技术A 理论我们看到了一些特征检测算法,他们很多都不错,但是从实时应用的角度看,他们都不够快,一个最好的例子是SLAM(同步定位与地图创建)移动机器人没有足够的计算能力。
作为解决方案,FAST(加速切片测试特征)算法被提出,Edward Rosten和Tom Drummond 2006年在他们的论文“Machine learning for high-speed corner detection”提出,并在2010年最后修订,算法的基本大意如下:
使用FAST进行特征检测
1.选择一个图像里的像素p用来识别是不是一个兴趣点,它的强度是Ip
2.选择一个合适的阈值t
3.在要测试的像素周围找16个像素的圆
4.现在如果存在一个在圆内(16像素的)的n个连续像素集合,他们都比Ip + t要亮,或者都比Ip - t 要暗(用白虚线显示),那p就是角, n取12。
5.用一个高速测试来排除大量非角。这个测试只检查1,9,5和13位置的像素(首先1和9会测试是否他们太亮或者太暗,如果是,再检查5和13)。如果p是角,那么至少3个都比Ip+t要亮或者比Ip-t要暗,如果不是这样,那么p不可能是角。这个检测器展现了高性能,但是有几个缺陷:
·当n< 12时不能拒绝很多备选点
·像素的选择不是可选的,因为它的效率依赖问题和角的分布。
·高速测试的结果被丢弃了
·会检测出多个爱挨在一起的特征
机器学习角点检测
1.选择一组图像进行训练(最好从目标应用范围内)
2.运行FAST算法来对每个图像进行特征点查找
3.对每个特征点,存下周围的16个像素作为向量。所有图像做完以后得到特征向量P。
4.这16个像素里的每个像素(设为x)可以有下面的三个状态:
5.根据这些状态,特征向量P被分成3个子集,Pd, Ps, Pb.
6.定义个新的布尔变量Kp,如果p是角就是真反之为假。
7.使用ID3算法(决策树分类)来查询每个子集,对于每个true类用变量Kp,它选择x来得出一个备选像素是否是角的信息。
8.对所有子集迭代直到为0
9.创建的决策树用来对其他图形做fast检测
非极大值抑制
在临近位置检测多个兴趣点是另一个问题,可以使用非极大值抑制来解决。
1.计算一个分数函数,V是所有检测到的特征点,V是p和16个围着的像素值得绝对差。
2.计算两个相邻关键点的V值
3.丢掉V值低的那个
总结:
它比其他存在的角点算法要快几倍
但是它对高噪点情况来说不健壮,依赖阈值
OpenCV里的FAST特征检测
它和其他OpenCV里的特征检测类似,如果你愿意,你可以指定阈值,是否使用非极大值抑制,要用的邻居等。
对于邻居,定义了三个标志位, cv2.FAST_FEATURE_DETECTOR_TYPE_5_8, cv2.FAST_FEATURE_DETECTOR_TYPE_7_12和cv2.FAST_FEATURE_DETECTOR_TYPE_9_16.
看结果,第一个图像显示了使用了非极大值抑制的FAST,第二个是没有使用非极大值抑制的。
END
[图像识别]11.OpenCV的角点检测 FAST和OBR算法
回顾,上节课你学到了什么?
#实例化sift
sift=cv.SIFT_create()
#检测关键点并计算
kp,des=sift.detectAndCompute(gray,None)
#将关键点绘制在图像上
cv.drawKeypoints(image,keypoints,outputimage,color,flags)
目录
FAST
1.原理
前面讲述的SIFT和SURF算法效率还是太低了,为解决这个问题提出了FAST算法
FAST算法通俗的将就是检测一个像素周围有一定数量的像素与该点像素值不同,就认为它是角点。
2.步骤
【1】在图像中选取一个像素点p,来判断它是不是关键点。Ip等于像素点p的灰度值。
【2】以r为半径画圆,覆盖p点周围的M个像素,通常情狂下,设置r=3,则M=16
【3】设置一个阈值t,如果在这16个像素点中存在n个连续像素点的灰度值都在(Ip- t,Ip+ t)之外,那么像素点p就被认为是一个角点。如上图中的虚线所示,n一般取值为12。
【4】为了快速筛选,首先对候选点的周围每个90度的点:上述图片的 1, 9, 5,13进行测试(先测试1和19,如果它们符合阈值要求再测试5和13)。如果p是角点,那么这四个点中至少有3个要符合阈值要求,否则直接剔除。对保留下来的点再继续进行测试(是否有12的点符合阈值要求)。
缺点:●获得的候选点比较多●特征点的选取不是最优的●大量的点被丢弃●很多特征点都是相邻的
前3个问题可以通过机器学习的方法解决,最后一个问题可以使用非最大值抑制的方法解决。
3.代码API
#实例化fast
fast=cv.FastFeatureDetector_create(threshold,nonMaxSuppression)
threshold:阈值默认10
nonMaxSuppression:是否进行非极大抑制
#检测关键点,没有关键点描述
kp=fast.detect(gray,None)
kp:关键点信息,位置,尺度,方向
gray:灰度图像
#将观测点绘制到图像上
cv.drawKeyPoints(img,keypoints,outputimg,color,flags)
举例:
#10.1
import cv2 as cv import numpy as np import matplotlib.pyplot as plt #解决中文显示问题,固定格式,直接复制下面俩行代码就行 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False #1.读取灰度图像 pic1 =cv.imread("10.jpg") gray=cv.cvtColor(pic1,cv.COLOR_BGR2GRAY) #2.FAST实例化 fast=cv.FastFeatureDetector_create(15,True) #3.检测关键点 kp=fast.detect(gray,None) #4.绘制关键点 pic2=pic1.copy() cv.drawKeypoints(pic2,kp,pic2,(0,0,255),flags=4) #绘制图像 fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,10)) axes[0,0].set_title("原图") axes[0,0].imshow(pic1[:,:,::-1]) axes[0,1].set_title("灰度图") axes[0,1].imshow(gray,plt.cm.gray) axes[1,1].set_title("FAST特征点检测") axes[1,1].imshow(pic2[:,:,::-1]) plt.show() cv.waitKey(0)
结果:
OBR
1.原理
ORB算法结合了Fast和Brief算法,提出了构造金字塔,为Fast特征点添加了 方向,从而使得关键点具有了尺度不变性和旋转不变性。
2.步骤
【1】构造尺度金字塔,金字塔共有n层,每一层仅有一副幅图像。第0层为初始图像σ0尺寸默认1.2,第s层的尺度为:
第s层图像大小
【2】在不同的尺度上利用Fast算法检测特征点,采用Harris角点响应函数,根据角点响应值R排序,选取前N个特征点,作为本尺度的特征点。
【3】计算特征点的主方向,计算以特征点为圆心半径为r的圆形邻域内的灰度质心位置,将从特征点位置到质心位置的方向做特征点的主方向。
质心位置
主方向位置
【4】为了解决旋转不变性,将特征点的邻域旋转到主方向.上利用Brief算法构建特征描述符,至此就得到了ORB的特征描述向量。
Brief算法:BRIEF是一种特征描述子提取算法,生成二值化描述子的算法,不提取代价低,匹配只需要使用简单的汉明距离利用比特之间的异或操作就可以完成。因此,时间代价低,空间代价低,效果还挺好。
(1)图像滤波,去除噪声
(2)选取点对:以特征点为中心,取S"S的邻域窗口,在窗口内随机选取N组点对,一般N=128,256,512,默认是256,有多种形式
(3)构建描述符,根据公式二值化:
p(x)和p(y)是点对的俩个端点的像素值。
形成BRIEF的关键 点的描述特征向量,该向量一般为128-512位的字符串。
3.代码API
#实例化orb
orb=cv.ORB_creat(nfeatures)
nfeatures:特征点最大数量
#检测关键点并计算
kp,des=orb.detectAndCompute(gray,None)
kp:关键点集合
des:关键点描述符
gray:灰度图
#关键点检测结果绘制到图像上面
cv.drawKeypoints(img,keypoints,outputimg,flags)
举例:
#10.2
import cv2 as cv import numpy as np import matplotlib.pyplot as plt #解决中文显示问题,固定格式,直接复制下面俩行代码就行 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False #1.读取灰度图像 pic1 =cv.imread("10.jpg") gray=cv.cvtColor(pic1,cv.COLOR_BGR2GRAY) #2.FAST实例化 orb=cv.ORB_create(10000) #3.检测关键点 kp,des=orb.detectAndCompute(gray,None) #4.绘制关键点 pic2=pic1.copy() cv.drawKeypoints(pic2,kp,pic2,(0,0,255),flags=0) #绘制图像 fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,10)) axes[0,0].set_title("原图") axes[0,0].imshow(pic1[:,:,::-1]) axes[0,1].set_title("灰度图") axes[0,1].imshow(gray,plt.cm.gray) axes[1,1].set_title("ORB特征点检测") axes[1,1].imshow(pic2[:,:,::-1]) plt.show() cv.waitKey(0)
结果:
总结,这节课你学到了什么?
#实例化fast
fast=cv.FastFeatureDetector_create(threshold,nonMaxSuppression)
#检测关键点,没有关键点描述
kp=fast.detect(gray,None)
#关键点检测结果绘制到图像上面
cv.drawKeypoints(img,keypoints,outputimg,flags)
#实例化orb
orb=cv.ORB_creat(nfeatures)
#检测关键点并计算
kp,des=orb.detectAndCompute(gray,None)
#关键点检测结果绘制到图像上面
cv.drawKeypoints(img,keypoints,outputimg,flags)
以上是关于OpenCV-Python教程:38.FAST角点检测算法的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV入门教程之十六OpenCV角点检测之Harris角点检测
OpenCV-Python基础教程2-PyQt编写GUI界面