【OpenCV】第十章: Canny边缘检测

这篇具有很好参考价值的文章主要介绍了【OpenCV】第十章: Canny边缘检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第十章: Canny边缘检测

canny边缘检测是一种一阶微分算子检测算法,但为什么还要单独拿出来讲呢,因为它几乎是边缘检测算子中最优秀的边缘检测算子,你很难找到一种边缘检测算子能显著地比Canny算子做的更好。

Canny提出了边缘检测算子优劣评判的三条标准:
1、较高的检测率。边缘检测算子应该只对边缘进行响应,检测算子不漏检任何边缘,也不应该将非边缘标记为边缘。
2、精确定位。检测到的边缘与实际边缘之间的距离要尽可能的小。
3、明确的响应。对每一条边缘只有一次响应,只得到一个点。

Canny边缘检测之所以优秀是因为它在一阶微分算子的基础上,增加了非最大值抑制和双阈值两项改进。
利用非极大值抑制不仅可以有效地抑制多响应边缘,而且还可以提高边缘的定位精度;利用双阈值可以有效减少边缘的漏检率。

  • Canny边缘检测的步骤:
    1、去噪。噪声会影响边缘检测的准确性,因此首先要将噪声过滤掉。
    2、计算梯度大小和方向。
    3、非极大值抑制。就是适当的让边缘'变瘦'。
    4、确定边缘。使用双阈值法确定最终的边缘信息。

一、Canny边缘检测原理讲解

1、用高斯滤波器除去图像噪声
为了避免检测到错误的边缘信息,我们就要先对图像进行去噪,因为噪声也集中于高频信号,很容易被识别为伪边缘。去噪就是平滑图像中的一些纹理较弱的非边缘的噪声区域,这样我们就可以得到更准确的边缘,降低了伪边缘的识别。canny双阈值,opencv,计算机视觉,学习

说明:我们一般用高斯滤波器,但是高斯核并不是固定的,核的大小也不是固定的。这个要自己根据自己图像的特点进行选择。
高斯核的大小和尺寸对边缘检测的效果具有很重要的作用。 当高斯核的尺寸一定,那么数值越大的核,对噪声的平滑效果就越小,就达不到去除伪边缘的效果。当高斯核的数值大致相当,那么核的尺寸越大,对噪声的平滑效果就越大,但同时也模糊了一些弱的边缘,容易弱边缘检测不到。所以要根据自己图像的噪声特点进行选核。一般情况下,我们都是用5x5的高斯核做为一个trade off。

2、计算梯度幅度和方向
这里我们计算的梯度是一阶的,就是做一次差分即可。但是,在计算梯度的时候我们不仅要考虑梯度值(幅度)的大小,我们还要考虑梯度的方向(就是这个梯度值是哪个方向的),比如 当我们计算某个像素点a的梯度值的时候:
当我们用的是a像素点的正左边像素点值-a像素点值的时候,这时a像素点的梯度方向就是:左-右,表示为:<--;
当我们用的是a像素点的正右边像素点值-a像素点值的时候,这时a像素点的梯度方向就是:右-左,表示为:-->;
当我们用的是a像素点的正上方像素点值-a像素点值的时候,这时a像素点的梯度方向就是:上-下,表示为:向下的箭头;
当我们用的是a像素点的正下方像素点值-a像素点值的时候,这时a像素点的梯度方向就是:下-上,表示为:向上的箭头;
同理,一个像素点的梯度方向还有左上、右上、左下、右下。所以一个像素点a的梯度值的方向有8个方向!

经典的Canny算法是用四个梯度算子来分别计算水平,垂直和对角线方向的梯度。但是通常我们都不用四个梯度算子来分别计算四个方向。因为常用的边缘差分算子,比如Rober,Prewitt,Sobel等都能计算这些方向的差分,我们以sobel算子为例介绍如何计算梯度值和梯度方向:
x方向和y方向的Sobel算子分别为:canny双阈值,opencv,计算机视觉,学习

可以看出:Sx表示x方向的Sobel算子,用于检测y方向的边缘,它同时计算了左右方向的梯度和左上右下、左下右上方向的梯度;
     Sy表示y方向的Sobel算子,用于检测x方向的边缘, 它同时计算了上下方向的梯度和左上右下、左下右上方向的梯度;(边缘方向和梯度方向垂直)。

