走进OpenCV-Python 8 Harris 角点检测

前言

本节将要介绍Harris角点检测

一、角点的定义

‘如果某一点在任意方向的一个微小变动都会引起灰度很大的变化,那么我们就把它称之为角点’
关于角点的具体描述可以有几种:

1、一阶导数(即灰度的梯度)的局部最大所对应的像素点
2、两条及两条以上边缘的点

3、图像中的梯度值和梯度方向的变化速率都很高的点
4、角点处的一阶导数最大,二阶导数为0,指示物体边缘变化不连续的方向
 

二、Harris角点检测原理

对于角点的检测,Harris依据上述直观判断,列出数学表达式
角点:窗口移动在水平、竖直两个方向上变化均较大的点,即Ix, Iy都比较
边界:仅在水平、或者仅在竖直方向有较大的变化量,另一个没有什么变化, 即Ix和Iy中只有一个比较大
平坦地区:在水平、竖直方向的变化量比较小。即Ix,Iy都比较小
将图像窗口平移[u, v]产生灰度变化E(u, v)

                                                                    
其中,w(x, y)是窗口函数,向量[u, v]表示某个方向,以及在该方向上的位移。由上述公式可知,E(u,v)表示某个方向上图像灰度的变化。角点检测中要是E(u, v)的值最大,就是说让方程右侧的第二项的取值最大。
,得到:

走进OpenCV-Python 8 Harris 角点检测_第1张图片
记上式最后的结果为△,则我们可以得到:

走进OpenCV-Python 8 Harris 角点检测_第2张图片

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

这里Ix和Iy是图像在x和y方向的导数(可以使用sobel算子求得)。他们根据一个用来判定窗口内是否包含角点的等式进行打分。

即:

                                                
所以根据这些特征我们可以判断一个区域是否是角点,边界或者平面:

当λ1和λ2都小时,|R|也小,这个区域就是一个平坦区域;
当λ1>>λ2 或者λ1<<λ2,R小于0,这个区域是边缘
当λ1和λ2都很大是,R也很大(λ1和λ2中的最小值都大于阈值),说明这个区域是角点。
用下面的图来表示我们的结论:

走进OpenCV-Python 8 Harris 角点检测_第3张图片

所以Harris角点检测的结果是一个由角点分数构成的灰度图像。选取适当的阈值对结果图像进行二值化我们就检测到图像中的角点。

三、OpenCV 中的 Harris 角点检测

 Open 中的函数 cv2.cornerHarris() 可以用来进行角点检测。参数如下:
  • img - 数据类型为 float32 的输入图像。必须为单通道
  • blockSize - 角点检测中要考虑的领域大小。
  • ksize - Sobel 求导中使用的窗口大小
  • k - Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06].

import cv2
import numpy as np

filename = 'box.png'
img = cv2.imread(filename)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)
dst = cv2.cornerHarris(gray,2,3,0.04)
#膨胀操作,使角点突出
dst = cv2.dilate(dst,None)
# 阈值,取决于自身图像
img[dst>0.02*dst.max()]=[0,0,255]
cv2.imshow('dst',img)
cv2.waitKey(0)

结果:

走进OpenCV-Python 8 Harris 角点检测_第4张图片

你可能感兴趣的:(走进OpenCV-Python 8 Harris 角点检测)