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


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


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

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

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


    6.1 哈里斯-斯蒂芬斯角检测器(Harris)

    在基于灰度变换的角点检测算法中,Harris 算法重复性良好、检测效率较高,应用较为广泛。

    哈里斯-斯蒂芬斯角检测器(Harris and Stephens)的原理是,通过检测窗口在图像上移动,计算移动前后窗口中像素的灰度变化。角点是两条边的交点,其特征是检测窗口沿任意方向移动都会导致灰度的显著变化。

    对于点 ( x , y ) (x,y) (x,y),令 w ( x , y ) w(x,y) w(x,y) 为矩形检测窗口或高斯检测窗口, I ( x , y ) I(x,y) I(x,y) 是检测窗口在点 ( x , y ) (x,y) (x,y) 的灰度值, I ( x + u , y + v ) I(x+u,y+v) I(x+u,y+v) 是检测窗口滑动 ( u , v ) (u,v) (u,v) 距离之后的灰度值。

    计算窗口 w ( x , y ) w(x,y) w(x,y) 滑动 ( u , v ) (u,v) (u,v) 距离之后的灰度变化:
    E ( u , v ) = ∑ x , y w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] 2 E(u,v) = \sum _{x,y} w(x,y) [I(x+u, y+v) - I(x,y)]^2 E(u,v)=x,yw(x,y)[I(x+u,y+v)I(x,y)]2
    对于很小的位移 ( u , v ) (u,v) (u,v),使用一阶泰勒展开进行简化:

    E ( u , v ) = ∑ x , y w ( x , y ) [ I ( x , y ) + u I x + v I y + O ( u 2 , v 2 ) − I ( x , y ) ] 2 ≈ ∑ x , y w ( x , y ) [ u 2 I x 2 + 2 u v I x I y + v 2 I y 2 ] ≈ [ u , v ] ∑ x , y w ( x , y ) [ I x I x I x I y I x I y I y I y ] [ u v ]

    E(u,v)=x,yw(x,y)[I(x,y)+uIx+vIy+O(u2,v2)I(x,y)]2x,yw(x,y)[u2Ix2+2uvIxIy+v2Iy2][u,v]x,yw(x,y)[IxIxIxIyIxIyIyIy][uv]" role="presentation" style="position: relative;">E(u,v)=x,yw(x,y)[I(x,y)+uIx+vIy+O(u2,v2)I(x,y)]2x,yw(x,y)[u2Ix2+2uvIxIy+v2Iy2][u,v]x,yw(x,y)[IxIxIxIyIxIyIyIy][uv]
    E(u,v)=x,yw(x,y)[I(x,y)+uIx+vIy+O(u2,v2)I(x,y)]2x,yw(x,y)[u2Ix2+2uvIxIy+v2Iy2][u,v]x,yw(x,y)[IxIxIxIyIxIyIyIy][uv]
    I x , I y I_x,I_y Ix,Iy 分别是在 x, y 方向的导数,可以由 Sobel 梯度算子求出。

    记 M 为梯度的协方差矩阵:
    M = ∑ x , y w ( x , y ) [ I x I x I x I y I x I y I y I y ] M =\sum_{x,y} w(x,y)

    [IxIxIxIyIxIyIyIy]" role="presentation" style="position: relative;">[IxIxIxIyIxIyIyIy]
    M=x,yw(x,y)[IxIxIxIyIxIyIyIy]

    在几何模型中通过判断两个特征值的大小,来判定像素的属性。矩阵 M 是 I x , I y I_x,I_y IxIy 的二次函数,可以表示为椭圆形状,椭圆的长短半轴由矩阵 M 的特征值 λ 1 , λ 2 \lambda _1,\lambda _2 λ1λ2 决定,方向由特征向量决定。

    定义角点响应函数 R:
    R = d e t ( M ) − k [ t r a c e ( M ) ] 2 d e t ( M ) = λ 1 ∗ λ 2 t r a c e ( M ) = λ 1 + λ 2

    R=det(M)k[trace(M)]2det(M)=λ1λ2trace(M)=λ1+λ2" role="presentation" style="position: relative;">R=det(M)k[trace(M)]2det(M)=λ1λ2trace(M)=λ1+λ2
    R=det(M)k[trace(M)]2det(M)=λ1λ2trace(M)=λ1+λ2
    k 是调节参数(通常取 0.04~0.06)。

    角点响应函数 R 只与矩阵 M 的特征值 λ 1 , λ 2 \lambda _1,\lambda _2 λ1λ2 有关,可以用来判断区域是拐角、边缘还是平坦:

    • λ 1 , λ 2 \lambda _1,\lambda _2 λ1λ2 较小时, ∣ R ∣ |R| R 较小,即各个方向上灰度基本不变,表明检测器处于平坦区域;
    • λ 1 > > λ 2 \lambda _1 >> \lambda _2 λ1>>λ2 或 $ \lambda _2 >> \lambda _1$ 时, R < 0 R <0 R<0 ,即灰度在某个方向变化,但在其正交方向不变化,表明检测器处于边缘区域;
    • λ 1 , λ 2 \lambda _1,\lambda _2 λ1λ2 较大且 λ 1 ∼ λ 2 \lambda _1 \sim \lambda _2 λ1λ2时, ∣ R ∣ |R| R 很大,即灰度在所有方向都发生重大变化,表明检测器包含角点(或孤立点。

    6.2 OpenCV 中的 Harris 角检测器

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


    函数说明:

    cv.cornerHarris(src, blockSize, ksize, k[, dst=None, borderType=BORDER_DEFAULT]	) → dst
    cv.cornerEigenValsAndVecs(src, blockSize, ksize[, dst=None, borderType=BORDER_DEFAULT]) → dst
    cv.cornerMinEigenVal(src, blockSize[, dst=None, ksize=3, borderType=BORDER_DEFAULT]) → dst
    
    • 1
    • 2
    • 3

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

    函数 cv.cornerEigenValsAndVecs 计算图像矩阵的特征值和特征向量。

    函数 cv.cornerMinEigenVal 计算用于角点检测的梯度矩阵的最小特征值。

    对于每个像素 (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

    注意事项:

    函数 cv.cornerMinEigenVal 类似于 cv.cornerEigenValsAndVecs,但它仅计算和保存矩阵 M 的最小特征值,即 m i n ( λ 1 , λ 2 ) min(\lambda_1, \lambda_2) min(λ1,λ2)


    例程 14.19:特征检测之 Harris 角检测器

        # 14.19 角点检测之 Harris 算法
        img = cv2.imread("../images/Chess01.png", flags=1)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # (600, 540)
        # gray = np.float32(gray)  # uint8,float32 都支持
    
        blockSize = [2, 3, 5]  # 滑动窗口大小
        ksize = [3, 5, 9]  # Sobel 核函数大小
        plt.figure(figsize=(9, 9))
        for i in range(len(blockSize)):
            for j in range(len(ksize)):
                dst = cv2.cornerHarris(gray, blockSize[i], ksize[j], k=0.04)
                imgCorner = np.copy(img)
                imgCorner[dst > 0.01*dst.max()] = [0, 0, 255]  # 筛选角点,红色标记
                plt.subplot(3,3,i*len(ksize)+j+1), plt.axis('off')
                plt.imshow(cv2.cvtColor(imgCorner, cv2.COLOR_BGR2RGB))
                plt.title("blockSize={},ksize={}".format(blockSize[i], ksize[j]))
    
        plt.tight_layout()
        plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述


    【本节完】

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

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

  • 相关阅读:
    读高性能MySQL(第4版)笔记18_扩展MySQL
    如果在学习spring的时候没看过这份学习笔记+源码剖析,真的亏大了!
    Golang | Leetcode Golang题解之第147题对链表进行插入排序
    Metasploit(MSF)使用
    前端面试(2)——页面布局
    互联网黑话
    fpm模式下读取到is_cli为何为true
    【开源】基于Vue和SpringBoot的快乐贩卖馆管理系统
    重新配置chrome中ffmpeg插件
    基于FPGA的I2C读写EEPROM
  • 原文地址:https://blog.csdn.net/youcans/article/details/125820758