角点检测:Harris角点及Shi-Tomasi角点检测
角点
特征检测与匹配是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 函数:
- void cornerHarris( InputArray src, OutputArray dst, int blockSize,
- int ksize, double k,
- int borderType=BORDER_DEFAULT );
可以结合 convertScaleAbs 函数,通过阈值取角点:
- void cornerHarris_demo( int, void* )
- {
- Mat dst, dst_norm;
- dst = Mat::zeros( src.size(), CV_32FC1 );
- /// Detector parameters
- int blockSize = 2;
- int apertureSize = 3;
- double k = 0.04;
- /// Detecting corners
- cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );
- /// Normalizing
- normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
- convertScaleAbs( dst_norm, dst_norm_scaled );
- /// Drawing a circle around corners
- for( int j = 0; j < dst_norm.rows ; j++ )
- { for( int i = 0; i < dst_norm.cols; i++ )
- {
- if( (int) dst_norm.at<float>(j,i) > thresh )
- {
- circle( dst_norm_scaled, Point( i, j ), 5, Scalar(0), 2, 8, 0 );
- circle(src,Point( i, j ), 5, Scalar(255,0,0), -1, 8, 0 );
- }
- }
- }
- /// Showing the result
- imshow( corners_window, dst_norm_scaled );
- imshow( source_window, src );
- }
Shi-Tomasi 算法
Shi-Tomasi 算法是Harris 算法的改进。Harris 算法最原始的定义是将矩阵 M 的行列式值与 M 的迹相减,再将差值同预先给定的阈值进行比较。后来Shi 和Tomasi 提出改进的方法,若两个特征值中较小的一个大于最小阈值,则会得到强角点。
如上面第二幅图中,对自相关矩阵 M 进行特征值分析,产生两个特征值
和两个特征方向向量。因为较大的不确定度取决于较小的特征值,也就是
,所以通过寻找最小特征值的最大值来寻找好的特征点也就解释的通了。
Shi 和Tomasi 的方法比较充分,并且在很多情况下可以得到比使用Harris 算法更好的结果。
【相关代码】
由于这种Shi-Tomasi算子与1994年在文章 Good Features to Track [1]中提出,OpenCV 实现的算法的函数名定义为 goodFeaturesToTrack:
- void goodFeaturesToTrack( InputArray image, OutputArray corners,
- int maxCorners, double qualityLevel, double minDistance,
- InputArray mask=noArray(), int blockSize=3,
- bool useHarrisDetector=false, double k=0.04 );
自定义使用函数(以方便createTrackbar的响应)如下:
- void cornerShiTomasi_demo( int, void* )
- {
- if( maxCorners < 1 ) { maxCorners = 1; }
- /// Parameters for Shi-Tomasi algorithm
- vector<Point2f> corners;
- double qualityLevel = 0.01;
- double minDistance = 10;
- int blockSize = 3;
- bool useHarrisDetector = false;
- double k = 0.04;
- /// Copy the source image
- Mat cormat;
- /// Apply corner detection :Determines strong corners on an image.
- goodFeaturesToTrack( src_gray,
- corners,
- maxCorners,
- qualityLevel,
- minDistance,
- Mat(),
- blockSize,
- useHarrisDetector,
- k );
- /// Draw corners detected
- for( int i = 0; i < corners.size(); i++ ){
- circle( dst_norm_scaled, corners[i], 5, Scalar(255), 2, 8, 0 );
- circle( src, corners[i], 4, Scalar(0,255,0), 2, 8, 0 );
- }
- /// Show what you got
- imshow( corners_window, dst_norm_scaled );
- imshow( source_window, src );
- }
实践
在主函数中定义两个进度条方便调整阈值:
- namedWindow( source_window, CV_WINDOW_AUTOSIZE );
- createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );
- createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, cornerShiTomasi_demo );
- namedWindow( corners_window, CV_WINDOW_AUTOSIZE );
- namedWindow( source_window, CV_WINDOW_AUTOSIZE );
- imshow( source_window, src );
- cornerHarris_demo( 0, 0 );
- cornerShiTomasi_demo( 0, 0 );
这里还需要说的是OpenCV 2.4.2中给的角点检测跟踪的示例代码有些问题,是应为SURF等不再定义在 feature2d模块中,而是legacy和nonfree,所以需要加入引用:
- #include "opencv2/legacy/legacy.hpp"
- #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角点检测的更多相关文章
- 【OpenCV十六新手教程】OpenCV角检测Harris角点检测
本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...
- 寻找Harris、Shi-Tomasi和亚像素角点
Harris.Shi-Tomasi和亚像素角点都是角点,隶属于特征点这个大类(特征点可以分为边缘.角点.斑点). 一.Harris角点检测是一种直接基于灰度图像的角点提取算法,稳定性较高,但是也可能出 ...
- shift + 空格 快捷键 使输入法 在全角和半角直接切换。。 但是全角输入一个 空格 ,会造成jsp页面 无法正常解析。。比如 无法获得参数。。
shift + 空格 快捷键 使输入法 在全角和半角直接切换.. 但是全角输入一个 空格 ,会造成jsp页面 无法正常解析....比如 无法获得参数.. 如 <form action=" ...
- uniapp云打包之后华为手机推送角标不显示(有推送没角标)
小米手机上有角标,华为和OPPO没有角标 解决方法: 华为手机添加权限(可通过反编译或者离线打包添加) < uses - permission android:name="com.hu ...
- 目标检测之hough forest---霍夫森林(Hough Forest)目标检测算法
Hough Forest目标检测一种比较时兴的目标检测算法,Juergen Gall在2009的CVPR上提出. Hough Forest听上去像hough变换+Random Forest的结合体, ...
- 实时检测微信域名防红拦截检测API系统,最新腾讯域名屏蔽检测官方接口
最近手里有个项目需要检测域名在微信里是否可以打开,如果被微信拦截,则需要进行下一步操作,所以需要判断域名的状态,但是微信官方并没有提供相关查询的方法,最后在网上找到了这个接口地址,分享给有需要的朋友. ...
- OpenCV——Harris、Shi Tomas、自定义、亚像素角点检测
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...
- Opencv学习笔记------Harris角点检测
image算法测试iteratoralgorithmfeatures 原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/73 ...
- OpenCV教程(45) harris角的检测(3)
在前面一篇教程中,我们通过取局部最大值的方法来处理检测结果,但是从图像中可以看到harris角的分布并不均匀,在纹理颜色比较深的地方检测的harris角结果更密集一些.本章中,我们使用一个 ...
- Harris角点及Shi-Tomasi角点检测(转)
一.角点定义 有定义角点的几段话: 1.角点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,广泛应用于运动检测.图像匹配.视频跟踪.三维建模和目标识别等领域中.也 ...
随机推荐
- 基于Bootstrap的Asp.net Mvc 分页的实现
最近写了一个mvc 的 分页,样式是基于 bootstrap 的 ,提供查询条件,不过可以自己写样式根据个人的喜好,以此分享一下.首先新建一个Mvc 项目,既然是分页就需要一些数据,我这边是模拟了一些 ...
- xmanager
[root@upright91 run]# ./runBenchmark.sh updbtpcc.properties sqlTableCreates Exception in thread &quo ...
- 基于 Laravel 开发博客应用系列 —— 从测试开始(一):创建项目和PHPUnit
1.创建博客项目 我们将遵循上一节提到的六步创建一个新 Laravel 5.1 项目的步骤,创建本节要用到的博客项目 —— blog. 首先,在本地主机安装应用骨架: nonfu@ubuntu:~/C ...
- 2017-2018-1 20179202《Linux内核原理与分析》第十周作业
一.设备与模块 1.设备类型 块设备:随机访问设备中的内容,通过块设备结点访问,通常被挂载为文件系统 字符设备:不可寻址,仅提供数据的流式访问,通过字符设备结点访问,应用程序通过直接访问设备节点与字符 ...
- Java_正则表达式&时间日期
正则表达式 1.概念 正则表达式(英语:Regular Expression,在代码中常简写为regex). 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配一系列符合某个句法规则 ...
- MCI:移动持续集成在大众点评的实践
一.背景 美团是全球最大的互联网+生活服务平台,为3.2亿活跃用户和500多万的优质商户提供一个连接线上与线下的电子商务服务.秉承“帮大家吃得更好,生活更好”的使命,我们的业务覆盖了超过200个品类和 ...
- FGPA 中的计数器Verilog语言(时钟分频器)
在quartusII8.0中为ALTERAFPGA设置一个分频器(计数器) 输入时钟48Mhz 输出时钟9600HZ /* 实验名称: 计数器 ** 程序功能: 将48Mhz的时钟分频为9600Hz ...
- 网络图片嗅探工具driftnet
网络图片嗅探工具driftnet 图片是网络数据传输的重要内容.Kali Linux内置了一款专用工具drifnet.该工具可以支持实时嗅探和离线嗅探.它可以从数据流中提取JPEG和GIF这两种网 ...
- git 相关资料应当查看廖雪峰所写的网站
廖雪峰关于git的网站 https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013 ...
- [BZOJ3638 && BZOJ3272]带修区间不相交最大K子段和(线段树模拟费用流)
https://www.cnblogs.com/DaD3zZ-Beyonder/p/5634149.html k可重区间集问题有两种建图方式,可能这一种才可以被线段树优化. 换个角度看,这也是一个类似 ...