在上一篇博文《OpenCV4学习笔记(38)》中记录的SIFT算法是一种包含了特征提取和描述的算法,而今天要整理记录的是分别对应于图像特征的提取和描述两个方面的FAST特征提取算法和BRIEF特征描述算法。
- FAST特征提取算法
FAST(Features from Accelerated Segment Test-加速段测试特征)特征点提取算法,是一种简单快速的特征提取算法,因为其具有比较快的运算速度和还算不错的特征提取效果而被广泛应用于实时检测系统中。但是对于某些由于光照不均匀或存在阴影等因素而导致局部对比度不同的图像,FAST算法提取特征的适应性和特征提取效果都很不理想。
FAST特征点提取算法的主要思想如下,通过检测某一个像素点的邻域中是否存在足够多的、连续的、大于或小于该中心像素点灰度值的像素点,如果存在则表明该中心像素点可以作为被检测出的特征点,如果邻域中不存在这样连续的满足条件的像素点,则该中心像素点作为非特征点被淘汰掉。
假设一个中心像素点p,以半径为3的离散圆选择其邻域像素,则中心像素点p被16个像素点包围,并将这十六个邻域像素点编号如下:
16 1 2
15 3
14 4
13 p 5
12 6
11 7
10 9 8
如果在p点的16个邻域像素点中存在n个连续的像素点,每个像素点的灰度值都比 I(p)+t 要大,或者是都比 I(p)-t 要小,则中心像素点p为特征点。(t为阈值,I(p)为p点灰度值)
而当选择 n = 12 才可以满足条件时,可以通过以下两个步骤快速排除非特征点:
(1)计算 delta1 = | I(1)- I(p) | , delta9 = | I(9)- I(p) | ,如果delta1和delta9都小于阈值t,则中心像素点p作为非特征点被淘汰,否则作为候选特征点进入下一步检测;
(2)计算 delta5 = | I(5)- I(p) | , delta13 = | I(13)- I(p) | ,如果delta5、delta13、delta1、delta9中有三项大于阈值t,则中心像素点p作为特征点,否则作为非特征点被淘汰。
经过上述两个步骤,就得到使用FAST算法提取出来的特征点了。
算法过程中的阈值t,是FAST算法所能检测到的特征点的最小对比度,也是接受噪声的最大限度。由于传统FAST算法中的阈值t是固定值,导致其鲁棒性较差,对于光照不均匀、局部对比度不同的图像,很难达到比较好的检测效果。可以通过自适应阈值来优化FAST算法,使阈值t随着图像局部对比度的变化而变化,从而改进FAST算法的特征点提取效果。
在OpenCV中,已经封装好了FAST算法的API,也就是FastFeatureDetector
这一个类。当我们使用这个算法时,需要先通过FastFeatureDetector::create()
这个方法来创建一个FAST特征检测器,其参数含义如下:
第一个参数thresh:就是算法过程中的阈值t,默认值为10;
第二个参数nonmaxSuppresiion:布尔值,默认值为true,表示是否使用非极大值抑制,如果为true则当某个中心像素点的灰度值不是其邻域中的最大值时,则将其淘汰掉,只保留在邻域中是最大值的中心像素点;如果为false则表示不使用非极大值抑制;
第三个参数DetectorType:检测邻域类型,有TYPE_5_8 、TYPE_7_12 、TYPE_9_16这几种可选类型,默认值为TYPE_9_16。
当我们创建好FAST特征检测器后,就可以通过detect()
方法来对图像进行FAST特征点检测,得到一幅图像的KeyPoint类型的FAST特征点。
下面是代码演示:
auto fast = FastFeatureDetector::create(20,true,FastFeatureDetector::DetectorType::TYPE_9_16);
Mat image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\tem.jpg");
vector<KeyPoint> keyPoints;
fast->detect(image, keyPoints, Mat());
Mat result;
drawKeypoints(image, keyPoints, result, Scalar::all(-1), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
imshow("image", image);
imshow("result", result);
看一下提取出的FAST特征点:
完成了特征提取后,还需要对特征点起个别名,也就是进行特征描述的工作。
- BEIEF特征描述算法
BRIEF(Binary Robust IndependentElementary Features-二进制健壮独立特征)特征描述算法仅仅是一种计算特征描述子的算法,它的作用就是来给特征点起别名,所以需要事先提取出特征点。
可以利用FAST特征点提取算法或Harris、shi-tomas角点检测算法或SIFT、SURF等算法事先提取出图像特征点,接下来再在特征点邻域利用BRIEF算法建立特征的二进制描述子。
在OpenCV官方文档中,推荐使用STAR特征检测算法与BRIEF特征描述算法相结合使用。其中,STAR是派生自CenSurE的特征检测器。但是与CenSurE不同,CenSurE使用正方形,六边形和八边形等多边形逼近一个圆,而Star模拟一个具有2个重叠正方形的圆:1个垂直正方形和1个45度旋转角度。这些多边形是双层的。可以将它们视为具有粗边框的多边形。边界和封闭区域的权重为相反的符号。与其他尺度空间检测器相比,它具有更好的计算特性,并且能够实时实现。与SIFT和SURF相比,在子采样像素处发现极值会损害较大尺度的精度,与此相反,CenSurE使用金字塔中所有尺度的完整空间分辨率来创建特征向量。在官方文档中建议使用STAR特征检测,它是一种快速检测器,对于STAR特征点,BRIEF的效果甚至比SURF点略好。
BRIEF特征描述算法的主要步骤如下:
1、对图像进行高斯模糊,消除噪声干扰,由于BRIEF算法是以具体像素值为基础来计算的,所以对噪声很敏感;
2、以每个特征点为中心像素点,选取其尺寸为SxS的邻域(如9x9),并且在邻域中通过某些随机算法来随机抽取两个点组成一个点对<p , q>,假如p像素点的像素值大于q像素点的像素值,则返回1;如果p像素点的像素值小于q像素点的像素值,则返回0;
有研究表明,当选取的两个随机点p、q都符合[ 0, (1 / 25) * S^2 ]的高斯分布时,最后获得的效果比较好;
3、重复步骤2 N次,获取一段N bit的二进制编码。一般选择重复256次来获得一段256bit的二进制编码,这就是该特征点的二进制描述子。
BRIEF算法的优势是利用二进制编码来获取描述子,只是进行简单的灰度值对比而不涉及大量复杂的计算,所以其运算速度很快。但是也正是因为它基于图像的具体像素值来运算,所以导致该算法对噪声非常敏感,而且不具有旋转不变性和尺度不变性,其鲁棒性会比较差一些。
如果今天整理将FAST特征提取算法和BRIEF特征描述算法结合起来,就可以对图像实现简单的目标检测、目标匹配等操作了,下次的笔记就来整理记录一下基于上述两种算法改进而来的特征提取描述算法——ORB算法。那么今天的笔记内容就到此为止了,谢谢阅读~