角点

特征检测与匹配是Computer Vision 应用总重要的一部分,这需要寻找图像之间的特征建立对应关系。点,也就是图像中的特殊位置,是很常用的一类特征,点的局部特征也可以叫做“关键特征点”(keypoint feature),或“兴趣点”(interest point),或“角点”(conrner)。

关于角点的具体描述可以有几种:

  • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
  • 两条及两条以上边缘的交点;
  • 图像中梯度值和梯度方向的变化速率都很高的点;
  • 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。

Harris角点检测

当一个窗口在图像上移动,在平滑区域如图(a),窗口在各个方向上没有变化。在边缘上如图(b),窗口在边缘的方向上没有变化。在角点处如图(c),窗口在各个方向上具有变化。Harris角点检测正是利用了这个直观的物理现象,通过窗口在各个方向上的变化程度,决定是否为角点。

将图像窗口平移[u,v]产生灰度变化E(u,v)

由:, 得到:

对于局部微小的移动量 [u,v],近似表达为:

其中M是 2*2 矩阵,可由图像的导数求得:

E(u,v)的椭圆形式如下图:

定义角点响应函数 R 为:

Harris角点检测算法就是对角点响应函数R进行阈值处理:R > threshold,即提取R的局部极大值。

【相关代码】

OpenCV中定义了 cornerHarris 函数:

[cpp] view plaincopy
  1. void cornerHarris( InputArray src, OutputArray dst, int blockSize,
  2. int ksize, double k,
  3. int borderType=BORDER_DEFAULT );

可以结合 convertScaleAbs 函数,通过阈值取角点:

[cpp] view plaincopy
  1. void cornerHarris_demo( int, void* )
  2. {
  3. Mat dst, dst_norm;
  4. dst = Mat::zeros( src.size(), CV_32FC1 );
  5. /// Detector parameters
  6. int blockSize = 2;
  7. int apertureSize = 3;
  8. double k = 0.04;
  9. /// Detecting corners
  10. cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );
  11. /// Normalizing
  12. normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
  13. convertScaleAbs( dst_norm, dst_norm_scaled );
  14. /// Drawing a circle around corners
  15. for( int j = 0; j < dst_norm.rows ; j++ )
  16. { for( int i = 0; i < dst_norm.cols; i++ )
  17. {
  18. if( (int) dst_norm.at<float>(j,i) > thresh )
  19. {
  20. circle( dst_norm_scaled, Point( i, j ), 5,  Scalar(0), 2, 8, 0 );
  21. circle(src,Point( i, j ), 5,  Scalar(255,0,0), -1, 8, 0 );
  22. }
  23. }
  24. }
  25. /// Showing the result
  26. imshow( corners_window, dst_norm_scaled );
  27. imshow( source_window, src );
  28. }

Shi-Tomasi 算法

Shi-Tomasi 算法是Harris 算法的改进。Harris 算法最原始的定义是将矩阵 M 的行列式值与 M 的迹相减,再将差值同预先给定的阈值进行比较。后来Shi 和Tomasi 提出改进的方法,若两个特征值中较小的一个大于最小阈值,则会得到强角点。

如上面第二幅图中,对自相关矩阵 M 进行特征值分析,产生两个特征值和两个特征方向向量。因为较大的不确定度取决于较小的特征值,也就是,所以通过寻找最小特征值的最大值来寻找好的特征点也就解释的通了。
Shi 和Tomasi 的方法比较充分,并且在很多情况下可以得到比使用Harris 算法更好的结果。

【相关代码】

由于这种Shi-Tomasi算子与1994年在文章 Good Features to Track [1]中提出,OpenCV 实现的算法的函数名定义为 goodFeaturesToTrack:

[cpp] view plaincopy
  1. void goodFeaturesToTrack( InputArray image, OutputArray corners,
  2. int maxCorners, double qualityLevel, double minDistance,
  3. InputArray mask=noArray(), int blockSize=3,
  4. bool useHarrisDetector=false, double k=0.04 );

