图像处理——Canny边缘检测

文章目录

  • 一、Canny边缘检测的过程
  • 二、Canny边缘检测过程的详细介绍
    • (一)平滑滤除噪声
    • (二)梯度和方向
    • (三)非极大值抑制
    • (四)双阈值
  • 三、Canny的实现

一、Canny边缘检测的过程

  1. 使用高斯滤波器,进行图像平滑操作,滤除噪声
    具体图像平滑操作,可以参考下面链接
    https://blog.csdn.net/qq_43279579/article/details/120766454
  2. 计算图像中每个像素点的梯度张度和方向
  3. 应用非极大值抑制,消除边缘检测带来的杂散响应
  4. 应用双阈值检测,来确定真实的和潜在的边缘

二、Canny边缘检测过程的详细介绍

(一)平滑滤除噪声

  1. 高斯滤波器
    H = [ 0.0924 0.1192 0.0924 0.1192 0.1538 0.1192 0.0924 0.1192 0.0924 ] H= \begin{bmatrix} 0.0924 & 0.1192 & 0.0924 \\ 0.1192 & 0.1538 & 0.1192 \\ 0.0924 & 0.1192 & 0.0924 \\ \end{bmatrix} H=0.09240.11920.09240.11920.15380.11920.09240.11920.0924
  2. 滤波后的结果
    e = H ∗ A = [ h 11 h 12 h 13 h 21 h 22 h 23 h 31 h 32 h 33 ] ∗ [ a b c d e f g h i ] e=H*A= \begin{bmatrix} h_{11} & h_{12} & h_{13} \\ h_{21} & h_{22} & h_{23} \\ h_{31} & h_{32} & h_{33} \\ \end{bmatrix} *\begin{bmatrix} a & b & c \\ d & e & f \\ g & h & i \\ \end{bmatrix} e=HA=h11h21h31h12h22h32h13h23h33adgbehcfi
    通过对应项乘积求和,得到最中心像素点的值。通过上面方式,求解每个像素点,从而获得滤波去噪的图像。

(二)梯度和方向

  1. 梯度的求法利用Sobel算子
    具体过程可以参考下面链接
    https://blog.csdn.net/qq_43279579/article/details/120785076
  2. 方向求解
    θ = arctan ⁡ ( G y / G x ) \theta=\arctan(G_y/G_x) θ=arctan(Gy/Gx)
    其中,Gy表示垂直方向的梯度,Gx表示水平方向的梯度。

(三)非极大值抑制

  1. 线性插值法
    图像处理——Canny边缘检测_第1张图片
    C表示需要判断是否为极大值的像素点,G1,G2,G3,G4分别为G邻近的像素点,QN表示C的梯度方向,从N到Q。求解G1,G2,G3,G4的梯度值分别为M(Gi)(i=1,2,3,4)。
    w = G 1 Q / G 1 G 2 w=G_1Q/G_1G_2 w=G1Q/G1G2
    Q点的梯度
    M ( Q ) = w ∗ M ( G 1 ) + ( 1 − w ) ∗ M ( G 2 ) M(Q)=w*M(G_1)+(1-w)*M(G_2) M(Q)=wM(G1)+(1w)M(G2)
    同理可以求解N点的梯度。
    判断C点梯度是否是其中最大的梯度点,如果是最大的点表示,C是其中的极大值点。如果不是最大梯度,表示C不是边缘点,应该抑制它。
  2. 简化方法
    一个像素点包含8个邻近的像素点,把一个像素点的梯度分散为8个方向,这样就不用计算插值。就只需要判断该点的梯度方向上邻近的点是否小于目标像素点。

(四)双阈值

  1. 阈值说明
    maxval表示最大梯度阈值,minval表示最小梯度阈值。
    当梯度值>maxval,则处理为边界。
    当minval<梯度值 当梯度值 图像处理——Canny边缘检测_第2张图片
    对于C点来说,它与A连接,所以保留,而对于B来说,它未与边界的点连接,所以舍弃。

三、Canny的实现

  1. opencv的Canny函数

    def Canny(image: Any,
              threshold1: Any,
              threshold2: Any,
              edges: Any = None,
              apertureSize: Any = None,
              L2gradient: Any = None)
    

    部分参数说明

    threshold1:最小阈值
    threshold2:最大阈值

  2. 实际实现举例

    import cv2
    import numpy as np
    def showImg(img, name):
        cv2.imshow(name, img)
        cv2.waitKey(10000)
        cv2.destroyAllWindows()
    lena = cv2.imread("Lena.png", cv2.IMREAD_GRAYSCALE)
    # Canny的边缘检测
    canny1 = cv2.Canny(lena, 80, 150)
    canny2 = cv2.Canny(lena, 50, 100)
    result = np.hstack((lena, canny1, canny2))
    showImg(result, 'result')
    

    图像处理——Canny边缘检测_第3张图片
    通过结果对比,可以发现双阈值指定的越小,边界就体现的越明细

你可能感兴趣的:(opencv图像处理,python,opencv)