【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()

【OpenCV 例程 300篇】239. Harris 角点检测之精确定位(cornerSubPix)_第1张图片


【本节完】

版权声明:
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,计算机视觉,python,图像处理)