本文总结了OpenCV中Harris角点检测技术,其他关于Harris角点检测原理性知识点,将在后续学习过程中进行补充!
目标:
- 我们将了解Harris Corner Detection背后的概念。
- 我们将看到函数:cv2.cornerHarris(),cv2.cornerSubPix()
理论:
在上一章中,我们看到角落是图像中各个方向强度变化很大的区域。早在一九八八年,Chris Harris&Mike Stephens就在其论文A Combined Corner and Edge Detector中发现了这些角落的一个早期尝试,现在它被称为Harris Corner Detector。他把这个简单的想法变成了一种数学形式。它基本上找到了所有方向上位移的强度差异。这表示如下:
窗口函数是一个矩形窗口或高斯窗口,它给下面的像素加权。
我们必须最大化这个角落检测功能。这意味着,我们必须最大限度地利用第二个任期。将泰勒展开应用于上述方程式并使用一些数学步骤(请参阅您喜欢的任何标准教科书以获得完整推导),我们得到最终方程式为:
哪里
这里,和在x图像衍生物和y方向分别。(可以很容易地找到使用cv2.Sobel())。
然后是主要部分。之后,他们创建了一个分数,基本上是一个方程,它将确定一个窗口是否可以包含角落。
哪里
- 并且是M的特征值
所以这些特征值的值决定了一个区域是角落,边缘还是平面。
- 当小,这发生在与小,该区域是平坦的。
- 何时发生,反之亦然,该地区是边缘。
- 当大,当其发生和大和,该地区是一个角落。
它可以表示在一个不错的图片如下:
所以哈里斯角落检测的结果是一个灰度图像与这些分数。为合适的阈值给出图像中的角落。我们会用一个简单的图像来做到这一点。
Harris角点探测器在OpenCV中
为此, OpenCV具有函数cv2.cornerHarris()。它的论据是:
- img - 输入图像,应该是灰度和float32类型。
- 块大小 - 这是考虑角落检测的邻域大小
- ksize - 使用Sobel衍生物的孔径参数。
- 方程中的k - 哈里斯检测器自由参数。
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()
具有SubPixel准确性的角落
有时候,您可能需要以最高精度找到角点。OpenCV带有一个函数cv2.cornerSubPix(),它进一步细化了以亚像素精度检测到的角点。下面是一个例子。像往常一样,我们需要先找到哈里斯的角落。然后我们通过这些角的质心(可能有一些像素位于角落,我们取其质心)来优化它们。哈里斯的角落标记为红色像素,精致的角落标记为绿色像素。对于这个函数,我们必须定义何时停止迭代的标准。我们停止指定次数的迭代或达到一定的准确度,以先发生者为准。我们还需要定义要搜索拐角的邻域的大小。
import cv2 import numpy as np filename = 'chessboard2.jpg' img = cv2.imread(filename) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # find Harris corners gray = np.float32(gray) dst = cv2.cornerHarris(gray,2,3,0.04) dst = cv2.dilate(dst,None) ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0) dst = np.uint8(dst) # find centroids ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst) # define the criteria to stop and refine the corners criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria) # Now draw them res = np.hstack((centroids,corners)) res = np.int0(res) img[res[:,1],res[:,0]]=[0,0,255] img[res[:,3],res[:,2]] = [0,255,0] cv2.imwrite('subpixel5.png',img)
结果:
参考:
http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html
转载请注明出处!!!