【OpenCv 4 Python 3.7】Canny边缘检测(边缘提取)

39 篇文章 9 订阅
30 篇文章 5 订阅

Canny边缘检测的概念
OpenCV函数用于:cv2.Canny()
步骤:

  1. 高斯模糊 - GaussianBlur
  2. 灰度转换 - cvtColor
  3. 计算梯度 – Sobel/Scharr
  4. 非最大信号抑制
  5. 高低阈值输出二值图像

Canny边缘检测:

是一种流行的边缘检测算法。它是由约翰·F·坎尼于1986年开发的。这是一个多阶段的算法。

1、降噪

由于边缘检测对图像中的噪声很敏感,第一步是用5x5高斯滤波器去除图像中的噪声。

2、灰度转换 - cvtColor

3、图像强度梯度的求取

然后在水平方向和垂直方向用Sobel核对平滑后的图像进行滤波,得到水平方向的一阶导数(G_x)和垂直方向(G_y)从这两幅图像中,我们可以找到每个像素的边缘梯度和方向如下:

Edge_Gradient ; (G) = \sqrt{G_x^2 + G_y^2} Angle ; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg)

梯度方向总是垂直于边缘。它是圆形的四个角之一,代表垂直,水平和两个对角线方向。

4、非极大抑制

在获得梯度幅值和方向后,对图像进行全面扫描,以消除可能不构成边缘的任何不需要的像素。为此,在每个像素上,检查像素是否是其邻域内沿梯度方向的局部最大值。检查下面的图像:

Non-Maximum Suppression

A点在边缘(垂直方向)。梯度方向是正常的边缘。点B和C呈梯度方向。因此,用点B和点C检查点A,看看它是否形成局部最大值。如果是,则考虑到下一阶段,否则就会被抑制(将为零)。

简而言之,你得到的结果是一幅带有“薄边”的二值图像。

5、迟滞阈值

这个阶段决定了哪些是边缘,哪些是真正的边,哪些不是边。为此,我们需要两个阈值,MinVal和MaxVal。任何强度梯度大于MaxVal肯定是边,而小于MinVal肯定是非边缘的,所以被丢弃了。处于这两个阈值之间的人根据其连通性分为边缘或非边缘。如果它们连接到“确定边缘”像素,则它们被视为边缘的一部分。否则,它们也会被丢弃。见下图:

Hysteresis Thresholding

边缘A在MaxVal,因此被认为是“确定边缘”。虽然边缘C在MaxVal下面,但是它与边A相连,因此也被认为是有效边,我们得到了这条全曲线。但是边缘B,虽然它在上面MinVal并且与边缘C的区域相同,它没有连接到任何“确定边”,因此被丢弃。所以我们必须相应地选择MinVal和MaxVal,得到正确的结果。

这一阶段也消除了小像素噪声的假设,边缘是长线。所以我们最终得到的是图像中的强边。

OpenCV中的Canny边缘检测

OpenCV将上述所有功能都放在一个函数中,cv2.Canny()。我们会看看如何使用它。第一个参数是我们的输入图像。第二个和第三个参数分别是我们的MinVal和MaxVal。第三个参数是aperture_size。它是用于查找图像梯度的Sobel核的大小。默认情况下是3。最后一个参数是L2gradient ,它指定了求梯度幅值的公式。如果是True,它使用上面提到的更精确的方程,否则它使用这个函数:Edge_Gradient ; (G) = |G_x| + |G_y|。默认情况下,它是False

代码实现:

import cv2 as cv
import numpy as np

#边缘检测
def edge_demo(image):
    #高斯模糊:降噪
    blurred = cv.GaussianBlur(image, (3, 3), 0)
    #灰度转换
    gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
    # X Gradient,深度cv.CV_16SC1 整型
    xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0)
    # Y Gradient
    ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1)
    #edge
    #edge_output = cv.Canny(xgrad, ygrad, 50, 150)
    #50, 150  低阈值  高阈值
    edge_output = cv.Canny(gray, 50, 150)
    cv.imshow("Canny Edge", edge_output)
    #bitwise_and:变成彩色
    dst = cv.bitwise_and(image, image, mask=edge_output)
    cv.imshow("Color Edge", dst)


print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("D:/vcprojects/images/topstar.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
edge_demo(src)
cv.waitKey(0)

cv.destroyAllWindows()

结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值