Canny边缘检测

Canny边缘检测Canny边缘检测是一种非常流行的边缘检测算法,是JohnCanny在1986年提出的。它是一个多阶段的算法,即由多个步骤构成。1.图像降噪2.计算图像梯度3.非极大值抑制4.阈值筛选我们就事后诸葛亮,分析下这个步骤的缘由。首先,图像降噪。我们知道梯度算子可以用于增强图像,本质上是通过增强边缘轮廓来实现的,也就是说是可以检测到边缘的。但是,它们受噪声的影响都很大。那么,我…

大家好,又见面了,我是你们的朋友全栈君。

Canny边缘检测是一种非常流行的边缘检测算法,是John Canny在1986年提出的。它是一个多阶段的算法,即由多个步骤构成。

1.图像降噪
2.计算图像梯度
3.非极大值抑制
4.阈值筛选

我们就事后诸葛亮,分析下这个步骤的缘由。

首先,图像降噪。我们知道梯度算子可以用于增强图像,本质上是通过增强边缘轮廓来实现的,也就是说是可以检测到边缘的。但是,它们受噪声的影响都很大。那么,我们第一步就是想到要先去除噪声,因为噪声就是灰度变化很大的地方,所以容易被识别为伪边缘。

第二步,计算图像梯度,得到可能边缘。我们在前面的关于《图像梯度》文章中有所介绍,计算图像梯度能够得到图像的边缘,因为梯度是灰度变化明显的地方,而边缘也是灰度变化明显的地方。当然这一步只能得到可能的边缘。因为灰度变化的地方可能是边缘,也可能不是边缘。这一步就有了所有可能是边缘的集合。

第三步,非极大值抑制。通常灰度变化的地方都比较集中,将局部范围内的梯度方向上,灰度变化最大的保留下来,其它的不保留,这样可以剔除掉一大部分的点。将有多个像素宽的边缘变成一个单像素宽的边缘。即“胖边缘”变成“瘦边缘”。

第四步,双阈值筛选。通过非极大值抑制后,仍然有很多的可能边缘点,进一步的设置一个双阈值,即低阈值(low),高阈值(high)。灰度变化大于high的,设置为强边缘像素,低于low的,剔除。在low和high之间的设置为弱边缘。进一步判断,如果其领域内有强边缘像素,保留,如果没有,剔除。

这样做的目的是只保留强边缘轮廓的话,有些边缘可能不闭合,需要从满足low和high之间的点进行补充,使得边缘尽可能的闭合。

我们看看效果:
这里写图片描述


# 读入图像
lenna = cv2.imread("images\\lenna.png", 0)
# 图像降噪
lenna = cv2.GaussianBlur(lenna, (5, 5), 0)
# Canny边缘检测,50为低阈值low,150为高阈值high
canny = cv2.Canny(lenna, 50, 150)
cv2.imshow("canny", canny)
cv2.waitKey()

在OpenCV中,Canny函数本身应该没有将图像降噪包含在内。因此,实施Canny边缘检测时,需要在Canny函数外面执行图像降噪的过程。
这里写图片描述

调整low和high双阈值,能够得到不同的边缘效果。

canny = cv2.Canny(lenna, 100, 200)

这里写图片描述

再看看有噪声的情况:

这里写图片描述

# 读入图像
lenna = cv2.imread("images\\lenna_gauss.png", 0)
# 图像降噪
lenna = cv2.GaussianBlur(lenna, (5, 5), 0)
# Canny边缘检测
canny = cv2.Canny(lenna, 50, 150)
cv2.imshow("canny", canny)
cv2.waitKey()

这里写图片描述

效果很差啊,我们调整下高斯模糊的核大小,效果立即好了很多很多。

lenna = cv2.GaussianBlur(lenna, (9, 9), 0)

这里写图片描述

所以,Canny在有噪声的情况下表现好不好,取决于前面的降噪过程,这也是为什么OpenCV将图像降噪放在Canny函数外面的原因吧,需要你自己精心调整它。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138994.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c语言字符串分割函数「建议收藏」

    c语言字符串分割函数「建议收藏」C语言字符串分割strsep函数用于分解字符串为一组字符串。定义语句为char*strsep(char**stringp,constchar*delim);使用实例:#include<stdio.h>#include<stdlib.h>#include<string.h>intmain(){charstr[]="$GP…

    2022年5月2日
    42
  • 深度学习—2.常见的神经网络结构

    深度学习—2.常见的神经网络结构

    2021年10月6日
    53
  • jlink 与 swd 接口定义

    jlink 与 swd 接口定义1.JLink介绍J-Link是SEGGER公司为支持仿真ARM内核推出的JTAG仿真器。J-Link支持所有基于ARM架构的处理器或微控制器配合IAREWAR,ADS,KEIL等集成开发环境进行开发过程中进行单步控制执行调试。J-Link除了可以配合集成开发环境进行调试程序,进行程序下载之外,J-Link还可以单独使用。比如在产品的生产环节中,就可以单独使用J-Link进行固件的下载。JLink,SWD接口定义缺口向左,左边为JLink接口定义,右边为SWD接口定义JTAG

    2022年4月25日
    42
  • 原码反码补码运算规则_正数的原码反码补码相同吗

    原码反码补码运算规则_正数的原码反码补码相同吗一.机器数和真值在学习原码,反码和补码之前,需要先了解机器数和真值的概念.1、机器数一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号,正数为0,负数为1.比如,十进制中的数+3,计算机字长为8位,转换成二进制就是00000011。如果是-3,就是10000011。那么,这里的00000011和10000011就是机器数。2、因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数100

    2022年9月23日
    3
  • python爬虫滑动验证码_python爬虫爬取京东优惠线报

    python爬虫滑动验证码_python爬虫爬取京东优惠线报如何自动登陆京东?我们先来看一下京东的登陆页面,如下图所示:【插入图片,登陆页面】登陆框就是右面这一个框框了,但是目前我们遇到一个困呐,默认的登陆方式是扫码登陆,如果我们想要以用户民个、密码的形式登陆,就要切换一下。我们看一下这两种登陆方式是如何切换的,通过浏览器的元素检查,我们看一下两个标签。【插入图片,两种登陆方式】扫码登陆和用户登陆分别在一个div标签里面,我们可以通过css选择器选定用户登…

    2022年9月18日
    2
  • java项目视频22套「建议收藏」

    java项目视频22套「建议收藏」java项目视频22套如图所示:获取方式:关注微信公众号:javafirst发送“Java项目视频”即可获取链接

    2022年9月28日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号