自定义使用函数(以方便createTrackbar的响应)如下:

[cpp] view plaincopy
  1. void cornerShiTomasi_demo( int, void* )
  2. {
  3. if( maxCorners < 1 ) { maxCorners = 1; }
  4. /// Parameters for Shi-Tomasi algorithm
  5. vector<Point2f> corners;
  6. double qualityLevel = 0.01;
  7. double minDistance = 10;
  8. int blockSize = 3;
  9. bool useHarrisDetector = false;
  10. double k = 0.04;
  11. /// Copy the source image
  12. Mat cormat;
  13. /// Apply corner detection :Determines strong corners on an image.
  14. goodFeaturesToTrack( src_gray,
  15. corners,
  16. maxCorners,
  17. qualityLevel,
  18. minDistance,
  19. Mat(),
  20. blockSize,
  21. useHarrisDetector,
  22. k );
  23. /// Draw corners detected
  24. for( int i = 0; i < corners.size(); i++ ){
  25. circle( dst_norm_scaled,  corners[i], 5,  Scalar(255), 2, 8, 0 );
  26. circle( src, corners[i], 4, Scalar(0,255,0), 2, 8, 0 );
  27. }
  28. /// Show what you got
  29. imshow( corners_window, dst_norm_scaled );
  30. imshow( source_window, src );
  31. }

实践

在主函数中定义两个进度条方便调整阈值:

[cpp] view plaincopy
  1. namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  2. createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );
  3. createTrackbar( "Max  corners:", source_window, &maxCorners, maxTrackbar, cornerShiTomasi_demo );
  4. namedWindow( corners_window, CV_WINDOW_AUTOSIZE );
  5. namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  6. imshow( source_window, src );
  7. cornerHarris_demo( 0, 0 );
  8. cornerShiTomasi_demo( 0, 0 );

这里还需要说的是OpenCV 2.4.2中给的角点检测跟踪的示例代码有些问题,是应为SURF等不再定义在 feature2d模块中,而是legacy和nonfree,所以需要加入引用:

[cpp] view plaincopy
  1. #include "opencv2/legacy/legacy.hpp"
  2. #include "opencv2/nonfree/nonfree.hpp"

角点检测结果:

蓝色实心点为Harris检测结果,绿色空心圈为goodFeaturetoTrack检测结果。

M特征值分解后每个像素点相减的图(也就是Harris阈值判断的图)如下:

黑色实心点为Harris阈值检测结果,白色空心圈为阈值为27时Shi-Tomasi检测结果。

转载请注明出处:http://blog.csdn.net/xiaowei_cqu/article/details/7805206
源码及资料下载: http://download.csdn.net/detail/xiaowei_cqu/4466627

参考资料:

[1] Shi and C. Tomasi. Good Features to Track. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, pages 593-600, June 1994.

[2] Richard Szeliski. Computer Vision: Algorithms and Applications. Springer, New York, 2010.

[3] 图像特征点提取PPT http://wenku.baidu.com/view/f61bc369561252d380eb6ef0.html

