图像处理——Canny边缘检测

本文详细介绍了Canny边缘检测算法的四个步骤:高斯滤波、梯度和方向计算、非极大值抑制以及双阈值检测。通过实例展示了如何使用OpenCV库在Python中实现这一经典算法,并探讨了不同阈值设置对边缘检测效果的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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. 线性插值法
    在这里插入图片描述
    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<梯度值<maxval,则连接边界就保留,否则舍弃。
    当梯度值<minval,舍弃。
    在这里插入图片描述
    对于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')
    

    在这里插入图片描述
    通过结果对比,可以发现双阈值指定的越小,边界就体现的越明细

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值