[翻译]Harris Corner Detection

这是opencv3.0.0的python版官方文档,原文在这里

目标

这一章节,将

  • 理解Harris角点检测算法背后的原理
  • 学习两个函数:cv2.cornerHarris()cv2.cornerSubPix()

理论

上一章,我们知道了角点是图像中各个方向亮度(intensity,0~255)变化都很大的区域。最早尝试做角点检测的是Chris Harris和Mike Stephens,1988年,记录在文献《A Combined Corner and Edge Detector》中,因此现在叫做Harris角点检测。他把这个简单的想法用数学形式表达了出来。它基本找到了(u, v)各个方向上位移后明亮度(Intensity)的差异,公式为:

[翻译]Harris Corner Detection_第1张图片
公式1

window function是一个矩形窗口或者高斯窗口,是像素的权重。

为了检测角点,我们必须让E(u, v)最大化。也就是说,我们要让第二项最大。将Taylor Expansion应用于上述方程并使用一些数学步骤(请参考您喜欢的任何标准教科书进行完全推导),我们得到最终的等式:

[翻译]Harris Corner Detection_第2张图片
公式2

其中
[翻译]Harris Corner Detection_第3张图片
公式3

这里,I x和I y分别是x和y方向的导数。(可以很容易的通过 cv2.Sobel()得到)。

接下来就是重点部分。上述操作结束后,会得到一个分数,基于一个用来决定窗口内是否包含角点的等式。


公式4

其中


[翻译]Harris Corner Detection_第4张图片
公式4说明

所以这些特征值决定了这个区域是角点,还是边缘,还是flat。

  • 当|R|比较小时,也就是lambda 1和lambda 2比较小,区域是flat
  • 当R<0时, 也就是lambda 1远大于lambda 2或反之亦然,区域是边缘
  • 当R比较大时,也就是lambda 1和lambda2都大且相似,区域是角点

可以用下面的图来表示


[翻译]Harris Corner Detection_第5张图片
图1

所以Harris角点检测的结果是一个带着这些分数的灰度图。图像角点检测需要一个合适的阈值。我们将用一个简单的图来实现

Opencv中的Harris角点检测

Opencv中有一个函数cv2.cornerHarris()用来实现这个算法,参数是:

  • img - 输入图片,需要灰度图且类型float32
  • blockSize - 是角点检测考虑的邻域大小
  • ksize - sobel所用参数
  • k - Harris检测器中的自由参数
    看下面的例子:
import cv2
import numpy as np

filename = 'chessboard.jpg'
img = cv2.imread(filename)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)
dst = cv2.cornerHarris(gray,2,3,0.04)

#result is dilated for marking the corners, not important
dst = cv2.dilate(dst,None)

# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]

cv2.imshow('dst',img)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

下面是三个结果图:


[翻译]Harris Corner Detection_第6张图片
结果图

你可能感兴趣的:([翻译]Harris Corner Detection)