7.4.3 canny边缘检测
canny边缘检测是使用最广泛的边缘检测算法之一,可以有效减少噪音的影响,同时边缘处理的效果也不错。
canny边缘检测算法可以分为以下5个步骤:
1)使用高斯滤波器,以平滑图像,滤除噪声。
2)计算图像中每个像素点的梯度强度和方向。
3)应用非极大值抑制,以消除边缘检测带来的杂散响应。
4)应用双阈值检测来确定真实的和潜在的边缘。
5)通过抑制孤立的弱边缘最终完成边缘检测。
canny算法应用双阈值的技术,即设定一个阈值上界和阈值下界,图像中的像素点如果大于阈值上界则认为必然是边缘,小于阈值下界则认为必然不是边缘,两者之间的则认为是候选项,须进行进一步处理。canny的具体原理这里不再展开,有兴趣的读者可以阅读相关文献。
canny边缘检测在opencv中的函数定义如下:
canny(image, threshold1, threshold2, edges=none, aperturesize=none, l2gradient=none)
其中主要的参数如下。
? threshold1:阈值1,即低阈值。
? threshold2:阈值2,即高阈值,低阈值用来控制边缘连接,高阈值用来控制强边缘的初始分割,低于低阈值的会被判定为不是边缘,高于高阈值的会被判定为边缘,中间区间的会通过计算判断是否为边缘。
如图7-21所示,一共有四个子图,子图a是原始图像,子图b在原始图像上叠加高斯噪声,子图c对混有高斯噪声的图像进行拉普拉斯边缘检测,子图d对混有高斯噪声的图像进行canny边缘检测。可见拉普拉斯边缘检测容易受到噪声干扰,canny边缘检测对噪声的干扰具有一定抵御能力。
img=cv2.imread("../picture/smallpig.jpeg")
img=cv2.cvtcolor(img.copy(), cv2.color_bgr2gray)
#高斯噪声
noise_img=skimage.util.random_noise(img.copy(), mode="gaussian", seed=none, clip=true,mean=0,var=0.0016)
noise_img=np.uint8(noise_img*255)
#拉普拉斯边缘检测
lap = cv2.laplacian(noise_img,cv2.cv_64f)#拉普拉斯边缘检测
lap = np.uint8(np.absolute(lap))##对lap去绝对值
#对二值图像进行反转,黑白颠倒
lap=cv2.bitwise_not(lap)
#canny边缘检测
canny = cv2.canny(noise_img,150,300)
#对二值图像进行反转,黑白颠倒
canny=cv2.bitwise_not(canny)
图7-21 canny边缘检测示例