角点检测中要使 E (µ, ν) 的值最大。这就是说必须使方程右侧的第二项的取值最大。对上面的等式进行泰勒级数展开然后再通过几步数学换算这里 Ix 和 Iy 是图像在 x 和 y 方向的导数。(可以使用函数 cv2.Sobel()计算得到)。
• det(M) = λ1λ2• trace (M) = λ1 + λ2λ和 λ是矩阵 M 的特征值
λ1 和 λ2 是矩阵 M 的特征值所以根据这些特征中我们可以判断一个区域是否是角点,边界或者是平面。当 λ1 和 λ2 都小时,|R| 也小,这个区域就是一个平坦区域。当 λ1≫ λ2 或者 λ1≪ λ2,时 R 小于 0,这个区域是边缘,当 λ1 和 λ2 都很大,并且 λ1~λ2 中的时,R 也很大,(λ1 和 λ2 中的最小值都大于阈值)说明这个区域是角点。可以用下图来表示我们的结论:
所以 Harris 角点检测的结果是一个由角点分数构成的灰度图像。选取适当的阈值对结果图像进行二值化我们就检测到了图像中的角点。
cv2.cornerHarris() 可以用来进行角点检测。参数如
下:
• img - 数据类型为 float32 的输入图像。
• blockSize - 角点检测中要考虑的领域大小。
• ksize - Sobel 求导中使用的窗口大小
• k - Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06]
import cv2 as cv import numpy as np def cornerHarri(imgae): gray = cv.cvtColor(imgae, cv.COLOR_BGR2GRAY) gray = np.float32(gray) dst = cv.cornerHarris(gray, 2, 3, 0.04) dst = cv.dilate(dst, None) imgae[dst>0.01*dst.max()]=[0,0,255] cv.imshow("corn",imgae) print("--------- Python OpenCV Tutorial ---------") src = cv.imread("C:/Users/weiqiangwen/Desktop/sest/data/lena.jpg") cv.namedWindow("input contours",cv.WINDOW_AUTOSIZE) cv.imshow("contours", src) cornerHarri(src) #cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) cv.waitKey(0) cv.destroyAllWindows()