当前位置: 首页 > news >正文

【Emgu CV教程】11.2、Canny边缘检测

文章目录

  • 一、背景知识
  • 二、Canny()函数
  • 三、演示
    • 1.原始素材
    • 2.程序代码
    • 3.threshold1=30,threshold2=90的效果
    • 3.threshold1=100,threshold2=200的效果
  • 四、最后总结


一、背景知识

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

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

在传统的边缘检测算法中,Canny边缘检测可以更好的满足以上三个标准,其步骤包括:

  1. 使用高斯滤波器,以平滑图像,滤除噪声。
  2. 使用Sobel函数滤波,计算图像中每个像素点的梯度强度和方向。
  3. 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
  4. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
  5. 通过抑制孤立的弱边缘最终完成边缘检测。

上述五个步骤,除了第一、二、三、五步都好理解,而第四步种的“双阈值”,在有些教程中也叫“滞后阈值”,其实就是设定两个数,阈值上界maxVal和阈值下界minVal。网上有一篇大佬的文章对双阈值描述的相对简洁明了,以下是我直接拷贝过来的:

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

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

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

要想充分理解Canny函数实现过程中,最好的办法是去学习opencv的源码,但对于图像处理相关人员,只需要会用这个函数就可以,看不懂也没什么。

二、Canny()函数

Emgu CV中,Canny()函数定义如下:

public static void Canny(IInputArray image,  // 输入图像IOutputArray edges, // 输出图像double threshold1, // 滞后阈值低值double threshold2, // 滞后阈值高值int apertureSize = 3, // 用于计算图片提取的 Sobel kernel 尺寸,默认为 3bool l2Gradient = false //指定计算梯度的等式。该参数默认为 False,当参数为 True 时,其精度更高。
)

注意:

  • 一般来说,threshold2的大小是threshold1的2~3倍。
  • threshold1、threshold2越小,越能够捕获更多的边缘信息,坏处是很多噪声造成的边缘会被保留。
  • threshold1、threshold2越大,越能够获得主要的边缘信息,坏处是强边缘也有可能被去掉。

三、演示

1.原始素材

原始素材srcMat如下图:
在这里插入图片描述

2.程序代码

Mat tempMat = srcMat.Clone();
Mat dstMat = new Mat();
int threshold1;
int threshold2;threshold1=???
threshold2=???// Canny运算
CvInvoke.Canny(tempMat, dstMat, threshold1, threshold2);
CvInvoke.Imshow("Canny, " + dstMat.Size.ToString(), dstMat);

apertureSize和l2Gradient 都采用默认的值,可以不用写。

3.threshold1=30,threshold2=90的效果

运行结果如下:
在这里插入图片描述
输出的图像中大桥的边缘提取的效果很好,但是桥墩和路面部分存在很多弱边缘。

3.threshold1=100,threshold2=200的效果

在这里插入图片描述
随着threshold1和threshold2的值增大,输出的图像中去掉了更多的弱边缘,但是注意左下角的白色面包车,它的真实边缘也被去掉了很多。

四、最后总结

一幅图像想要利用Canny函数使用边缘检测,threshold1、threshold2、apertureSize、l2Gradient这四个参数需要尝试多次才能得出一个比较好的效果。

而且,图像不同,这四个参数值也可能不同,不存在一组通用的参数可以精确提取任何图像的边缘信息。


原创不易,请勿抄袭。共同进步,相互学习。

http://www.xdnf.cn/news/889975.html

相关文章:

  • 【计组】真题 2015 大题
  • ModuleNotFoundError No module named ‘torch_geometric‘未找到
  • windows VeraCrypt – 磁盘加密工具
  • Python实例题:Python计算二元二次方程组
  • Life:Internship finding
  • RMSE可以融合均值与标准差
  • 核货宝订货平台源码:构建高效智能订货系统,驱动企业数字化转型
  • Nature Methods | OmiCLIP:整合组织病理学与空间转录组学的AI模型
  • win32相关(远程线程和远程线程注入)
  • React 第五十四节 Router中useRevalidator的使用详解及案例分析
  • Next打包导出静态文件(纯前端),不要服务器端(node), 隐藏左下角调试模式
  • Conda 基本使用命令大全
  • 数据库优化实战分享技术文章大纲
  • Qt 开发中的父类与父对象的区别和父对象传递:如何选择 `QWidget` 或 `QObject`?
  • Palo Alto Networks Expedition存在命令注入漏洞(CVE-2025-0107)
  • dvwa11——XSS(Reflected)
  • 视频爬虫的Python库
  • 鸿蒙Next开发真机调试签名申请流程
  • Qt/C++学习系列之QGroupBox控件的简单使用
  • 【TinyWebServer】线程同步封装
  • Raw Denoising 论文,以及如何制作noisy-clean图像对
  • AI问答-vue3+ts+vite:http://www.abc.com:3022/m-abc-pc/#/snow 这样的项目 在服务器怎么部署
  • 亲测解决self.transform is not exist
  • vscode里如何用git
  • TIA博途中的程序导出为PDF格式的具体方法示例
  • [zynq] Zynq Linux 环境下 AXI BRAM 控制器驱动方法详解(代码示例)
  • MYSQL(三)--服务器启动参数与配置
  • 群晖NAS如何在虚拟机创建飞牛NAS
  • ABP VNext 在 Kubernetes 中的零停机蓝绿发布
  • Abaqus载荷与边界条件(Load BC)