OpenCV 例程 300篇239. Harris 角点检测之精确定位(cornerSubPix)

Posted YouCans

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV 例程 300篇239. Harris 角点检测之精确定位(cornerSubPix)相关的知识,希望对你有一定的参考价值。

『youcans 的 OpenCV 例程300篇 - 总目录』


【youcans 的 OpenCV 例程 300篇】239. Harris 角点检测之精确定位(cornerSubPix)


角是直线方向的快速变化。角点通常被定义为两条边的交点,或者说角点的邻域应该具有两个不同区域的不同方向的边界。

角是高度有效的特征。角点检测(Corner Detection)广泛应用于运动检测、图像匹配、视频跟踪、三维重建和目标识别。


6.2 OpenCV 中的 Harris 角检测器

OpenCV 中提供了 Harris 角点检测函数 cv.cornerHarris()


函数说明:

cv.cornerHarris(src, blockSize, ksize, k[, dst=None, borderType=BORDER_DEFAULT]	) → dst

函数 cv.cornerHarris 运行 Harris 角检测器。

对于每个像素 (x,y) 计算梯度协方差矩阵 M ( x , y ) M(x,y) M(x,y)。然后计算特征:
d s t ( x , y ) = d e t M ( x , y ) − k ⋅ ( t r M ( x , y ) ) 2 dst(x,y) = det M^(x,y) - k \\cdot (tr M^(x,y))^2 dst(x,y)=detM(x,y)k(trM(x,y))2

则角点在特征响应图像中是局部极大值。 实践中定义当 R 大于设定阈值,且为局部最大值的点为角点 。

参数说明:

  • src:输入图像,单通道的 8位图像或浮点数图像
  • dst:输出图像,Harris 检测器的响应,大小与 src 相同,格式为 CV_32FC1
  • blockSize:邻域尺寸
  • ksize:Sobel 算子的孔径参数
  • k:Harris 检测器调节参数,通常取 0.04~0.06
  • borderType:边界扩充类型
    • cv.BORDER_CONSTANT
    • cv.BORDER_REPLICATE
    • cv.BORDER_REFLECT
    • cv.BORDER_REFLECT_101
    • cv.BORDER_TRANSPARENT

例程 14.20:Harris 角点检测之精确定位(cornerSubPix)

OpenCV 提供了函数 cv.cornerSubPix() 用于细化角点位置,细化了以亚像素精度检测到的角点位置。

cv.cornerSubPix(image, corners, winSize, zeroZone, criteria[, ]) → corners

函数 cv.cornerSubPix 用于细化角点位置。该算法通过将角的质心设为新的中心,迭代计算以获得角点或径向鞍点的亚像素精确位置。

参数说明:

  • image:输入图像,单通道的 8位图像或浮点数图像
  • corners:实数,输入时为角点初始坐标,输出时为角点的精细坐标
  • winSize:搜索窗口边长的一半,如 winSize = Size(5,5) 表示搜索窗口为 11*11
  • zeroZone:搜索区域中间死区大小的一半,(-1,-1) 表示不存在死区
  • criteria:迭代过程终止的判据,迭代次数达到设定值 maxCount 或角点位移小于设定阈值 epsilon

注意事项:

  1. 输入输出参数 corners 的格式必须转化实数,不是整数。
  2. 函数 cv.cornerSubPix() 用于细化角点位置,不仅可以用于对 Harris 角点检测结果进行细化检测,也可以用于对其它角点检测结果进行细化检测。
    # 14.20 Harris 角点检测之精确定位 (cornerSubPix)
    img = cv2.imread("../images/sign01.png", flags=1)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # (600, 540)
    print(img.shape)  # (600, 836, 3)

    # 角点检测
    gray = np.float32(gray)    # uint8,float32 都支持
    dst = cv2.cornerHarris(gray, 2, 3, 0.04)  # Harris 角点检测
    _, dst = cv2.threshold(dst, 0.01 * dst.max(), 255, 0)  # 提取角点
    dst = np.uint8(dst)  # (600, 836)
    # 角点检测结果图像
    imgCorner = np.copy(img)
    imgCorner[:,:,2] = cv2.bitwise_or(imgCorner[:,:,2], dst)  # 筛选角点,红色标记

    # 对检测角点进行精细定位
    ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)  # 检测连通区域
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)  # 终止判据
    fineCorners = cv2.cornerSubPix(gray, np.float32(centroids), (5,5), (-1,-1), criteria)  # (144, 2)
    # 精细定位检测图像
    imgFineCorners = np.copy(img)
    centroids = centroids.astype(np.int)  # 连通区域的质心 (x,y)
    fineCorners = fineCorners.astype(np.int)  # 精细定位的角点 (x,y)
    imgFineCorners[centroids[:, 1], centroids[:, 0]] = [0,255,0]  # Harris 检测位置,绿色
    imgFineCorners[fineCorners[:, 1], fineCorners[:, 0]] = [0,0,255]  # 精细检测位置,红色

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title("Origin")
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.subplot(132), plt.axis('off'), plt.title("Harris corners")
    plt.imshow(cv2.cvtColor(imgCorner[115:195, 90:200], cv2.COLOR_BGR2RGB))
    plt.subplot(133), plt.axis('off'), plt.title("cornerSubPix")
    plt.imshow(cv2.cvtColor(imgFineCorners[115:195, 90:200], cv2.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()


【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125821029)
Copyright 2022 youcans, XUPT
Crated:2022-7-15

238. OpenCV 中的 Harris 角点检测
239. Harris 角点检测之精确定位(cornerSubPix)
240. OpenCV 中的 Shi-Tomas 角点检测

以上是关于OpenCV 例程 300篇239. Harris 角点检测之精确定位(cornerSubPix)的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 例程300篇238. OpenCV 中的 Harris 角点检测

OpenCV 例程300篇238. OpenCV 中的 Harris 角点检测

OpenCV 例程 300篇254.OpenCV 绘制图像标记

OpenCV 例程 300篇255.OpenCV 实现图像拼接

OpenCV 例程 300篇255.OpenCV 实现图像拼接

youcans 的 OpenCV 例程 300篇254.绘制标记