使用Python+OpenCV进行图像处理(三)

磐创AI
关注

检测是计算机视觉任务中的主要任务之一,而且应用很广泛。检测技术可以帮助人类检测那些容易被肉眼忽略的错误;也可以”帮助“自动驾驶汽车感知空间信息。无疑自动化的检测技术的广泛应用将为我们带来效率与安全。

本篇是这个系列的第三篇。整个系列目录如下:

理解颜色模型与在图像上绘制图形(图像处理基本操作)。

基本的图像处理与滤波技术。

从特征检测到人脸检测。

轮廓检测

之前已经介绍了几种颜色模型以及如何在图像上绘制图形。还介绍了常用的图像处理技术,如:模糊、梯度、腐蚀、扩张等。本篇将把这些技术应用到图像特征检测和人脸检测中。

本篇会用到本系列前两篇中介绍的图像处理技术。

边缘检测 (Edge Detection)

边缘检测本质上是检测图像中变化剧烈或者不连续的像素点。将这些像素点连接线段即为边。实际上,在上一篇文章中我们已经介绍了一种基础的边缘检测技术:使用Sobel算子和拉普拉斯算子进行梯度滤波。通过计算图像像素值在给定方向上的导数,梯度滤波器即可以描绘出图像的边缘从而实现边缘检测。

Canny检测算法是另外一种图像边缘检测技术。而且是目前最流行的边缘检测技术之一,分为以下四个步骤实现:降噪、判断梯度及梯度方向、非最大值抑制和滞后阈值化处理。

首先通过高斯模糊技术实现降噪。然后,使用sobel算子得到图像梯度。接着使用得到的梯度,检测每一个像素点与其中周围的像素点,确认这个像素点是不是这些局部像素点中的局部最大值。如果不是局部最大值,则将这个点的像素值置为零(完全缺失,黑色)。这个过程即为非极大值抑制。

如果这个点被确认为局部最大值,则进行下一步即第四个步骤。第四步是决定之前检测出的边是否为真正边缘的最后一个决策阶段。这一决策阶段被称为滞后阈值化,它需要两个阈值(“较小阈值”、“较大阈值”)来进行决策。

给定两个不同的阈值,我们可以得到三个阈值化区间。因此,如果这个点的像素值大于两个阈值中的“较大阈值”则被判定为边缘点。相对地,如果其小于所设定的两个阈值参数中的“较小阈值”则被认定为非边缘点,即会被丢弃。另外,如果这个点的像素值位于两个参数阈值之间则是跟据其是否与”确认边缘点“之间有连接来决定是否丢弃,遵循有连接则不丢弃的原则。

img = cv2.imread('images/giraffe.jpg')

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# Canny detection without blurring

edges = cv2.Canny(image=img, threshold1=127, threshold2=127)

plt.figure(figsize = (20, 20))

plt.subplot(1, 2, 1); plt.imshow(img)

plt.axis('off')

plt.subplot(1, 2, 2); plt.imshow(edges)

plt.axis('off')

上方仅使用了一个阈值中值作判断,也没有进行图像模糊处理,边缘检测结果不是很理想。接下来让我们尝试不同的参数阈值设定:

# Set the lower and upper threshold

med_val = np.median(img)

lower = int(max(0, .7*med_val))

upper = int(min(255, 1.3*med_val))

为了更直观的比较模糊化对图像边缘检测的影响,将使用两种不同尺寸的卷积核(5x5)与(9x9)。设定两种阈值参数,一种在上述阈值设定的基础上将“较大阈值”增加100。也就意味着我们会得到四种不同的组合结果图。如下:

# Blurring with ksize = 5 

img_k5 = cv2.blur(img, ksize = (5, 5))

# Canny detection with different thresholds

edges_k5 = cv2.Canny(img_k5, threshold1 = lower, threshold2 = upper)

edges_k5_2 = cv2.Canny(img_k5, lower, upper+100)

# Blurring with ksize = 9 

img_k9 = cv2.blur(img, ksize = (9, 9))

# Canny detection with different thresholds

edges_k9 = cv2.Canny(img_k9, lower, upper)

edges_k9_2 = cv2.Canny(img_k9, lower, upper+100)

# Plot the images

images = [edges_k5, edges_k5_2, edges_k9, edges_k9_2]

plt.figure(figsize = (20, 15))

for i in range(4):

plt.subplot(2, 2, i+1)

plt.imshow(images[i])

plt.axis('off')

plt.show()

正如上图所示,模糊化可以帮助减少噪声。我们在使用卷积核尺寸为(9x9)时得到了更好的结果。而且,在使用更大的“较大阈值”时得到了更好的边缘检测结果。

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存