第10章 角点检测
10.1 Harris角点检测
10.1.1 爱好点与角点
在图像处理和与计算机视觉领域,爱好点(interest points),也被称作关键点 (key points)、特 征 点(feature points)。它被大量用于办理物体辨认、图像辨认、 图像匹配、视觉跟踪、三维重修等一系列的问题。我们不再观察整幅图,而是选 择某些特殊的点,然后对它们进行局部有的放矢地分析。如果能检测到充足多的 这种点,同时它们的区分度很高,而且可以精确定位稳定的特性,那么这个方法 就具有实用代价。
图像特性范例可以被分为如下三种:
- 边 缘
- 角点(感爱好关键点)
- 斑点(Blobs)(感爱好地区)
其中,角点是个很特殊的存在。如果某一点在任意方向的一个微小变更都会 引起灰度很大的变化,那么我们就把它称之为角点。角点作为图像上的特性点, 包含有紧张的信息,在图像融合和目标跟踪及三维重修中有紧张的应用代价。它 们在图像中可以容易地定位,同时,在人造物体场景,好比门、窗、桌等处也随 处可见。由于角点位于两条边沿的交点处,代表了两个边沿变化的方向上的点, 以是它们是可以精确定位的二维特性,乃至可以到达亚像素的精度。又由于其图 像梯度有很高的变化,这种变化是可以用来资助检测角点的。需要留意的是,角 点与位于相同强度地区上的点差异,与物体外貌上的点也差异,由于外貌点难以 在相同的其他物体上精确定位。
别的,关于角点的详细描述可以有如下几种:
- 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
- 两条及两条以上边沿的交点;
- 图像中梯度值和梯度方向的变化速率都很高的点;
- 角点处的一阶导数最大,二阶导数为零,它指示了物体边沿变化不连续的 方向。
10.1.2 角点检测
现有的角点检测算法并不是都十分的健壮。许多方法都要求有大量的练习集 和冗余数据来防止或减少错误特性的出现。别的,角点检测方法的一个很紧张的 评价标准是其对多幅图像中相同或相似特性的检测能力,而且能够应对光照变化、 图像旋转等图像变化。
在当前的图像处理领域,角点检测算法可归纳为以下三类。
- 基于灰度图像的角点检测
- 基于二值图像的角点检测
- 基于外貌曲线的角点检测
而基于灰度图像的角点检测又可分为基于梯度、基于模板和基于模板梯度组 合三类方法。其中基于模板的方法紧张考虑像素领域点的灰度变化,即图像亮度 的变化,将与邻点亮度对比充足大的点界说为角点。常见的基于模板的角点检测 算法有Kitchen-Rosenfeld 角点检测算法,Harris 角点检测算法、KLT 角点检测算 法 及SUSAN 角点检测算法。
接下来,让我们一起来了解harris角点检测。
10.1.3 harris角 点 检 测
harris 角点检测是一种直接基于灰度图像的角点提取算法,稳定性高,尤其对 L 型角点检测精度高。但由于采用了高斯滤波,运算速率相对较慢,角点信息有 丢失和位置偏移的现象,而且角点提取有聚簇现象。
10.1.4 实 现Harris 角点检测:cornerHarris(函数
cornerHarris 函数用于在OpenCV 中 运 行Harris 角点检测算子来进行角点检 测。和cornerMinEigenVal() 以 及cornerEigenValsAndVecs() 函数雷同,cornerHarris 函数对于每一个像素(x,y) 在 blockSize×blockSize 邻域内,计算2x2 梯度的协 方差矩阵M(x,y), 接着它计算如下式子:
d s t ( x , y ) = d e t M K ) − k ⋅ ( t r M × ) 2 dst(x,y)=detMK)-k·(trM×)² dst(x,y)=detMK)−k⋅(trM×)2
就可以找出输出图中的局部最大值,即找出了角点。 其函数原型和参数分析如下。
- void cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, intborderType = BORDER_DEFAULT)
复制代码
- 第 一 个参数,InputArray类 型 的src, 输入图像,即源图像,填Mat 类的对 象即可,且须为单通道8位或者浮点型图像。
- 第二个参数,OutputArray 类 型 的dst, 函数调用后的运算结果存在这里, 即这个参数用于存放Harris 角点检测的输出结果,和源图片有一样的尺寸 和范例。
- 第三个参数,int 类 型 的 blockSize, 体现邻域的大小,更多详细信息在 cornerEigen ValsAndVecs()中有讲到。
- 第四个参数,int类 型 的ksize,体现 Sobel()算子的孔径大小。
- 第五个参数,double 范例的k,Harris 参数。
- 第六个参数,int类 型 的borderType, 图像像素的界限模式。留意它有默认 值 BORDER_DEFAULT 。 更详细的解释,参考borderInterpolate() 函数。
讲解完这个函数,我们看一个Harris 角点检测示例步调,其中还用到了之前 讲到的 threshold 函数。
- void Test65() {
- Mat srcImage = imread("school.jpg", 0);
- imshow("srcImage", srcImage);
- //进行Harris角点检测找出角点
- Mat cornerStrength;
- cornerHarris(srcImage, cornerStrength, 2, 3, 0.01);
- //二值化
- Mat harrisCorner;
- threshold(cornerStrength, harrisCorner, 0.00001, 255, THRESH_BINARY);
- imshow("harrisCorner", harrisCorner);
- waitKey(0);
- }
复制代码
10.1.5 综 合 示 例 :harris 角点检测与绘制
本次综合示例为调治滚动条来控制阈值,以控制的 harris 检测角点的数目。 一共有三个图片窗口,分别为显示原始图的窗口、包含滚动条的彩色效果图窗口, 以及灰度图效果图窗口。
- namespace test66 {
- Mat g_srcImage, g_srcImage1, g_grayImage;
- int thresh = 30;
- int max_thresh = 175;
- void on_CornerHarris(int, void*) {
- Mat dstImage, normImage, scaledImage;
- dstImage = Mat::zeros(g_srcImage.size(), CV_32FC1);
- g_srcImage1 = g_srcImage.clone();
- //角点检测
- cornerHarris(g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT);
- //归一化与转换
- normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
- convertScaleAbs(normImage, scaledImage); //转换为8为无符号整型
- for (int j = 0; j < normImage.rows; ++j) {
- for (int i = 0; i < normImage.cols; ++i) {
- if ((int)normImage.at<float>(j, i) > thresh + 80) {
- circle(g_srcImage1, Point(i, j), 5, Scalar(10, 10, 255), 2, 8, 0);
- circle(scaledImage, Point(i, j), 5, Scalar(0 ,10, 255), 2, 8, 0);
- }
- }
- }
- imshow("srcImage", g_srcImage);
- imshow("scaledImage", scaledImage);
- }
- void Test() {
- g_srcImage = imread("school.jpg");
- imshow("srcImage", g_srcImage);
- g_srcImage1 = g_srcImage.clone();
- cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
- namedWindow("srcImage");
- createTrackbar("value", "srcImage", &thresh, max_thresh, on_CornerHarris);
- waitKey(0);
- }
- }
- void Test66() {
- test66::Test();
- }
复制代码