角点检测:Harris角点及Shi-Tomasi角点检测相关推荐

  1. 角点检测--基于梯度的方法(Moravec角点检测、Harris角点检测、Shi-Tomasi角点检测)

    Moravec Detector Moravec角点检测是第一个提出兴趣点(interest points)的Paper.它的主要思想是:以每个像素为中心,有一个固定的滑动窗口.该方法计算并在八个方向 ...

  2. OpenCV角点检测: Harris算子, ShiTomasi算子

    角点检测 角点的特征检测与匹配是Computer Vision 应用总重要的一部分,这需要寻找图像之间的特征建立对应关系.点,也就是图像中的特殊位置,是很常用的一类特征,点的局部特征也可以叫做&quo ...

  3. Python+OpenCV:图像Harris角点检测(Harris Corner Detection)

    Python+OpenCV:图像Harris角点检测(Harris Corner Detection) 理论 corners are regions in the image with large v ...

  4. python:实现哈里斯角检测|Harris Corner算法(附完整源码)

    python:实现哈里斯角检测|Harris Corner算法 import cv2 import numpy as npclass Harris_Corner:def __init__(self, ...

  5. 【OpenCV十六新手教程】OpenCV角检测Harris角点检测

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...

  6. 角点检测 c语言 棋盘格,一种棋盘格角点全自动检测方法与流程

    本发明属于图像处理与计算机视觉领域,特别涉及一种棋盘格角点全自动检测的方法. 背景技术: 棋盘格角点作为一种特殊的角点在相机标定中具有广泛的应用,扮演着相当重要的角色.棋盘格图案由于对比度明显,特征简 ...

  7. 检测实现OpenCV2.4.4实现Shi-Tomasi角点检测(goodFeaturesToTrack)

    最近研究检测实现,稍微总结一下,以后继续补充: #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgp ...

  8. java 判断全角_Java如何判断字符串中包含有全角,半角符号

    首先介绍下全角跟半角之间的区别: 在计算机屏幕上,一个汉字要占两个英文字符的位置,人们把一个英文字符所占的位置称为"半角",相对地把一个汉字所占的位置称为"全角" ...

  9. 全角数字变半角php,php代码中全角数字转半角的方法

    php代码中全角数字转半角的方法 发布时间:2020-10-13 14:33:52 来源:亿速云 阅读:66 作者:小新 小编给大家分享一下php代码中全角数字转半角的方法,相信大部分人都还不怎么了解 ...

  10. 计算机考试半角全角,全角和半角怎么切换?是什么意思?全角半角的区别

    你知道输入法里面的全角和半角是什么吗?下面我们就一起来了解一下它吧! 全角和半角是什么? 01全角,指一个字符占用两个标准字符位置的状态,也是排字的度量单位,宽度等于所使用的文字的磅数汉. 02半角, ...

最新文章

  1. 亚洲诚信联合又拍云升级云端SSL证书服务
  2. python个人项目-个人项目WC(Python实现)
  3. apt 根据注解,编译时生成代码
  4. linux用户组和权限分配
  5. Git ssh_key生成方法
  6. win10安装影子系统导致的蓝屏
  7. delphi写QQ消息群发(模拟按键精灵)
  8. 创建快捷方式以轻松查看Windows剪贴板
  9. ADB命令获取手机应用安装包
  10. 计算机硬盘170gb,假的:《最终幻想15》PC推荐配置GTX1080Ti+170GB硬盘为误传
  11. 《大数据》第1期“专题”——大数据与智慧城市
  12. 支持tcam的服务器,使用tcam实现数据流的选择性路由
  13. PLSQL Developer新手使用教程(图文教程)(转载)
  14. 苹果越狱手机知识大全
  15. MongoDB 2018 深圳年度大会 报告
  16. 数组对象,如何取数组中的最小值和最大值
  17. 思科3560交换机console线灌IOS
  18. 女生学有关计算机的什么专业好,女生学计算机专业好吗 适合的岗位有哪些
  19. DDR4内存全景解析
  20. c语言中第一字符必须是,【填空题】C语言中规定标识符只能由字母、数字、下划线组成,且第一个字符必须是( ) 。...

热门文章

  1. 从零开始用TensorFlow搭建卷积神经网络
  2. 线性回归代码matlab
  3. 返乡置业?多数人将掉入陷阱
  4. 从一副漫画说编码思维,编码习惯,编码风格 (条件判断,死代码,true 或false)
  5. JVM-12虚拟机性能监控与故障处理工具之【JDK的可视化工具-VisualVM】
  6. Spring-AOP基础知识
  7. php访问数组用引号_php双引号中访问数组元素报错如何解决
  8. 使用android studio查看内存,Android Studio Profiler使用心得 检测内存泄露问题
  9. python 从尾到头打印链表
  10. 河南测绘职业学院招生计算机,河南测绘职业学院代码