hrris检测类别分为flat、edge、corner三类
flat:
沿x、y方向梯度变化均不明显,可判定为普通平面区域
edge:
沿x方向梯度变化明显,y方向不同明显,可以判定为y方向的边界
corner:
沿x、y方向梯度变化都非常明显,可判定为一个角点
数学证明
设图像上的点坐标(x,y),经过平移之后
定义自相似性为:
其中,w(u,v)是权值,赋予图像窗口中不同点不同的重要性,比如可以是常数或者高斯加权函数。我们不妨设w=1便于推导公式
由于右式不利于化简,可用其泰勒展开式近似:
因此:
然后写成矩阵的形式:
其中
将M带入上式可得:
可以注意到,此方程类似于椭圆方程。由于M是实对称矩阵,可以利用矩阵对角化得到:
这里不妨设H是单位阵,则:
则
,
从而可以得到:
由于式中不含下x,y,不妨设c=1,则有:
类比于标准椭圆方程:
可得
可以根据椭圆的特征得出结论:
1> 两个特征值都很小且近似相等,则判定为“flat”.
2>两个特征值相差较大,则自相关函数在某一方向较大,其他方向上小,则判定为”edge“.
3>两个特征值都大且近似相等,则判定为”corner“.
具体判定时使用指标角点相应R值:
其中
代码演示
cv2.cornerHarris(src,blockSize,ksize,k,dst=None,borderType=None)
参数说明:
src:原图像
blockSize:角点检测窗口大小
ksize:Sobel算子(计算梯度)窗口大小
k:超参数,一般设置为 0.04~0.06 即可
import cv2
import numpy as np
src = cv2.imread('E:\\opencv\\board.jpg')
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
src_gray_float32 = np.float32(src_gray)
src_harris = cv2.cornerHarris(src_gray_float32, 6, 3, 0.04)
src[src_harris>0.01*src_harris.max()] = [0,0,255]
cv2.imshow('src_harris', src_harris)
cv2.imshow('src_result', src)
cv2.imwrite('E:\\opencv\\harris.jpg', src_harris)
cv2.imwrite('E:\\opencv\\src_result.jpg', src)
cv2.waitKey(0)
cv2.destroyAllWindows()