10.2 Shi-Tomasi角点检测
10.2.1 Shi-Tomasi角点检测概述
除 了 利 用Harris 进行角点检测之外,我们通常还可以使用Shi-Tomasi 方法进 行角点检测。Shi-Tomasi 算 法 是Harris 算法的改进,此算法最原始的界说是将矩 阵M 的行列式值与M 的迹相减,再将差值同预先给定的阈值进行比较。后来Shi 和Tomasi 提出改进了方法,若两个特性值中较小的一个大于最小阈值,则会得到 强角点。
由 于Shi-Tomasi 算子是1994年在文章《Good Features to Track》中被提出的, OpenCV 实现此算法的函数名便界说为goodFeaturesToTrack。下面我们来看看此 函数的用法。
10.2.2 确定图像强角点:goodFeaturesToTrackO 函数
goodFeaturesToTrack() 函 数 结 合 了Shi-Tomasi 算子,用于确定图像的强角点 。
- 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)
复制代码
- 第一个参数,InputArray范例的image, 输入图像,须为8位或浮点型32 位单通道图像。
- 第二个参数,OutputArray范例的corners,检测到的角点的输出向量。
- 第三个参数,int范例的maxCorners, 角点的最大数目。
- 第四个参数,double范例的qualityLevel,角点检测可接受的最小特性值。 其实实际用于过滤角点的最小特性值是qualityLevel 与图像中最大特性值 的乘积。以是qualityLevel 通常不会凌驾1(常用的值为0.10或者0.01)。 而检测完全部的角点后,还要进一步剔除掉一些距离较近的角点。
- 第五个参数,double范例的minDistance,角点之间的最小距离,此参数用 于保证返回的角点之间的距离不小于minDistance 个像素。
- 第六个参数,InputArray范例的mask, 可选参数,体现感爱好地区,有默 认值noArray()。若此参数非空(需为CV_8UC1 范例,且和第一个参数image 有相同的尺寸),便用于指定角点检测地区。
- 第七个参数,int范例的blockSize,有默认值3,是计算导数自相关矩阵时 指定的邻域范围。
- 第八个参数,bool 范例的useHarrisDetector,默认值 false,指示是否使用 Harris 角点检测。
- 第九个参数,double范例的k, 有默认值0.04,为用于设置Hessian自相关 矩阵行列式的相对权重的权重系数。
别的值得一提的是,goodFeaturesToTrack 函数可用来初始化一个基于点的对 象跟踪利用。
10.2.3 综 合 示 例 :Shi-Tomasi 角点检测
下面是一个详细解释的以goodFeaturesToTrack 函数为核心, 进 行Shi-Tomasi 角点检测的示例步调。
- namespace test67 {
- Mat g_srcIMage, g_grayImage;
- int g_maxCornerNumber = 33;
- int g_maxTrackerbarNumber = 500;
- RNG g_rng(12345);
- void onGoodFeaturesToTrack(int, void*) {
- if (g_maxCornerNumber <= 1) {
- g_maxCornerNumber = 1;
- }
- std::vector<Point2f>corners;
- double qualityLevel = 0.01;
- double minDistance = 10;
- int blockSize = 3;
- double k = 0.04;
- Mat copy = g_srcImage.clone();
- goodFeaturesToTrack(g_grayImage, corners, g_maxCornerNumber, qualityLevel, minDistance, Mat(), blockSize, false, k);
- std::cout << "total corners:" << corners.size() << std::endl;
- //绘制角点
- int r = 4;
- for (int i = 0; i < corners.size(); ++i) {
- circle(copy, corners[i], r, Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)), -1, 8, 0);
- imshow("srcImage", copy);
- }
- Size winSize = Size(5, 5);
- Size zeroZone = Size(-1, -1);
- TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
- //计算出亚像素角点位置
- cornerSubPix(g_grayImage, corners, winSize, zeroZone, criteria);
- //输出角点信息
- for (int i = 0; i < corners.size(); ++i) {
- std::cout << " \t" << "pos[" << i << "]" << " = (" << corners[i].x << "," << corners[i].y << ")" << std::endl;
- }
- }
- void Test() {
- g_srcImage = imread("school.jpg");
- cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
- namedWindow("srcImage");
- createTrackbar("value", "srcImage", &g_maxCornerNumber, g_maxTrackerbarNumber, onGoodFeaturesToTrack);
- imshow("srcImage", g_srcImage);
- waitKey(0);
- }
- }
- void Test67() {
- test67::Test();
- }
复制代码