我们用x方向的sobel算子和原图进行卷积运算,就得到一阶导数值Gx,用y方向的sobel算子和原图进行卷积运算,就得到一阶导数值Gy。然后我们根据Gx、Gy就可以确定这个像素点的梯度大小G和方向θ,公式是:
canny双阈值,opencv,计算机视觉,学习

 其中,G就是这个像素点的梯度大小,θ是这个像素点的梯度方向,arctan为反正切函数。梯度角度θ范围从弧度-π到π,然后把它近似到四个方向,分别代表水平,垂直和两个对角线方向(0°,45°,90°,135°)。
这样我们就求出了每个像素点的梯度值和梯度方向,如下图。(边缘方向和梯度方向垂直)!!!
canny双阈值,opencv,计算机视觉,学习

3、非极大值抑制
遍历一阶梯度图像中的每个像素点(这个图像里面的每个像素点都是不仅有值的大小还有方向,就是我们上一步求出了梯度图),判断当前像素点是否是周围像素点中具有相同梯度方向的最大值,如果该点是这个方向上的最大值,则保留该点;如果不是,则该点归零,就是抑制该点。

  • 为什么要这样处理?
    因为对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。对于标准3,对边缘有且应当只有一个准确的响应的标准来说,非极大值抑制可以帮助我们将局部最大值之外的所有梯度值抑制为0,这样就可以剔除掉一大部分的点,将有多个像素宽的边缘变成一个单像素宽的边缘,即将“胖边缘”变成“瘦边缘”。

  • 具体算法是什么?
    对梯度图像中每个像素进行非极大值抑制的算法是:
    1)将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。
    2)如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制。
    通常为了更加精确的计算,在跨越梯度方向的两个相邻像素之间使用线性插值来得到要比较的像素梯度,例如:
    canny双阈值,opencv,计算机视觉,学习

     将梯度分为8个方向,分别为E、NE、N、NW、W、SW、S、SE,其中0代表0-45度,1代表45-90度,2代表-90--45度,3代表-45-0度。像素点P的梯度方向为θ,则像素点P1和P2的梯度
    线性插值为:
     canny双阈值,opencv,计算机视觉,学习

 因此,非极大值抑制的伪代码描写如下:
if  Gp >= Gp1  and  Gp >= Gp2:
   Gp may be an edge
else:
   Gp should be suppressed
需要注意的是,如何标志方向并不重要,重要的是梯度方向的计算要和梯度算子的选取保持一致。

4、双阈值检测
在进行了非极大值抑制之后,剩余的梯度像素已经可以较准确地表示图像中的实际边缘了。但是,还可能仍然存在一些由于噪声和颜色变化引起的一些伪边缘存在。为了解决这些杂散的伪边缘响应,必须要对梯度像素再过滤一遍。
这次我们过滤的手段是,用高低阈值来过滤。就是人为设置一个高阈值一个低阈值,保留高于高阈值的边缘像素,抑制低于低阈值的边缘像素。
如果边缘像素的值高于高阈值,将其标记为强边缘像素;如果边缘像素值小于高阈值但大于低阈值,则将其标记为弱边缘像素;如果边缘像素值小于低阈值,则会被抑制。
双阈值检测的伪代码描写如下:
if  Gp >= HighThreshold :
   Gp is an strong edge
else if Gp >= LowThreshold:
   Gp is an weak edge
else:
   Gp should be suppressed

说明:阈值的选择取决于给定输入图像的内容。

5、进一步确认弱边缘像素的去留 (抑制孤立点)
上面第4步我们代码已经写死:去除了一些低阈值像素,同时把其他像素区分了成了强边缘像素和弱边缘像素。
下面我们再通过弱边缘像素是否和强边缘相连这条规则,确定是要保留这个弱边缘像素还是抛弃这个边缘像素。用专业一点的话讲就是:抑制孤立点。
因为通常情况下,由真实边缘引起的弱边缘像素点是与强边缘相连接的,而由噪声响应的弱边缘是不和强边缘相连的。canny双阈值,opencv,计算机视觉,学习

 canny双阈值,opencv,计算机视觉,学习

抑制孤立边缘点的伪代码:
if  Gp == LowThreshold and Gp connected to a strong edge pixel :
   Gp is a strong edge
else:
   Gp should be suppressed

二、canny边缘检测API

cv2.Canny(img, threshold1, threshold2)

#例10.1 组合不同的参数观察canny检测的效果
import cv2
import numpy as np
import matplotlib.pyplot as plt

lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp', 0)

lena_canny_1 = cv2.Canny(lena, 128, 200)   
lena_canny_2 = cv2.Canny(lena, 32, 128) 

