opencv(23) Canny边缘检测流程(Canny算子)

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

Canny 边缘检测算法 是 John F. Canny 于 1986年开发出来的一个多级边缘检测算法,也被很多人认为是边缘检测的 最优算法, 最优边缘检测的三个主要评价标准是:

  1. 低错误率: 标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。
  2. 高定位性: 标识出的边缘要与图像中的实际边缘尽可能接近。
  3. 最小响应: 图像中的边缘只能标识一次。

1 最优边缘准则

Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:

  1. 最优检测:算法能够尽可能多地标识出图像中的实际边缘,漏检真实边缘的概率和误检非边缘的概率都尽可能小;
  2. 最优定位准则:检测到的边缘点的位置距离实际边缘点的位置最近,或者是由于噪声影响引起检测出的边缘偏离物体的真实边缘的程度最小;
  3. 检测点与边缘点一一对应:算子检测的边缘点与实际边缘点应该是一一对应。

 文章来源地址https://www.toymoban.com/news/detail-848184.html

2 算法实现步骤详解

Canny边缘检测算法可以分为以下5个步骤:

1)减噪声:边缘检测对噪声非常敏感,利用5*5高斯滤波器进行操作

2)图像梯度:利用sobel求X、Y的梯度,得到边缘梯度和方向,梯度方向与边缘垂直

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

3)应用非极大值(Non_Maxinum Supperession)抑制,以消除边缘检测带来的杂散影响。该点是8邻域的边缘梯度幅值最大值,则该点保留,否则就剔除

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

点A在垂直方向边缘上,梯度方向正交于边缘。点B与点C在梯度方向,检测点A是否点B和点C形成局部极大值,如果是,进入下阶段,否则设置为0。

4)应用双阈值(Double-Thresold)检测来确定真实和潜在的边缘。

滞后阈值:梯度大于最大值是边界,低于最小值是非边界,剔除掉。介于最小值和最大值之间的边界取决于连接性,与只是真实边界相连为边界,不相连予以剔除

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

5)通过抑制孤立的弱边缘最终完成边缘检测。

边缘A高于最大值,被认为是真边缘。边缘C低于最大值,与边缘A相连,被认为是真边缘。边缘B没有与真边缘相连接,予以剔除。

第一步:消除噪声

应用高斯滤波来平滑(模糊)图像,目的是去除噪声。

高斯滤波器是将高斯函数离散化,将滤波器中对应的横纵坐标索引代入到高斯函数,从而得到对应的值。

二维的高斯函数如下:其中 (x , y)为坐标, σ 为标准差。

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

不同尺寸的滤波器,得到的值也不同,下面是 cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉  滤波器的计算公式 :

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

常见的高斯滤波器大小为 5×5 σ = 1.4  ,其近似值为:

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

第二步:计算梯度强度和方向

接下来,我们要寻找边缘,即灰度强度变化最强的位置,(一道黑边一道白边中间就是边缘,它的灰度值变化是最大的)。在图像中,用梯度来表示灰度值的变化程度和方向。

常见方法采用Sobel滤波器【水平x和垂直y方向】在计算梯度和方向

1)水平方向的Sobel算子Gx:用来检测 y 方向的边缘。

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

2)垂直方向的Sobel算子Gy:用来检测 x 方向的边缘 边缘方向和梯度方向垂直

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

3)采用下列公式计算梯度和方向:

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

梯度方向近似到四个可能角度之一(一般 0, 45, 90, 135)

第三步:非最大抑制

利用非最大抑制技术NMS来消除边误检,这一步排除非边缘像素, 仅仅保留了一些细线条(候选边缘)。

原理:遍历梯度矩阵上的所有点,并保留边缘方向上具有极大值的像素

这一步的目的是将模糊(blurred)的边界变得清晰(sharp)。通俗的讲,就是保留了每个像素点上梯度强度的极大值,而删掉其他的值。对于每个像素点,进行如下操作:

1)将其梯度方向近似为以下值中的一个(0,45,90,135,180,225,270,315)(即上下左右和45度方向)

2)比较该像素点,和其梯度方向正负方向的像素点的梯度强度

3)如果该像素点梯度强度最大则保留,否则抑制(删除,即置为0)

        cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

