边缘检测 OpenCV-Python v4.7.0

目标

在本章中,我们将了解到:

  • Canny边缘检测的概念
  • 用于检测的OpenCV函数:cv.Canny()

理论

Canny边缘检测是一种流行的边缘检测算法。它是由John F. Canny在2006年开发的。

  • 1.它是一个多阶段的算法,我们将对每个阶段进行分析。
  • 2.减少噪音

由于边缘检测容易受到图像中噪音的影响,第一步是用5x5高斯滤波器去除图像中的噪音。我们已经在前几章中看到了这一点。

  • 3.寻找图像的强度梯度

然后用Sobel核对水平和垂直方向的平滑图像进行过滤,得到水平方向(Gx)和垂直方向(Gy)的第一导数。从这两幅图像中,我们可以找到每个像素的边缘梯度和方向,如下所示:
E d g e _ G r a d i e n t ( G )   =   G x 2 + G y 2   Edge\_Gradient(G)\ =\ \sqrt{G_x^2+G_y^2}\ Edge_Gradient(G) = Gx2+Gy2  
A n g l e ( θ ) = tan ⁡ − 1 ( G y G x ) Angle\left( \theta \right) =\tan ^{-1}\left( \frac{G_y}{G_x} \right) Angle(θ)=tan1(GxGy)
梯度方向总是垂直于边缘。它被四舍五入为四个角度之一,代表垂直、水平和两个对角线方向。

  • 4.非最大限度的压制

在得到梯度大小和方向后,对图像进行全面扫描,以去除任何可能不构成边缘的不必要的像素。为此,在每一个像素点上,检查该像素点是否是梯度方向上其附近的局部最大值。请看下面的图片:
在这里插入图片描述
Gradient Direction:梯度方向
edge:边缘

点A在边缘上(垂直方向)。梯度方向是对边缘的法线。B点和C点处于梯度方向。因此,A点与B点和C点一起被检查,看它是否形成一个局部最大值。如果是,它就会被考虑到下一阶段,否则,它就会被压制(归为零)。

简而言之,你得到的结果是一个具有 "薄边缘 "的二进制图像。

  • 5.滞后阈值处理

这个阶段决定哪些是真正的边缘,哪些不是。为此,我们需要两个阈值,minVal和maxVal。任何强度梯度大于maxVal的边缘都肯定是边缘,而那些低于minVal的边缘肯定是非边缘,所以被丢弃。那些位于这两个阈值之间的边,根据它们的连接性被分为边和非边。如果它们与 "确定的边缘 "像素相连,它们就被认为是边缘的一部分。否则,它们也会被丢弃。请看下面的图片:
在这里插入图片描述
maxVal:即maximum Value,极(最)大值
minVal:即minimum Value,极(最)小值

边A在maxVal之上,所以被认为是 “确定的边”。虽然边C低于maxVal,但它与边A相连,所以它也被认为是有效的边,我们得到了完整的曲线。但是边B,尽管它高于minVal,并且与边C在同一区域,但它没有与任何 "确定的边 "相连,所以它被丢弃了。因此,我们必须相应地选择minVal和maxVal来获得正确的结果,这一点非常重要。

这个阶段还在假设边缘是长线的基础上去除小像素的噪音。

因此,我们最终得到的是图像中的强边缘。

OpenCV中的Canny边缘检测

OpenCV将上述所有内容都放在一个函数中,即cv.Canny()。我们将看到如何使用它。第一个参数是我们的输入图像。第二个和第三个参数分别是我们的minVal和maxVal。第四个参数是aperture_size。它是用于寻找图像梯度的Sobel核的大小。最后一个参数是L2gradient,它指定了用于寻找梯度大小的方程式。如果它是True,它使用上面提到的更精确的方程,否则它使用这个函数:
E d g e _ G r a d i e n t ( G ) = ∣ G x ∣ + ∣ G y ∣ Edge\_Gradient(G)=|G_x|+|G_y| Edge_Gradient(G)=Gx+Gy
默认情况下,它为 “假”。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
edges = cv.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()

请看下面的结果:
在这里插入图片描述

其他资源

  • 1.维基百科上的Canny边缘检测器
  • 2.《Canny边缘检测教程》,作者Bill Green,2002年
    (Canny Edge Detection Tutorial by Bill Green, 2002.)

练习

写一个小程序来寻找Canny边缘检测,其阈值可以用两个轨迹杆来改变。这样,你就可以了解阈值的影响。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值