fig, axes = plt.subplots(1,3, figsize=(10,6), dpi=100)
axes[0].imshow(lena, cmap='gray')
axes[1].imshow(lena_canny_1, cmap='gray')
axes[2].imshow(lena_canny_2, cmap='gray')
plt.show()

canny双阈值,opencv,计算机视觉,学习文章来源地址https://www.toymoban.com/news/detail-771641.html

到了这里,关于【OpenCV】第十章: Canny边缘检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python Opencv实践 - Canny边缘检测

     

    2024年02月11日
    浏览(32)
  • 【OpenCV实现图像梯度,Canny边缘检测】

    OpenCV中,可以使用各种函数实现图像梯度和Canny边缘检测,这些操作对于图像处理和分析非常重要。 图像梯度通常用于寻找图像中的边缘和轮廓。在OpenCV中,可以使用cv2.Sobel()函数计算图像的梯度,该函数可以计算图像在水平和垂直方向上的梯度。梯度的方向和大小可以帮助

    2024年02月07日
    浏览(36)
  • opencv(七)Canny边缘检测和图像轮廓检测

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 1、检测步骤 1)使用高斯滤波器,以平滑图像,滤掉噪声。 2)计算图像中每个像素点的梯度强度和方向 3)应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应 4)应用双阈值(

    2024年02月04日
    浏览(41)
  • OpenCV自学笔记十四:Canny边缘检测

    Canny边缘检测是一种经典的图像边缘检测算法,具有以下几个步骤: 1. 噪声抑制:首先对图像进行平滑处理,以去除图像中的噪声。常用的方法是应用高斯滤波器。 2. 计算梯度:通过对平滑后的图像应用Sobel算子(或其他梯度算子),计算图像的梯度幅值和梯度方向。梯度表

    2024年02月08日
    浏览(32)
  • OpenCV 笔记(12):常用的边缘检测算子—— Canny

    一阶导数、二阶导数的边缘算子虽然简单易用,但存在一些缺点。例如容易受噪声影响,容易产生虚假边缘。 John F. Canny 在 1986 年提出了 Canny 边缘检测算法。它是结合了梯度计算方法和非极大值抑制技术的一种边缘检测算法。该算法克服了之前的边缘检测算法在抑制噪声和保

    2024年02月03日
    浏览(46)
  • opencv 边缘检测 cv2.Canny()详解

    👨‍💻 个人简介: 深度学习图像领域工作者 🎉 总结链接:              链接中主要是个人工作的总结,每个链接都是一些常用demo,代码直接复制运行即可。包括:                     📌 1.工作中常用深度学习脚本                     📌 2.to

    2024年02月03日
    浏览(27)
  • OpenCV 入门教程:Laplacian算子和Canny边缘检测

    边缘检测在图像处理和计算机视觉领域中起着重要的作用。 Laplacian 算子和 Canny 边缘检测是两种常用的边缘检测方法,它们能够帮助我们准确地检测图像中的边缘信息。 OpenCV 提供了这

    2024年02月13日
    浏览(42)
  • OPENCV C++(六)canny边缘检测+仿射变换+透射变换

    图像的缩放  输入图像 输出图像 大小变换 canny边缘算子的使用  必须先转化为灰度图,作为输入 超过100是真的边缘 低于40是确定不是边缘 在中间若连接边缘 则为边缘  普通旋转缩放变换(仿射变换) 获取仿射变换的矩阵 中心点 旋转角度 大小是否变换 -10是顺时针转 输入

    2024年02月14日
    浏览(38)
  • OpenCV15-图像边缘检测:Sobel、Scharr、Laplace、Canny

    图像的边缘指的是图像中像素灰度值突然发生变化的区域,如果将图像中的每一行像素和每一列像素都描述成一个关于灰度值的函数,那么图像的边缘对应在灰度值函数中是函数值突然变大的区域。函数值得变化趋势可以用导数描述,当函数值突然变大时,导数也必然会变大

    2024年02月07日
    浏览(37)
  • 【C++】【Opencv】cv::Canny()边缘检测函数详解和示例

    Canny边缘检测是一种流行的边缘检测算法,由John F. Canny在1986年开发。它是一种多阶段过程,包括噪声滤波、计算图像强度的梯度、非最大值抑制以及双阈值检测。本文通过函数原型解读和示例对cv::Canny()函数进行详解,以帮助大家理解和使用。 Canny边缘检测的步骤如下: (

    2024年02月04日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包