边缘检测算法--------canny

本文深入解析了Canny边缘检测算法,一种广泛应用于图像处理领域的经典算法。文章详细介绍了算法的五步流程:高斯滤波去噪、计算梯度强度和方向、非极大值抑制、双阈值检测及抑制孤立低阈值点,旨在帮助读者理解并掌握这一核心图像处理技术。

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

在目前常用的边缘检测方法中,Canny边缘检测算法是具有严格定义的,可以提供良好可靠检测的方法之一。由于它具有满足边缘检测的三个标准和实现过程简单的优势,成为边缘检测最流行的算法之一。

Canny边缘检测算法可以分为以下5个步骤:
1)使用高斯滤波器,以平滑图像,滤除噪声。
2) 计算图像中每个像素点的梯度强度和方向。
3)应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
4)应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
5) 通过抑制孤立的弱边缘最终完成边缘检测

步骤:
(1)高斯滤波(去燥)
目的:为了尽可能减少噪声对边缘检测结果的影响,所以必须滤除噪声以防止由噪声引起的错误检测。
尺寸为3x3的高斯卷积核的例子(需要注意归一化):
在这里插入图片描述
若图像中一个3x3的窗口为A,要滤波的像素点为e,则经过高斯滤波之后,像素点e的亮度值为:
在这里插入图片描述
其中*为卷积符号,sum表示矩阵中所有元素相加求和。

高斯卷积核大小的选择将影响Canny检测器的性能。尺寸越大,检测器对噪声的敏感度越低,但是边缘检测的定位误差也将略有增加。一般5x5是一个比较不错的trade off。

(2)计算梯度强度和方向
图像中的边缘可以指向各个方向,因此Canny算法使用四个算子来检测图像中的水平、垂直和对角边缘。边缘检测的算子(如Roberts,Prewitt,Sobel等)返回水平Gx和垂直Gy方向的一阶导数值,由此便可以确定像素点的梯度G和方向theta
在这里插入图片描述
其中G为梯度强度, theta表示梯度方向,arctan为反正切函数
在这里插入图片描述
若图像中一个3x3的窗口为A,要计算梯度的像素点为e,则和Sobel算子进行卷积之后,像素点e在x和y方向的梯度值分别为:
在这里插入图片描述
其中*为卷积符号,sum表示矩阵中所有元素相加求和。
根据公式在这里插入图片描述
便可以计算出像素点e的梯度和方向。

(3)非极大值抑制
非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于“瘦”边。对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。对于标准3,对边缘有且应当只有一个准确的响应。而非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0,对梯度图像中每个像素进行非极大值抑制的算法是:

1)将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。
2)如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制。
在这里插入图片描述
如图3-2所示,将梯度分为8个方向,分别为E、NE、N、NW、W、SW、S、SE,其中0代表0045o,1代表45090o,2代表-900-45o,3代表-4500o。
像素点P的梯度方向为theta,则像素点P1和P2的梯度线性插值为:
在这里插入图片描述

(4) 双阈值检测(设定阈值,规定成为边缘,梯度需要达到的界限)
在施加非极大值抑制之后,剩余的像素可以更准确地表示图像中的实际边缘。然而,仍然存在由于噪声和颜色变化引起的一些边缘像素为了解决这些杂散响应必须用弱梯度值过滤边缘像素,并保留具有高梯度值的边缘像素,可以通过选择高低阈值来实现。如果边缘像素的梯度值高于高阈值,则将其标记为强边缘像素;如果边缘像素的梯度值小于高阈值并且大于低阈值,则将其标记为弱边缘像素;如果边缘像素的梯度值小于低阈值,则会被抑制。阈值的选择取决于给定输入图像的内容。
在这里插入图片描述
(5)抑制孤立低阈值点
到目前为止,被划分为强边缘的像素点已经被确定为边缘,因为它们是从图像中的真实边缘中提取出来的。然而,对于弱边缘像素,将会有一些争论,因为这些像素可以从真实边缘提取也可以是因噪声或颜色变化引起的。为了获得准确的结果,应该抑制由后者引起的弱边缘。通常,由真实边缘引起的弱边缘像素将连接到强边缘像素,而噪声响应未连接。为了跟踪边缘连接,通过查看弱边缘像素及其8个邻域像素只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。
在这里插入图片描述
代码:

import cv2 
import numpy as np

def img_show(img,name='image'):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyWindow(name)
    
img=cv2.imread("lenna.jpg",cv2.IMREAD_GRAYSCALE)
#设置双阈值
canny1=cv2.Canny(img,50,110)
canny2=cv2.Canny(img,100,180)
res=np.hstack((canny1,canny2))
img_show(res)

原图
在这里插入图片描述
canny检测
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值