概述
了解学习哈里斯角检测、cv2.connerHarris()、cv2.connerSubPix()。
原理
哈里斯角点是在任意方向上移动(u,v),都会有很明显的变化。如下图一个局部很小的区域,如果是在图片区域中移动灰度值没有变化,那么窗口内不存在角点。如果在某一个方向上移动,一个发生很大变化而另一侧没有变化,那么说明这个区域是位于该对象的边缘区域。
其表达式如下图。
其含义是对于图像I(x,y),在点(x,y)处平移(u,v)后的自相似性。其中w(x,y)是加权函数,它可以是常数,也可以是高斯加权函数。如图2所示。
根据泰勒展开和一些数学步骤后可得到如下结果
其中
公式中Ix和Iy是在x和y方向获取的区域。
最后转化为R=det(M) - k(trace(M))^2,该公式决定了一个区域内是否包含角特征。
公式中
- det(M) = λ1λ2
- trace(M) = λ1+λ2
- λ1和λ2是M的特征值。
这些特征值决定了一个区域是角,边缘还是平面。 - 当|R|很小时,即λ1和λ2很小时,该区域时平面。
- 当 R < 0时,即λ1远远大于λ2或者λ2远远大于λ1时,该区域时直线。
-
当 R很大时,即λ1和λ2都很大且近似相等,该区域时角点。
他们的关系可以表示为下图。
哈里斯角点的性质
- 该算法算子对亮度和对比度的变化不敏感。
- 算子具有旋转不变性。
- 算子不具有尺度不变性。
Python中Harris角点检测函数
cv2.cornerHarris(src, blockSize, ksize, k[, dst[,borderType]]) -> dst
其中,src - 输入为单通道8位或者浮点数图片,dst - 存储哈里斯角点检测响应的图像矩阵,矩阵大小跟src输入的一样,数据类型为浮点数, blockSize - 邻域大小,ksize - 孔径参数,k - 公式中的无限制参数,borderTyoe - 边界处理类型。
代码如下:
import cv2
import numpy as np
img = cv2.imread('harris.jpg')
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.01*dst.max()] = [0,0,255]
cv2.imshow('img', dst)
if cv2.waitKey(0) & 0xff == 27:
cv2.destroyAllWindows()
关于哈里斯角点检测我感觉博客园☆Ronny丶写得更详细,有兴趣的点击这里可以去看看。