角点

特征检测与匹配是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 = ;
int apertureSize = ;
double k = 0.04;
/// Detecting corners
cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );
/// Normalizing
normalize( dst, dst_norm, , , NORM_MINMAX, CV_32FC1, Mat() );
convertScaleAbs( dst_norm, dst_norm_scaled );
/// Drawing a circle around corners
for( int j = ; j < dst_norm.rows ; j++ )
{ for( int i = ; i < dst_norm.cols; i++ )
{
if( (int) dst_norm.at<float>(j,i) > thresh )
{
circle( dst_norm_scaled, Point( i, j ), , Scalar(), , , );
circle(src,Point( i, j ), , Scalar(,,), -, , );
}
}
}
/// 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=,
bool useHarrisDetector=false, double k=0.04 );

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

void cornerShiTomasi_demo( int, void* )
{
if( maxCorners < ) { maxCorners = ; }
/// Parameters for Shi-Tomasi algorithm
vector<Point2f> corners;
double qualityLevel = 0.01;
double minDistance = ;
int blockSize = ;
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 = ; i < corners.size(); i++ ){
circle( dst_norm_scaled, corners[i], , Scalar(), , , );
circle( src, corners[i], , Scalar(,,), , , );
} /// 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( , );
cornerShiTomasi_demo( , );

这里还需要说的是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

【OpenCV】角点检测:Harris角点及Shi-Tomasi角点检测的更多相关文章

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

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

  2. 寻找Harris、Shi-Tomasi和亚像素角点

    Harris.Shi-Tomasi和亚像素角点都是角点,隶属于特征点这个大类(特征点可以分为边缘.角点.斑点). 一.Harris角点检测是一种直接基于灰度图像的角点提取算法,稳定性较高,但是也可能出 ...

  3. shift + 空格 快捷键 使输入法 在全角和半角直接切换。。 但是全角输入一个 空格 ,会造成jsp页面 无法正常解析。。比如 无法获得参数。。

    shift + 空格 快捷键 使输入法 在全角和半角直接切换.. 但是全角输入一个 空格 ,会造成jsp页面 无法正常解析....比如 无法获得参数.. 如 <form action=" ...

  4. OpenCV学习笔记(八) 边缘、线与圆的检测

    边缘检测 对图像进行边缘检测之前,一般都需要先进行降噪(可调用GaussianBlur函数). Sobel算子 与 Scharr算子 都是一个离散微分算子 (discrete differentiat ...

  5. uniapp云打包之后华为手机推送角标不显示(有推送没角标)

    小米手机上有角标,华为和OPPO没有角标 解决方法: 华为手机添加权限(可通过反编译或者离线打包添加) < uses - permission android:name="com.hu ...

  6. 目标检测之hough forest---霍夫森林(Hough Forest)目标检测算法

     Hough Forest目标检测一种比较时兴的目标检测算法,Juergen Gall在2009的CVPR上提出. Hough Forest听上去像hough变换+Random Forest的结合体, ...

  7. 实时检测微信域名防红拦截检测API系统,最新腾讯域名屏蔽检测官方接口

    最近手里有个项目需要检测域名在微信里是否可以打开,如果被微信拦截,则需要进行下一步操作,所以需要判断域名的状态,但是微信官方并没有提供相关查询的方法,最后在网上找到了这个接口地址,分享给有需要的朋友. ...

  8. Opencv学习笔记------Harris角点检测

    image算法测试iteratoralgorithmfeatures 原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/73 ...

  9. OpenCV教程(43) harris角的检测(1)

          计算机视觉中,我们经常要匹配两幅图像.匹配的的方式就是通过比较两幅图像中的公共特征,比如边,角,以及图像块(blob)等,来对两幅图像进行匹配.      相对于边,角更适合描述图像特征, ...

  10. OpenCV——Harris、Shi Tomas、自定义、亚像素角点检测

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

随机推荐

  1. wifi,Android渗透之arp欺骗

    查看自己wifi ip段 查看有哪些用户连接了此wifi,下图标记处为我的测试机(华为) 攻击开始,如果开启了arp防火墙,就会有提示 开启图片捕获

  2. mongoose和mongodb的几篇文章 (ObjectId,ref)

    http://mongoosejs.com/docs/populate.html http://stackoverflow.com/questions/6578178/node-js-mongoose ...

  3. dirname命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/xiaofei125145/article/details/50620281 示例一 来自手册页的例子 $ dirname ...

  4. python的Socket网络编程 使用模板

    本文给出的是TCP协议的Socket编程. 其中用了一个dbmanager数据库操作模块,这个模块是我自己定义的,可以在我的另一个文章中找到这个模块的分享.python操作mysql数据库的精美实用模 ...

  5. Shell脚本 数据清洗

    需要做的任务是将上图类似的格式的文件进行处理,将年月日小时分别提取出来放到每行的行尾(上图已清洗好) 自己的思路是先用cut命令将每行的年月日小时提取出来,分别给一个变量,然后再循环利用sed命令将年 ...

  6. SQL Server 2008 存储过程示例

    出处:http://www.jb51.net/article/54730.htm --有输入参数的存储过程-- create proc GetComment (@commentid int) as s ...

  7. The North American Invitational Programming Contest 2017 题目

    NAIPC 2017 Yin and Yang Stones 75.39% 1000ms 262144K   A mysterious circular arrangement of black st ...

  8. 树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 (四) 树莓派单子节点查询

    考虑到项目的实际需要,树莓派作为主机,应该只在需要的时候查询特定节点发送的数据,因此接收到数据后需要根据头部判断是否是自己需要的数据,如果不是继续接收数据,超过一定时间未查询到特定节点的数据,则退出程 ...

  9. 车牌识别算法库EasyPR的使用

    主要参考以下两个博客: http://blog.csdn.net/junmuzi/article/details/49888123 http://blog.csdn.net/Lucas66666/ar ...

  10. linu中解压不同后缀的文件

    1.*.tar 用 tar –xvf 解压 2.*.gz 用 gzip -d或者gunzip 解压 3.*.tar.gz和*.tgz 用 tar –xzf 解压 4.*.bz2 用 bzip2 -d或 ...