例如下图:点 A 位于图像边缘垂直方向. 梯度方向 垂直于边缘. B 和点 C 位于梯度方向. 因此,检查点 A 和点 B,点 C,确定点A是否是局部最大值. 如果点 A 是局部最大值,则继续下一个阶段;如果点 A 不是局部最大值,则其被抑制设为0

最后会保留一条边界处最亮的一条细线

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

第四步:滞后阈值

最后一步,Canny 使用了滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值):

这个阶段决定哪些边缘是真正的边缘,哪些边缘不是真正的边缘

经过非极大抑制后图像中仍然有很多噪声点。Canny算法中应用了一种叫双阈值的技术。即设定一个阈值上界maxVal和阈值下界minVal,图像中的像素点如果大于阈值上界则认为必然是边界(称为强边界,strong edge),小于阈值下界则认为必然不是边界,两者之间的则认为是候选项(称为弱边界,weak edge),需进行进一步处理——如果与确定为边缘的像素点邻接,则判定为边缘;否则为非边缘。

应用双阈值的方法来决定可能的(潜在的)边界。

  1. 如果某一像素位置的幅值超过 阈值maxVal, 该像素被保留为边缘像素。
  2. 如果某一像素位置的幅值小于 阈值minVal, 该像素被排除。
  3. 如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于 阈值的像素时被保留。

第五步:利用滞后技术来跟踪边界

这个阶段是进一步处理弱边界。

大体思想是,和强边界相连的弱边界认为是边界,其他的弱边界则被抑制。

由真实边缘引起的弱边缘像素将连接到强边缘像素,而噪声响应未连接。为了跟踪边缘连接,通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。

3 cv2.Canny()函数 Canny算子

函数原型:

edge=cv2.Canny(image,threshold1,threshold2[,edgs[,apertureSize[,L2gradient]]])

参数:

  1. image - 输入图片,必须为单通道的灰度图
  2. threshold1 和 threshold2 - 分别对应于阈值 minVal 和 maxVal
  3. apertureSize - 用于计算图片提取的 Sobel kernel 尺寸. 默认为 3.
  4. L2gradient - 指定计算梯度的等式的参数。该参数默认为 False。当参数为 True 时,其精度更高;采用 梯度计算公式(1)(2),

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

否则采用的梯度计算公式为:

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

4 示例: Canny边缘检测流程

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 第一步读取图片
img = cv2.imread('C:\\Users\\xxx\\Downloads\\picture1.jpeg', cv2.IMREAD_GRAYSCALE)


# 第二步:使用cv2.sobel进行sobel算子计算
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0)
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1)
sobel_x = cv2.convertScaleAbs(sobel_x)
sobel_y = cv2.convertScaleAbs(sobel_y)
sobel_xy = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)

# 第三步:使用cv2.scharr进行scharr算子计算
scharr_x = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharr_y = cv2.Scharr(img, cv2.CV_64F, 0, 1)
scharr_x = cv2.convertScaleAbs(scharr_x)
scharr_y = cv2.convertScaleAbs(scharr_y)
scharr_xy = cv2.addWeighted(scharr_x, 0.5, scharr_y, 0.5, 0)

# 第四步: 使用cv2.laplacian 拉普拉斯算子计算
lapkacian = cv2.Laplacian(img, cv2.CV_64F)
lapkacian = cv2.convertScaleAbs(lapkacian)

# 第五步: 使用cv2.Canny 算子计算
canny = cv2.Canny(img,100,200)

# 第六步:比较原图和四种算子的效果
names = ['Original','sobel','scharr','lapkacian','canny']
images =  [img,sobel_xy,scharr_xy,lapkacian,canny]

plt.figure(figsize=(19.2,9))
for i in range(2):
    for j in range(3):
        plt.subplot(2,3,i*3+j+1),plt.imshow(images[i*3+j])
        plt.title(names[i*3+j],fontsize=30), plt.xticks([]), plt.yticks([])
        num=i*3+j
        if num >= len(names)-1:
            break

plt.show()

 运行后结果如下:

cv2.canny(image, 100, 200),opencv,人工智能,计算机视觉

 

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

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

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

