前面描述角点检测的时候说到,角点其实也是一种图像特征点,对于一张图像来说,特征点分为三种形式包括边缘,焦点和斑点,在OPENCV中,加上角点检测,总共提供了以下的图像特征点检测方法

  1. FAST
  2. SURF
  3. ORB
  4. BRISK
  5. KAZE
  6. AKAZE
  7. MESR
  8. GFTT good feature to tack
  9. Bob斑点
  10. STAR
  11. 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<FastFeatureDetector> 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特征点没有方向信息,这样就会失去旋转不变性.但是在要求实时性的场合,比如视频监控的物体识别,是可以使用的.

使用代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//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);
    }
    vector<KeyPoint>detectKeyPoint;
    Mat keyPointImage1,keyPointImage2;
    Ptr<FastFeatureDetector> 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",srcImage);
    imshow("keyPoint image1",keyPointImage1);
    imshow("keyPoint image2",keyPointImage2);
    imwrite("F:\\opencv\\OpenCVImage\\FeatureDetectSrc1FASTKeyPointImageDefault.jpg",keyPointImage2);
    waitKey(0);
    return 0;
}

  

Opencv特征点检测相关推荐

  1. OpenCV特征点检测匹配图像-----添加包围盒

    OpenCV特征点检测匹配图像-----添加包围盒 最终效果: 其实这个小功能非常有用,甚至加上只有给人感觉好像人脸检测,目标检测直接成了demo了,主要代码如下: // localize the o ...

  2. Opencv特征点检测及目标提取

    Opencv特征点检测及目标提取 前言 1. 特征点检测方法简介 2. 单张图片特征点检测 3. opencv批量处理图片模板 4. 多张图片特征点检测及目标提取 总结 前言 在图像预处理时,会出现背 ...

  3. OpenCV 特征点检测与图像匹配

    特征点又称兴趣点.关键点,它是在图像中突出且具有代表意义的一些点,通过这些点我们可以用来识别图像.进行图像配准.进行3D重建等.本文主要介绍OpenCV中几种定位与表示关键点的函数. 一.Harris ...

  4. OpenCV 特征点检测

    特征点检测 目标 在本教程中,我们将涉及: 使用 FeatureDetector 接口来发现感兴趣点.特别地: 使用 SurfFeatureDetector 以及它的函数 detect 来实现检测过程 ...

  5. python opencv识别点个数_python+OpenCV 特征点检测

    1.Harris角点检测 Harris角点检测算法是一个极为简单的角点检测算法,该算法在1988年就被发明了,算法的主要思想是如果像素周围显示存在多于一个方向的边,我们认为该点为兴趣点.基本原理是根据 ...

  6. OpenCV特征点检测------Surf(特征点篇)

    Surf(Speed Up Robust Feature) Surf算法的原理                                                              ...

  7. 十.OpenCv 特征点检测和匹配

    特征点检测和匹配 1. 特征检测的基本概念 特征检测是计算机视觉和图像处理中的一个概念.它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征.特征检测的结果是把图像上的点分为不同的子集 ...

  8. python+OpenCV 特征点检测

    1.Harris角点检测 Harris角点检测算法是一个极为简单的角点检测算法,该算法在1988年就被发明了,算法的主要思想是如果像素周围显示存在多于一个方向的边,我们认为该点为兴趣点.基本原理是根据 ...

  9. OpenCV —— 特征点检测之 SIFT 特征检测器

    SIFT 原理详解 尺度空间的表示 高斯金字塔的构建 高斯差分金字塔 空间极值点检测 尺度变化的连续性 特征点定位 特征点的精确定位 剔除不稳定的边缘响应点 特征点方向赋值 生成特征描述 SIFT的缺 ...

  10. OpenCV特征点检测算法对比

    识别算法概述: SIFT/SURF基于灰度图, 一.首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后进行在极值点周围26个点进行NMS,从而得到粗略的特征点, ...

最新文章

  1. linux/hpux 添加用户
  2. QT的QQuickView类的使用
  3. java编写WordCound的Spark程序,Scala编写wordCound程序
  4. 并发和Read-copy update(RCU)
  5. 惠普招聘 运维质量管理顾问 1名 北京
  6. 苹果Mac批量图像格式转换软件:XnConvert
  7. ASP.NET中Dictionary的基本用法
  8. java 全排列非递归算法_我的字典序全排列java程序,怎么改成非递归算法
  9. STM8S103之时钟设置
  10. C语言编程入门——浮点数
  11. linux---finger命令
  12. 信号处理之FIR数字滤波器(Matlab仿真)
  13. 【一些题目】CTF Crypto初接触
  14. 关于使用佳信客服产品时产生的14问
  15. 【PPic】在PPic图床中如何配置使用七牛
  16. 比尔盖兹CES的最后语录
  17. 解决android上WIFI提示“未检测到任何互联网连接,因此不会自动重新连接“
  18. ExtJs 学习教程,个人感觉不错。
  19. 一些忠告给想转行当程序员的你
  20. vscode插件开发之Swagger生成Ts

热门文章

  1. 创业反思三:只喜欢我干活,拒不听建议,出了问题还找我
  2. DeepStream中,获得并修改识别对象参数的代码
  3. SmartSVN报错format的解决办法
  4. 漏桶算法和令牌桶算法
  5. Dxg——python MicroPython 开发笔记整理分类合集【所有的相关记录,都整理在此】
  6. java用if怎么编程税收_Java - 使用If和if else语句的简单税计算器
  7. datetime只要年月python_Python 的日期和时间处理
  8. 再谈MV*(MVVM MVP MVC)模式的设计原理—封装与解耦
  9. table中td的内容换行。
  10. (转)注意力机制(Attention Mechanism)在自然语言处理中的应用