Canny算子是一种非常流行的边缘检测算法,在opencv中直接提供给了我们Canny函数,但是我们还是有必要对其原理有一定的了解。

原理

Canny算子包含四步操作:

去噪

首先要去除图像的噪声,边缘检测很容易受到噪声的影响。去噪操作中我们使用的是5*5的高斯滤波器。

计算梯度

在这一步要计算图像的梯度。不但要计算梯度的大小,还要求出梯度的方向。梯度的方向被归为四类:水平,垂直,两条对角线方向。

计算图像梯度的大小和方向的公式如下:

python 云层边缘检测 canny边缘检测算法python_像素点

非极大值抑制

经过以上操作得出的边界是非常粗糙且精度低的。我们需要在计算出梯度的大小和方向之后对整幅图像的像素点进行遍历。去除那些不在边界上的点。

对每一个像素点进行检查,看它是否是周围同方向梯度的点中梯度最大的。如果是最大的,就保留,如果不是,就抑制(归0)

python 云层边缘检测 canny边缘检测算法python_像素点_02


如图,黄色点被保留,白色点被抑制。

滞后阈值

这是确定点是否在边界上的最后一关。我们设置两个阈值(maxVal,minVal)

  • 凡是梯度大于maxVal的点我么就认为这个点处在边界上,保留
  • 梯度值大于minVal小于maxVal的点,如果这个点与某个确定为边界的点相连,保留;否则就抛弃
  • 梯度值小于minVal的点,全部抛弃

    经过这四步操作,我们就可以得到所想要的真正边界。

函数

OpenCV中提供给我们现成的函数:

cv2.Canny(sec,minVal,maxVal)
  • src:原图
  • minVal:阈值下界
  • maxVal:阈值上界

从Canny算子的原理我们可以知道,在使用Canny函数的时候两个阈值的设置是很有讲究的。如果我们吧maxVal设置的太高,就会导致高于maxVal的点很少,边界就会不清楚时断时续;如果设置的太低就会导致大于maxVal的点很多,噪声也就太多,不利于我们的后续操作。所以在实际操作中可以多试几次,找到最合适的值。

import cv2
img=cv2.imread('D://zopencv//ball.jpg',0)
mask=cv2.Canny(img,100,120)
mask1=cv2.resize(mask,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)
cv2.imshow('2',mask1)
cv2.waitKey(0)
cv2.destroyAllWindows()

python 云层边缘检测 canny边缘检测算法python_边缘检测_03