相关文章

  • Canny算子边缘检测原理讲解及其完整C语言实现(不使用opencv)

    作者:队友调车我吹空调 日期:2023/05/17 版权:遵循CC 4.0 BY-SA版权协议 这里是后期的笔者,本文算是笔者的学习笔记,主要是在单片机中使用的,再者就是由于某些原因,笔者不想使用opencv,因此尝试跟着原理手搓了这份代码,笔者也尽力将代码写到最简和效率最优了。然而

    2024年04月27日
    浏览(31)
  • 我在Vscode学OpenCV 图像处理三(图像梯度--边缘检测【图像梯度、Sobel 算子、 Scharr 算子、 Laplacian 算子、Canny 边缘检测】)

    这里需要区分开边缘检测和轮廓检测 边缘检测并非万能,边缘检测虽然能够检测出边缘,但边缘是不连续的,检测到的边缘并不是一个整体。图像轮廓是指将边缘连接起来形成的一个整体,用于后续的计算。 OpenCV 提供了查找图像轮廓的函数 cv2.findContours(),该函数能够查找图

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

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

    2024年02月04日
    浏览(40)
  • python --opencv图像处理Canny算子边缘检测(Roberts算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr 算子、 LOG 算子)

    边缘检测是基于灰度突变来分割图像的常用方法,其实质是提取图像中不连续部分的特征。目前常见边缘检测算子有差分算子、 Roberts 算子、 Sobel 算子、 Prewitt 算子、 Log 算子以及 Canny 算子等。 其中, Canny 算子是由计算机科学家 John F. Canny 于 1986 年提出的一种边缘检测算子

    2024年04月12日
    浏览(36)
  • python实现Canny算子边缘检测算法

        边缘检测是一种将图片中关键信息表现出来的一种图片技术,它的结果并不是字面意思上的获取图片边缘,而是将图片有用的信息勾勒出来,类似素描的结果,但是已经去掉了很多信息。如下所示,一张原始的图片是这样的:          通过边缘检测算法,我们最终得到

    2024年02月08日
    浏览(29)
  • openCV实战-系列教程5:边缘检测(Canny边缘检测/高斯滤波器/Sobel算子/非极大值抑制/线性插值法/梯度方向/双阈值检测 )、原理解析、源码解读 ?????OpenCV实战系列总目录

    打印一个图片可以做出一个函数: Canny是一个科学家在1986年写了一篇论文,所以用自己的名字来命名这个检测算法,Canny边缘检测算法这里写了5步流程,会用到之前《openCV实战-系列教程》的内容。  使用高斯滤波器,以平滑图像,滤除噪声。 计算图像中每个像素点的梯度强

    2024年02月11日
    浏览(39)
  • Canny边缘检测算子原理和matlab实现代码

      图像边缘是图像的重要信息,而Canny算子则是用于边缘检测的经典算法。在用Canny算子进行边缘检测之前必须有效地抑制噪声,该算法使用的是高斯平滑滤波。接下来计算图像中每一点的梯度向量,根据梯度向量可以得到梯度方向和梯度幅值。梯度方向在(-π,π]范围内,

    2023年04月09日
    浏览(27)
  • Halcon边缘检测Sobel、Laplace和Canny算子

    提示:文章参考了网络上其他作者的文章,以及相关书籍,如有侵权,请联系作者。        除了阈值分割外,也可以通过检测区域的边缘得到目标区域。区域的边缘像素的灰度值往往会发生灰度上的突变,针对这些跳跃性的突变进行检测和计算,可以得到区域的边缘轮廓

    2023年04月08日
    浏览(30)
  • Halcon经典的边缘检测算子Sobel/Laplace/Canny

    关于边缘检测,有许多经典的算子,各大图形处理库都有各自的边缘检测算子,这里简要介绍几种。 Sobel算子结合了高斯平滑和微分求导。它是一阶导数的边缘检测算子,使用卷积核对图像中的每个像素点做卷积和运算,然后采用合适的阈值提取边缘。Soble算子有两个卷积核

    2024年01月22日
    浏览(34)
  • opencv基础41-图像梯度-sobel算子详解cv2.Sobel()(边缘检测基础)

    图像梯度是用于描述图像变化率的概念。在图像处理中,梯度指的是图像中每个像素的灰度值变化速率或方向。它常用于边缘检测和图像特征提取。 一维图像的梯度表示为函数 f(x) 的导数,而在二维图像中,梯度是一个向量,包含两个分量:水平方向和垂直方向的灰度变化率

    2024年02月14日
    浏览(36)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包