OpenCV中的平滑、腐蚀膨胀和边缘检测

图像平滑与滤波

图像平滑是指为了抑制噪声,使图像亮度趋于平缓的处理方法就是图像平滑。图像平滑可以通过各种滤波来实现,这些图像滤波都是一些简单的卷积操作。

  • 均值滤波:即在一个卷积核的感受野内的平均值作为该像素点的值,opencv代码为cv2.blur(img, (3, 3))
  • 高斯滤波:高斯滤波会根据距离取周围的像素点加权和,越近的像素权重越大。opencv代码为cv2.GaussianBlur。由于高斯滤波对中心点权重最高,使得其对椒盐类的噪声处理效果较差。
  • 中值滤波:即在一个卷积核的感受野内的中值作为该像素点的值,opencv代码为cv2.midianBlur(img, (3, 3))。中值滤波对中心点的取值较为绝对化,故对椒盐类的噪声处理能力较强。

下面三张图分别为原图、高斯滤波结果、中值滤波结果。

image.png

图像的形态学操作

1 腐蚀与膨胀

进行膨胀(dilation)操作时,使用卷积核遍历图像,使用内核覆盖区域的最大相素值代替锚点位置的相素。这一最大化操作将会导致图像中的亮区扩大,因此名为膨胀 。腐蚀(erosion)则与膨胀相反。在OpenCV中代码如下:

1
2
3
kernel = np.ones((3, 3), np.uint8)
cv2.erode(img, kernel, iterations=1) # 腐蚀
cv2.dilate(img, kernel, iterations=1) # 膨胀

image.png

2 开运算与闭运算

开运算指的是先腐蚀后膨胀的操作,闭运算则是先膨胀后腐蚀的操作。通常用于消除噪点、沟壑,平滑物体轮廓。在OpenCV中代码如下所示:

1
2
cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)  # 开运算
cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) # 闭运算

3 梯度计算

使用膨胀的结果减去腐蚀的结果可以计算得到图像的梯度,但OpenCV中提供了更便捷的操作:cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

Sobel算子

Sobel算子是计算机视觉领域的一种重要处理方法。主要用于获得数字图像的一阶梯度,常用于边缘检测(注意与轮廓检测相区分)。Sobel算子是把图像中每个像素的上下左右四领域的灰度值加权差,在边缘处达到极值从而检测边缘。

该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的差值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如下:

image.png

在OpenCV中,可通过cv2.Sobel(src, ddepth, dx, dy, ksize)调用Sobel算子。具体操作:

1
2
3
4
5
6
7
8
img = cv2.imread('pic.png', cv2.IMREAD_GRAYSCALE)  # 读取灰度图
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) # x方向的梯度
sobelx = cv2.convertScaleAbs(sobelx) # 取绝对值将复数转为正数
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) # y方向的梯度
sobely = cv2.convertScaleAbs(sobely)

# 将x和y方向分别求到的梯度加权求和
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)

求得的结果如下所示,其中左边是原图,右边是边缘检测结果:

image.png

因为直接求两个方向的梯度效果较差,所以此处是对两个方向分别求梯度再加权平均,而不是直接求两个方向的梯度。

Canny边缘检测

Canny边缘检测算法是对图像进行的一系列用于边缘检测的操作步骤:

  1. 使用高斯滤波器对图像进行平滑处理,滤除噪声;
  2. 计算图像中每个像素点的梯度强度和方向;
  3. 使用非极大值抑制消除边缘检测带来的杂散效应;
  4. 应用双阈值检测找出潜在的边缘,抑制孤立弱边缘。

image.png

OpenCV:cv2.Canny(img, min_threshold, max_threshold)

-------------本文结束感谢您的阅读-------------