一、步骤
1、用高斯滤波去除图像噪声,目的是平滑一些纹理较弱的非边缘区域,以得到更准确的边缘。
2、计算梯度的幅度与方向
3、非极值抑制,即适当地让边缘“变瘦”。
做法:逐一遍历像素点,判断当前像素点是否是周围像素点中具有相同梯度方向的最大值,如果改点是正/负梯度方向上的局部最大值,则保留改点;如果不是,则抑制改点(归零)。
4、确定边缘。使用双阈值算法确定最终的边缘信息。
二、代码
# canny算法:边缘检测器
def edge_demo(image):
# GaussianBlur:对图像进行降噪声
blurred = cv.GaussianBlur(image, (3, 3), 0)
gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
# X方向梯度;CV_16SC1深度
xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0)
# Y Gradient
ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1)
# edge边缘
"""
Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
image:8位输入图像
threshold1:处理过程的第一个阈值
threshold2:处理过程的第二个阈值
edges:计算得到的边缘图像信息
apertureSize:sobel算子的孔径大小
L2gradient:计算图像梯度幅度的标识,默认FALSE使用L1范数(直接将两个方向导数的绝对值相加)进行计算,true使用更精确的L2范数(两个方向的导数的平方和再开方)。
"""
# 黑白边缘图像1
edge_output = cv.Canny(xgrad,ygrad,50,150)
cv.imshow('Canny Edge1', edge_output)
# 黑白边缘图像2
edge_output1 = cv.Canny(gray, 50, 150)
cv.imshow('Canny Edge2', edge_output1)
# 彩色边缘图像1
dst = cv.bitwise_and(image, image, mask=edge_output)
cv.imshow('Color Edge1', dst)
# 彩色边缘图像2
dst = cv.bitwise_and(image, image, mask=edge_output1)
cv.imshow('Color Edge2', dst)
- 下图为计算图像x和y梯度和直接用COLOR_BGR2GRAY来进行边缘检测