计算机视觉(角点检测)- 1 - Harris角点检测
- 学习前言
- 一、Harris角点检测
- 1、什么是角点?
- 2、Harris角点检测的基本原理&基本思想
- 3、Harris角点检测的数学表达
- 4、获取点数据后,计算 I x , I y I_x,I_y Ix,Iy
- 5、比较特征值
- 二、OpenCV来实现Harris角点检测
- 1、Harris角点检测API
- 1) ```dst = cv.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])```
- 2) ```dst = cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) ```
- 2、代码举例
学习前言
今天更新一下计算机视觉的东西吧,哈哈哈o( ̄︶ ̄)o
关于角点检测呢,就是检测图像中角点的算法,常见的有四种常见的算法:Moravec角点检测算法、 Harris角点检测算法、Shi-Tomasi 算法、FAST角点检测算法.,不过常用的就两种吧——Harris角点检测算法、FAST角点检测算法(反正我基本上就只用到这两种,先着重介绍前面两种,后面再花时间介绍吧)(~ ̄▽ ̄)~
一、Harris角点检测
1、什么是角点?
怎么判断角点?我们先看一幅图:
简单粗暴的讲,红色框框住的部分就是角点 ,黑色框框住的部分是边界,蓝色框框住的…就是普通的部分。
再生动形象点估计就是用下面这张图片来表示了。
- A和B处于平坦区域,没有什么确切的特征,它们所在的位置有很多种可能;
- C和D要相对简单一些,它们是建筑物的边缘,我们可以找到一个大致的位置,但是要定位到精确的位置仍然很难。所以边缘是更好的特征,但还不够好。
- E和F是建筑的一些角落,可以很容易地发现它们的位置,因为对于建筑物角落这个图像片段,我们不管朝哪个方向移动,这个片段看起来都会不一样。
2、Harris角点检测的基本原理&基本思想
角点检测算法的基本思想:使用一个固定的窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大的灰度变化,那么我们可以认为该窗口中存在角点。
用下面这两条线过一个夹角,表示平面、边界、角点三种位置:
3、Harris角点检测的数学表达
下面我们来分析一下数学上的定义,我们先设 I ( x , y ) I(x,y) I(x,y)代表图像中 ( x , y ) (x,y) (x,y)点的像素灰度值, w ( x , y ) w(x,y) w(x,y)代表以 ( x , y ) (x,y) (x,y)为中心的Harris角点检测的滑动窗口,即加权函数。
那么 当窗口发生 ( △ x , △ y ) (△x,△y) (△x,△y)移动时,那么滑动前与滑动后对应的窗口中的像素点灰度变化数学方法描述如下:
对于 w ( x , y ) w(x,y) w(x,y)窗口函数,最简单情形就是窗口内的所有像素所对应的 w w w权重系数均为1。但有时候,我们会将 w ( x , y ) w(x,y) w(x,y)函数设定为以窗口中心为原点的二元正态分布,如高斯分布。
如果窗口中心点是角点时,移动前与移动后,该点的灰度变化应该最为剧烈,表示窗口移动时,该点在灰度变化贡献较大;而离窗口中心(角点)较远的点,这些点的灰度变化几近平缓,以示该点对灰度变化贡献较小,那么我们自然想到使用二元高斯函数来表示窗口函数。
4、获取点数据后,计算 I x , I y I_x,I_y Ix,Iy
数学表达我们搞定了,接下来是怎么解这个表达式了。其中最主要的是 I ( u , v ) − I ( u + △ x , v + △ y ) I(u,v)-I(u+△x,v+△y) I(u,v)−I(u+△x,v+△y)这一部分。高等数学里面我们都学过泰勒公式吧。
这里不会的可能需要去补习一下高等数学哦~
然后将近似结果带入,然后再恒等变换处理一下:
5、比较特征值
再分析最后的出来的这个公式,我们再把它简化一下:
这玩意是不是就是一个简单的椭圆公式了ー( ̄~ ̄)ξ,我们先假设 c = 1 c=1 c=1,方便画图。
接下来,我们就只要分析这个椭圆了。如果在图像在窗口滑动过程中灰度变化较大,那是不是 c ( x , y ; △ x , △ y ) c(x,y;△x,△y) c(x,y;△x,△y)的值就越大,那么这个椭圆也会变大?椭圆变大那么对应的 λ 1 和 λ 2 λ_1和λ_2 λ1和λ2也会变大,然后就是比较 λ 1 , λ 2 λ_1,λ_2 λ1,λ2的变化程度。如果只有其中一个变化程度较大说明是边界。
如何解出这两个特征值,并有效地进行量化评价呢?此时就引入角点响应值R 。
Harris角点检测算法就是对角点响应函数R进行阈值处理: R > t h r e s h o l d R>threshold R>threshold,即捏取R的局部极大值。
这样选出的角点可能会在某一区域特别多,并且角点窗口w(x,y)相互重合,为了能够更好地通过角点检测追踪目标,需要进行非极大值抑制(NMS)操作。
注意:Harris 检测器具有旋转不变性,但不具有尺度不变性,也就是说尺度变化可能会导致角点变为边缘,如下图所示:
想要尺度不变特性的话,可以关注SIFT特征
二、OpenCV来实现Harris角点检测
1、Harris角点检测API
1) dst = cv.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])
API功能:该功能在图像上运行Harris角检测器。
参数:
src: 输入单通道8位或浮点图像。
blockSize:它是考虑进行角点检测的邻域的大小
ksize:滑动核的大小。
k:角点响应值R计算公式中的α。
返回:
dst: 用于存储哈里斯探测器响应的图像。它的类型为CV_32FC1,大小与src相同。
2) dst = cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
API功能:通过使用特定的结构元素来放大图像。该函数使用指定的结构化元素来扩展源图像,该结构化元素确定在其上获取最大值的像素邻域的形状:
该功能支持就地模式。可以进行几次(迭代)扩张。在多通道图像的情况下,每个通道都是独立处理的。
参数:
src: 输入图像;通道数可以是任意的,但深度应为CV_8U,CV_16U,CV_16S,CV_32F或CV_64F之一。
kernel:用于扩张的结构元素;如果elemenat = Mat(),则使用3 x 3的矩形结构元素。
anchor: 锚在元素内的位置;默认值(-1,-1)表示锚点位于元素中心。
iterations:进行扩张的次数。
返回:
dst: 输出与src大小和类型相同的图像。
2、代码举例
import numpy as np
import cv2 as cv
filename = 'test_image/test_chessboard.jpg'
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
#result is dilated for marking the corners, not important
dst = cv.dilate(dst,None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]
cv.imshow('dst',img)
if cv.waitKey(0) & 0xff == 27:cv.destroyAllWindows()