目录
一、canny边缘检测介绍
1、canny
Canny边缘检测是一种广泛应用于计算机视觉和图像处理领域的边缘检测算法。它是由约翰·Canny在1986年提出的,是一种基于梯度的边缘检测算法,以其精准和稳健的性能而受到了广泛的认可。
2、边缘检测的目的:
Canny边缘检测的主要目的是从图像中准确地检测出物体的边缘,这些边缘通常表示了物体的表面变化、纹理变化或颜色变化。
3、Canny算法的步骤:
Canny边缘检测算法包括以下几个关键步骤:
-
噪声抑制:使用高斯滤波器来平滑图像,以减少噪声的影响。这有助于使后续的边缘检测更加稳健。
-
计算梯度:通过对平滑后的图像应用Sobel滤波器,计算图像的梯度幅值和方向。
-
非极大值抑制:在梯度图像上执行非极大值抑制,以保留只有在梯度方向上具有局部最大值的像素。
-
双阈值处理:将像素分为强边缘、弱边缘和非边缘三类,通过设定合适的高低阈值来实现。
-
边缘跟踪:通过连接强边缘像素与其周围的弱边缘像素,来形成完整的边缘。
1)噪声抑制:
使用高斯滤波器来平滑图像,以减少噪声的影响。这有助于使后续的边缘检测更加稳健。
2)计算梯度:
通过对平滑后的图像应用Sobel滤波器,计算图像的梯度幅值和方向。
公式:
3)非极大值抑制:
在梯度图像上执行非极大值抑制,以保留只有在梯度方向上具有局部最大值的像素。
注:一阶微分在灰度值斜坡过渡时不为零且存在较粗的边缘,较粗的边缘会增大边缘检测的误差,
因此需要细化边缘,一种较为常用的方法是非极大值抑制
非极大值抑制:即在梯度图像中寻找梯度方向上的最大值作为边缘,不是梯度方向上的最大值则抑制为 0。因为梯度方向是灰度变化最大的方向。比较梯度图像中每一点的灰度值与梯度方向上至少两个梯度图像像素点灰度值的大小,根据上述大小关系来确定是否保留该点的灰度值。
4)双阈值处理:
将像素分为强边缘、弱边缘和非边缘三类,通过设定合适的高低阈值来实现。
注:双阙值处理就是根据实际情况需要设置一个灰度高阙值和一个灰度低闽值对 NMS 后的图像进
行过滤,使得得到的边缘尽可能是直实的边缘。
红色的线上的像素会被保存,蓝色就不会。
5)边缘跟踪:
通过连接强边缘像素与其周围的弱边缘像素,来形成完整的边缘。
4、参数选择:
cv2.canny(src,threshold1,threshold2)
src:原数据
threshold1:低阈值
threshold2:高阈值
选择合适的高斯滤波器尺寸和标准差,以及合适的高低阈值,对于获得良好的边缘检测结果非常重要。
5、优缺点:
-
优点:
- Canny算法能够提供精准的边缘检测结果,对于细节和弱边缘的检测效果很好。
- 通过调整阈值,可以灵活地控制检测结果的灵敏度。
-
缺点:
- Canny算法对噪声敏感,因此在应用前通常需要对图像进行预处理以减少噪声的影响。
- 该算法的计算成本相对较高,因此在实时系统中可能需要进行优化。
总的来说,Canny边缘检测是一种高度有效的边缘检测算法,广泛用于图像处理和计算机视觉的各种应用中,包括边缘检测、物体检测、图像分割等。
二、代码实现canny边缘检测
注:数据图像:‘thesky.png’
1、导入库
import cv2
import numpy
2、读取图像:
使用cv2.imread()
函数读取了一个名为'thesky.png'的图像,并将其转换为灰度图像。
img=cv2.imread('thesky.png',cv2.IMREAD_GRAYSCALE)
#cv2.imread()函数读取了一个名为'thesky.png'的图像,并将其转换为灰度图像。
3、调整图像大小:
使用cv2.resize()
调整了图像的大小。这对于后续处理是可行的,但确保'thesky.png'的实际大小适合缩小到500x500,否则可能会失真。
img=cv2.resize(img,(500,500))
#调整了图像的大小。这对于后续处理是可行的,但确保'thesky.png'的实际大小适合缩小到500x500,否则可能会失真。
4、Canny边缘检测:
应用了Canny边缘检测,低阈值为100,高阈值为200。这些值对于某些图像可能是合适的,但对于其他图像可能需要调整。
canny=cv2.Canny(img,100,200)
#Canny边缘检测,低阈值为100,高阈值为200
5、Sobel算子:
你使用了Sobel算子来计算图像的x方向和y方向的梯度。然后,你使用cv2.convertScaleAbs()
函数来转换这些梯度值为绝对值。这是正确的。
#Sobel算子来计算图像的x方向和y方向的梯度。然后使用cv2.convertScaleAbs()函数来转换这些梯度值为绝对值。
c_x=cv2.Sobel(img,cv2.CV_64F,dx=1,dy=0)
c_x=cv2.convertScaleAbs(c_x)
c_y=cv2.Sobel(img,cv2.CV_64F,dx=0,dy=1)
c_y=cv2.convertScaleAbs(c_y)
6、组合梯度:
使用cv2.addWeighted()
函数将x方向和y方向的梯度图像组合起来。权重设置为1表示两者的重要性相同。
#cv2.addWeighted()函数将x方向和y方向的梯度图像组合起来。权重设置为1表示两者的重要性相同。
c_all=cv2.addWeighted(c_x,1,c_y,1,0)
7、显示结果:
使用cv2.imshow()
显示结果。你通过将原始图像、Canny边缘检测结果和组合的Sobel梯度结果水平堆叠来显示。这有助于在单一窗口中比较和观察各种处理效果。
#cv2.imshow()显示结果。你通过将原始图像、Canny边缘检测结果和组合的Sobel梯度结果水平堆叠来显示。
# 这有助于在单一窗口中比较和观察各种处理效果。
every=np.hstack((img,canny,c_all))
cv2.imshow('every',every)
cv2.waitKey(0)