特征检测(一):OpenCV中的Harris角点检测技术

本文总结了OpenCV中Harris角点检测技术,其他关于Harris角点检测原理性知识点,将在后续学习过程中进行补充!

目标:

  • 我们将了解Harris Corner Detection背后的概念。
  • 我们将看到函数:cv2.cornerHarris()cv2.cornerSubPix()

理论:

    在上一章中,我们看到角落是图像中各个方向强度变化很大的区域。早在一九八八年,Chris Harris&Mike Stephens就在其论文A Combined Corner and Edge Detector中发现了这些角落的一个早期尝试,现在它被称为Harris Corner Detector。他把这个简单的想法变成了一种数学形式。它基本上找到了(U,V)所有方向上位移的强度差异。这表示如下:

E(u,v)= \ sum_ {x,y} \ underbrace {w(x,y)} _ \ text {window function} \,[\ underbrace {I(x + u,y + v)} _ \ text {shifted intensity}  -  \ underbrace {I(x,y)} _ \ text {intensity}] ^ 2

窗口函数是一个矩形窗口或高斯窗口,它给下面的像素加权。

我们必须最大化这个E(U,V)角落检测功能。这意味着,我们必须最大限度地利用第二个任期。将泰勒展开应用于上述方程式并使用一些数学步骤(请参阅您喜欢的任何标准教科书以获得完整推导),我们得到最终方程式为:

E(u,v)\ approx \ begin {bmatrix} u&v \ end {bmatrix} M \ begin {bmatrix} u \ v \ end {bmatrix}

哪里

M = \ sum_ {x,y} w(x,y)\ begin {bmatrix} I_x I_x&I_x I_y \\ I_x I_y&I_y I_y \ end {bmatrix}

这里,I_XI_Y在x图像衍生物和y方向分别。(可以很容易地找到使用cv2.Sobel())。

然后是主要部分。之后,他们创建了一个分数,基本上是一个方程,它将确定一个窗口是否可以包含角落。

R = det(M)-k(trace(M))^ 2

哪里

  • det(M)= \ lambda_1 \ lambda_2
  • trace(M)= \ lambda_1 + \ lambda_2
  • \ lambda_1并且\ lambda_2是M的特征值

所以这些特征值的值决定了一个区域是角落,边缘还是平面。

  • | R |小,这发生在\ lambda_1\ lambda_2小,该区域是平坦的。
  • 何时[R <0发生,\ lambda_1 >> \ lambda_2反之亦然,该地区是边缘。
  • [R大,当其发生\ lambda_1\ lambda_2大和\ lambda_1 \ sim \ lambda_2,该地区是一个角落。

它可以表示在一个不错的图片如下:

图像点的分类

所以哈里斯角落检测的结果是一个灰度图像与这些分数。为合适的阈值给出图像中的角落。我们会用一个简单的图像来做到这一点。

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)

结果:

Corner Detection with SubPixel Accuracy

参考:

http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html

转载请注明出处!!!

猜你喜欢

转载自my.oschina.net/u/3702502/blog/1815332