Python - opencv (九)角点检测

参考:https://blog.csdn.net/poem_qianmo/article/details/29356187

https://zhuanlan.zhihu.com/p/68571164

在图像处理和与计算机视觉领域,兴趣点(interest points),或称作关键点(keypoints)、特征点(feature points) 被大量用于解决物体识别,图像识别、图像匹配、视觉跟踪、三维重建等一系列的问题。我们不再观察整幅图,而是选择某些特殊的点,然后对他们进行局部有的放矢的分析。如果能检测到足够多的这种点,同时他们的区分度很高,并且可以精确定位稳定的特征,那么这个方法就有使用价值。

图像特征类型可以被分为如下三种:

<1>边缘
<2>角点 (感兴趣关键点)
<3>斑点(Blobs)(感兴趣区域)
其中,角点是个很特殊的存在。他们在图像中可以轻易地定位,同时,他们在人造物体场景,比如门、窗、桌等出随处可见。因为角点位于两条边缘的交点处,代表了两个边缘变化的方向上的点,,所以他们是可以精确定位的二维特征,甚至可以达到亚像素的精度。且其图像梯度有很高的变化,这种变化是可以用来帮助检测角点的。需要注意的是,角点与位于相同强度区域上的点不同,与物体轮廓上的点也不同,因为轮廓点难以在相同的其他物体上精确定位。

 

1. Harris 

将窗口向各个方向 移动(u , v)然后计算所有差异的总和。表达式如下:

[公式]

数学转换后:

[公式]

其中:

[公式]

[公式] 和 [公式] 是图像在 x 和 y 方向的导数(可以用函数cv2.Sobel()计算得到).

最终,根据一个用来判定窗口内是否包含角点的等式进行打分:

[公式]

其中:

  • [公式] 。
  • [公式] 。
  • [公式] 和 [公式] 是矩阵 M 的特征值。

我们根据这些特征来判断一个区域是角点,边界还是平面: - 当 [公式] 和 [公式] 都小时, [公式] 也小,则为平面区域。 - 当 [公式] 或者 [公式] 时,R小于0,则为边缘。 - 当 [公式] 和 [公式] 都很大时,且 [公式] 中时,R也很大,( [公式] 和 [公式] 中的最小值都大于阈值),则为角点。

如图所示:

 

 

 代码:

cv2.cornerHarris() 可以用来进行角点检测,参数如下:

  • img - 输入图像。
  • blockSize - 角点检测中领域像素的大小。
  • ksize - Sobel 求导中使用的窗口大小
  • k - Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06]

示例:

将一个棋盘作为输入,来计算它的角点:

 

 

 代码:

 1 import numpy as np
 2 import cv2
 3 
 4 def harris(image, opt=1):
 5     # Detector parameters
 6     blockSize = 2
 7     apertureSize = 3
 8     k = 0.04
 9     
10     # Preprocess
11     gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
12     ret, thresh1 = cv2.threshold(gray,65,255,cv2.THRESH_BINARY)
13     ret = cv2.morphologyEx(thresh1, cv2.MORPH_OPEN, np.ones((5,5), np.uint8))
14 
15     # Detecting corners
16     dst = cv2.cornerHarris(ret, blockSize, apertureSize, k)
17     image[dst>0.1*dst.max()]=[0,0,255]
18     return image

结果:

 

 

 

2. Shi-thomas

✔️ Shi-Tomas是源于《Good Features to Track》,其中对Harris角点检测算法改进后的新算法。

✔️ Shi-Tomas使用的打分函数为:

[公式]

如果打分超过阈值,则认为它是一个角点,只有当 [公式] 和 [公式] 都大于之最小值,才可以被认为是角点(绿色区域)

代码:

 1 def shi_thomas(image, opt=1):
 2     # Detecting corners
 3     gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 4     ret, thresh1 = cv2.threshold(gray,65,255,cv2.THRESH_BINARY)
 5     ret = cv2.morphologyEx(thresh1, cv2.MORPH_OPEN, np.ones((5,5), np.uint8))
 6     corners = cv2.goodFeaturesToTrack(ret, 80, 0.05, 10)
 7     print(len(corners))
 8     for pt in corners:
 9         print(pt)
10         b = np.random.random_integers(0, 256)
11         g = np.random.random_integers(0, 256)
12         r = np.random.random_integers(0, 256)
13         x = np.int32(pt[0][0])
14         y = np.int32(pt[0][1])
15         cv2.circle(image, (x, y), 5, (int(b), int(g), int(r)), 2)
16     # output
17     return image

 

 用cornerSubPix可以令goodFeaturesToTrack效果更出色。

 

 

 

 

posted @ 2021-08-13 11:24  Asp1rant  阅读(1231)  评论(0编辑  收藏  举报