使用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)时得到了更好的结果。而且,在使用更大的“较大阈值”时得到了更好的边缘检测结果。
    
    
    1  2  3  下一页>