您好,欢迎来到爱go旅游网。
搜索
您的当前位置:首页OPENCV图像特征点检测与FAST检测算法

OPENCV图像特征点检测与FAST检测算法

来源:爱go旅游网
OPENCV图像特征点检测与FAST检测算法

  前⾯描述⾓点检测的时候说到,⾓点其实也是⼀种图像特征点,对于⼀张图像来说,特征点分为三种形式包括边缘,焦点和斑点,在OPENCV中,加上⾓点检测,总共提供了以下的图像特征点检测⽅法1. FAST2. SURF3. ORB4. BRISK5. KAZE6. AKAZE7. MESR

8. GFTT good feature to tack9. Bob斑点10. STAR11. AGAST

  接下来分别讲述这是⼀种图像特征检测算法,但是⾸先,需要了解OPENCV的⼀种数据结构, KeyPoint结构,该结构的头⽂件定义如下:class KeyPoint{

Point2f pt; //该图像特征点的坐标float size; //特征点邻域直径

float angle; //特征点的⽅向,值为[零,三百六⼗),负值表⽰不使⽤,有了这个⽅向,能够让特征点拥有更⾼的辨识度,否则仅仅坐标和直径有时会误判特征点

float response;//响应程度,代表该点的强壮程度,也就是该点⾓点程度,⽤于后期使⽤和排序int octave; //特征点所在的图像⾦字塔的组int class_id; //⽤于聚类的id}

  每个图像特征点检测算法最终的⽬标之⼀,⽽当⼀张图像的特征点被检测出来之后,就可以和另⼀张图像的特征点进⾏匹配,根据相似级别判定两个图像的相似程度.

  ⽐如我们可以在图像中检测⼀张⼈脸的特征点,从⽽来检索在另⼀张图中是否存在相似程度很⾼的特征点集,从⽽确认另⼀张图像中的⼈脸以及⼈脸的位置,等,特征点检测算法在物体检测,视觉跟踪,3D重建的时候都有着重要的作⽤.

⼀. 图像特征点检测的通⽤接⼝

  Opencv为了⽅便⽤户使⽤图像特征点检测的相应算法,将全部的特征点检测都封在⼀个类似的API中,名为Ptr的模板类,也就是说,所有的特征检测算法都实现了相同的借⼝,detect 检测图像特征点.使⽤⽅法类似于  Ptr<相应的特征点检测类名>变量名 = 相应的特征点检测类::create()  变量名->detect(原图像,特征点向量).

  使⽤上⾯描述的算法,就可以调⽤⼏乎全部的图像特征检测算法.但是注意,create函数有多个重载函数,如果为空,每个图像检测算法都会使⽤⾃⼰的⼀套默认的初始值来初始化类,如果想修改参数,那么create函数调⽤的时候需要根据检测类的不同,设置不同的初始化变量.  另外,opencv提供⽽⼀个快速显⽰图像特征点的函数,如下

  drawKeyPoints(画布图像,特征点向量集,输出的绘制结果,绘制颜⾊值,绘制模式)

  ⼀般来说,画布图像会使⽤我们检测特征点的原图像(⼀般检测特征点都是原图像变换为灰度图像之后进⾏的检测,简单算法复杂度).  绘制模式有以下⽅法可以选择,是DrawMatchesFlags枚举

  DEFAULT:只绘制特征点的坐标点,显⽰在图像上就是⼀个个⼩圆点,每个⼩圆点的圆⼼坐标都是特征点的坐标.

  DRAW_OVER_OUTIMG:函数不创建输出的图像,⽽是直接在输出图像变量空间绘制,要求本⾝输出图像变量就是⼀个初始化好了的,size与type都是已经初始化好的变量

  NOT_DRAW_SINGLE 单点的特征点不被绘制

  DRAW_RICH_KEYPOINT 绘制特征点的时候绘制的是⼀个个带有⽅向的圆,这种⽅法同时显⽰图像的坐标,size,和⽅向,是最能显⽰特征的⼀种绘制⽅式,但是缺点就是绘制结果太杂乱.

⼀. FAST特征点检测算法

FAST算法是基于⾓点检测的图像特征.

⼀个特征点检测的算法的第⼀步是定义什么是特征点,FAST算法定义特征点是如果某个像素点和他周围领域⾜够多的像素点处于不同区域,那么这个像素点就是特征点,对于灰度图像来说,也就是该点的灰度值和其周围⾜够多的像素点的灰度值不同,那么这个像素点就是⼀个特征点.该算法的详细计算步骤如下

1. 从图⽚中选取⼀个坐标点,获取该点的像素值,接下来判定该点是否为特征点.

2. 选取⼀个以选取点坐标为圆⼼的半径等于三的Bresenham圆(⼀个计算圆的轨迹的离散算法,得到整数级的圆的轨迹点),⼀般来说,这个圆上有16个点,如下所⽰

  

⿊点坐标为(0,0),坐标step为1

1. 现在选取⼀个阈值,假设为t,关键步骤,假设这16个点中,有N个连续的像素点,他们的亮度值与中⼼点的像素值的差⼤于或者⼩于t,那么这个点就是⼀个特征点.(n的取值⼀般取值12或者9,实验证明9可以取得更好的效果,因为可以获取更多的特征点,后⾯进⾏处理时,数据样本额相对多⼀些).

2. 加⼊每个轨迹点都需要遍历的话,那么需要的时间⽐较长,有⼀种⽐较简单的⽅法可以选择,那就是仅仅检查在位置1,9,5和13四个位置的像素,⾸先检测位置1和位置9,如果它们都⽐阈值暗或⽐阈值亮,再检测位置5和位置13, 如果P\" role=\"presentation\" style=\"word-wrap: normal; max-width: none; max-height: none; min-width: 0px; min-height: 0px; float: none;\" id=\"MathJax-Element-8-Frame\">中⼼点是⼀个⾓点,那么上述四个像素点中⾄少有3个应该必须都⼤于Ip+t\" role=\"presentation\" style=\"word-wrap: normal; max-width:none; max-height: none; min-width: 0px; min-height: 0px; float: none;\" id=\"MathJax-Element-9-Frame\">中⼼点亮度值+阈值或者⼩于Ip−t\" role=\"presentation\" style=\"word-wrap: normal; max-width: none; max-height: none; min-width: 0px; min-height: 0px;float: none;\" id=\"MathJax-Element-10-Frame\">中⼼点亮度值-阈值,因为若是⼀个⾓点,超过四分之三圆的部分应该满⾜判断条件。如果不满⾜,那么p\" role=\"presentation\" style=\"word-wrap: normal; max-width: none; max-height: none; min-width: 0px; min-height:0px; float: none;\" id=\"MathJax-Element-11-Frame\">中⼼点不可能是⼀个⾓点。对于所有点做上⾯这⼀部分初步的检测后,符合条件的将成为候选的⾓点,我们再对候选的⾓点,做完整的测试,即检测圆上的所有点.

3. 但是,这种检测⽅法会带来⼀个问题,就是造成特征点的聚簇效应,多个特征点在图像的某⼀块重复⾼频率的出现,FAST算法提出了⼀种⾮极⼤值抑制的办法来消除这种情况,具体办法如下.

1. 为每⼀个检测到的特征点计算它的响应⼤⼩(score function)VV。这⾥VV定义为中⼼点和它周围16个像素点的绝对偏差的和.2. 考虑两个相邻的特征点,并⽐较它们的VV值3. VV值较低的点将会被删除  以上就是快速特征点检测的原理,OPENCV中定义的快速特征点检测算法的检测API如下  static Ptr create( int threshold=10, bool nonmaxSuppression=true, int type=FastFeatureDetector::TYPE_9_16 );

  threshold是指⽐较时边缘轨迹点和中⼼点的差值,也就是第三步的阈值t, nonmaxSuppression代表是否使⽤第五步⾮极⼤值抑制,如果发现fast检测的结果有聚簇情况,那么可以考虑采⽤,第三个参数type的取值来⾃于FastFeatureDetector枚举,有如下取值:1. TYPE_5_8 从轨迹中取8个点,当有5个点满⾜条件,就是特征点.2. TYPE_7_12 取轨迹12个点,7个满⾜条件,就是特征点.3. TYPE_9_16 取轨迹16个点,当9个满⾜条件,就是特征点.

  综上所述我们可以看出,FAST检测算法没有多尺度的问题,所以计算速度相对较快,但是当图⽚中的噪点较多的时候,会产⽣较多的错误特征点,健壮性并不好,并且, 算法的效果还依赖于⼀个阈值t。⽽且FAST不产⽣多尺度特征⽽且FAST特征点没有⽅向信息,这样就会失去旋转不变性.但是在要求实时性的场合,⽐如视频监控的物体识别,是可以使⽤的.使⽤代码如下

//fast

int main(int argc,char* argv[]){

Mat srcImage = imread(\"F:\\\\opencv\\\\OpenCVImage\\\\FeatureDetectSrc1.jpg\"); Mat srcGrayImage;

if (srcImage.channels() == 3) {

cvtColor(srcImage,srcGrayImage,CV_RGB2GRAY); } else {

srcImage.copyTo(srcGrayImage); }

vectordetectKeyPoint;

Mat keyPointImage1,keyPointImage2;

Ptr fast = FastFeatureDetector::create(); fast->detect(srcGrayImage,detectKeyPoint);

drawKeypoints(srcImage,detectKeyPoint,keyPointImage1,Scalar(0,0,255),DrawMatchesFlags::DRAW_RICH_KEYPOINTS); drawKeypoints(srcImage,detectKeyPoint,keyPointImage2,Scalar(0,0,255),DrawMatchesFlags::DEFAULT); imshow(\"src image\

imshow(\"keyPoint image1\ imshow(\"keyPoint image2\

imwrite(\"F:\\\\opencv\\\\OpenCVImage\\\\FeatureDetectSrc1FASTKeyPointImageDefault.jpg\ waitKey(0); return 0;}

  

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igat.cn 版权所有 赣ICP备2024042791号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务