10.3 亚像素级角点检测
10.3.1 背景概述
若我们进行图像处理的目的不是提取用于辨认的特性点而是进行几何丈量, 这通常需要更高的精度,而函数 goodFeaturesToTrack) 只能提供简朴的像素的坐 标值,也就是说,有时间会需要实数坐标值而不是整数坐标值。
亚像素级角点检测的位置在摄像机标定、跟踪并重修摄像机的轨迹,或者重 建被跟踪目标的三维结构时,是一个基本的丈量值。
下面我们将讨论怎样将所求得的角点位置精确到亚像素级精度。 一个向量和 与其正交的向量的点积为0,角点则满足如图10.11所示情况。
其中,(a) 点 p 附近的图像是均匀的,其梯度为0;(b) 边沿的梯度与沿 边沿方向的q-p 向量正交。在图中的两种情况下,p 点 梯 度 与q-p 向量的点积 均为0。
图10. 11中,我们假设起始角点q 在实际亚像素级角点的附近。检测全部的 q-p 向量。若点p 位于一个均匀的地区,则点p 处的梯度为0。若q-p 向量的方向 与边沿的方向一致,则此边沿上p 点处的梯度与q-p 向量正交,在这两种情况下, p 点处的梯度与qp 向量的点积为0。我们可以在p 点四周找到许多组梯度以及相 关的向量q-p, 令其点集为0,然后可以通过求解方程组,方程组的解即为角点q 的亚像素级精度的位置,也就是精确的角点位置。
OpenCV 为我们提供了cornerSubPix() 函数,用于发现亚像素精度的角点位 置。
10.3.2 寻找亚像素角点:cornerSubPix(函数
cornerSubPix 函数用于寻找亚像素角点位置(不是整数范例的位置,而是更 精确的浮点范例位置)。
- void cornerSubPix(
- InputArray image,
- InputOutputArray corners,
- Size winSize,
- Size zeroZone,
- TermCriteria criteria)
复制代码
- 第 一 个参数,InputArray 范例的image, 输入图像,即源图像。
- 第二个参数,InputOutputArray类 型 的corners,提供输入角点的初始坐标和 精确的输出坐标。
- 第三个参数,Size范例的winSize, 搜索窗口的一半尺寸。若winSize=Size (5,5),那么就体现使用(52+1)×(52+1)=11×11大小的搜索窗口。
- 第四个参数,Size 类 型 的zeroZone, 体现死区的一半尺寸。而死区为不对 搜索区的中央位置做求和运算的地区,用来避免自相关矩阵出现的某些可 能的奇异性。值为(-1,-1)体现没有死区。
- 第五个参数,TermCriteria范例的criteria,求角点的迭代过程的终止条件。 即角点位置的确定,要么迭代数大于某个设定值,或者是精确懂到达某个 设定值。criteria 可以是最大迭代数目,或者是设定的精确度,也可以是它 们的组合。
10.3.3 综合示例:亚像素级角点检测
这个步调在上一小节Shi-Tomasi 角点检测示例步调的基础上,在 on_GoodFeaturesToTrack (回调函数中加上以下进行亚像素角点检测的代码,就成 为了亚像素级角点检测的示例步调,需添加的代码如下。
- namespace test67 {
- Mat g_srcIMage, g_grayImage;
- int g_maxCornerNumber = 33;
- int g_maxTrackerbarNumber = 500;
- RNG g_rng(12345);
- void onGoodFeaturesToTrack(int, void*) {
- if (g_maxCornerNumber <= 1) {
- g_maxCornerNumber = 1;
- }
- std::vector<Point2f>corners;
- double qualityLevel = 0.01;
- double minDistance = 10;
- int blockSize = 3;
- double k = 0.04;
- Mat copy = g_srcImage.clone();
- goodFeaturesToTrack(g_grayImage, corners, g_maxCornerNumber, qualityLevel, minDistance, Mat(), blockSize, false, k);
- std::cout << "total corners:" << corners.size() << std::endl;
- //绘制角点
- int r = 4;
- for (int i = 0; i < corners.size(); ++i) {
- circle(copy, corners[i], r, Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)), -1, 8, 0);
- imshow("srcImage", copy);
- }
- Size winSize = Size(5, 5);
- Size zeroZone = Size(-1, -1);
- TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
- //计算出亚像素角点位置
- cornerSubPix(g_grayImage, corners, winSize, zeroZone, criteria);
- //输出角点信息
- for (int i = 0; i < corners.size(); ++i) {
- std::cout << " \t" << "pos[" << i << "]" << " = (" << corners[i].x << "," << corners[i].y << ")" << std::endl;
- }
- }
- void Test() {
- g_srcImage = imread("school.jpg");
- cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
- namedWindow("srcImage");
- createTrackbar("value", "srcImage", &g_maxCornerNumber, g_maxTrackerbarNumber, onGoodFeaturesToTrack);
- imshow("srcImage", g_srcImage);
- waitKey(0);
- }
- }
- void Test67() {
- test67::Test();
- }
复制代码
10.4 本章小结
本章我们讲解了Harris 角点检测和Shi-Tomasi 角点检测,以及一种亚像素角 点检测方法。固然,也可以自己制作角点检测的函数,需要用到cornerMinEigen Val 函数和minMaxLoc 函数。最后的特性点选取,判断条件要根据自己的情况编辑。 如果对特性点,角点的精度要求更高,可以用cornerSubPix 函数将角点定位到子 像 素 。
本章核心函数清单
函数名称说明对应讲解章节cornerHarris运行Harris角点检测算子来进行角点检测10.1.4goodFeaturesToTrack结合Shi-Tomasi算子确定图像的强角点 10.2.2cornerSubPix寻找亚像素角点位置10.3.2 本章示例步调清单
示例步调序号步调说明对应章节85实现Harris角点检测:cornerHarris()函数的使用10.1.486harris角点检测与绘制10.1.587Shi-Tomasi角点检测10.2.388亚像素级角点检测10.3.3
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |