[转载+原创]Emgu CV on C# (六) —— Emgu CV on Canny边缘检测
Canny边缘检测也是一种边缘检测方法,本文介绍了Canny边缘检测的函数及其使用方法,并利用emgucv方法将轮廓检测解算的结果与原文进行比较。
图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘。Canny边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法。
Canny 边缘检测的数学原理和算法实现这里就不再了,有兴趣的读者可以查阅专业书籍。
一、概述(若果不想看,可以略过。转自:《Canny边缘检测算法原理及其VC实现详解》、“百度百科”和《我的OpenCV学习笔记(19):检测轮廓,直线,圆以及直线拟合》)
Canny边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法。更为重要的是 Canny 创立了边缘检测计算理论(Computational theory of edge detection)解释这项技术如何工作。
检测轮廓时我们使用canny边沿检测算法,这个算法其实也是基于梯度的。但是,与传统的梯度算法求边沿不同的是:
•对图像进行扫描,当遇到一个非零灰度的像素p(x,y)时,跟踪以p(x,y)为开始点的轮廓线,直到轮廓线的终点q(x,y)。
•考察图像1中与图像2中q(x,y)点位置对应的点s(x,y)的8邻近区域。如果在s(x,y)点的8邻近区域中有非零像素s(x,y)存在,则将其包括到图像2中,作为r(x,y)点。从r(x,y)开始,重复第一步,直到我们在图像1和图像2中都无法继续为止。
•当完成对包含p(x,y)的轮廓线的连结之后,将这条轮廓线标记为已经访问。回到第一步,寻找下一条轮廓线。重复第一步、第二步、第三步,直到图像2中找不到新轮廓线为止。
•至此,完成canny算子的边缘检测。
在OpenCV中使用Canny函数来检测边沿。第一个参数是待检测的图像,第二个参数是检测结果;后两个参数是那两个门限,通常高低阈值比在 2:1 到3:1之间。
参数调整:Canny 算法包含许多可以调整的参数,它们将影响到算法的计算的时间与实效。
不足:Canny 算法适用于不同的场合。它的参数允许根据不同实现的特定要求进行调整以识别不同的边缘特性。对于PC上的实时图像处理来说可能慢得无法使用,尤其是在使用大的高斯滤波器的情况下。但是,我们讨论计算能力的时候,也要考虑到随着处理器速度不断提升,有望在未来几年使得这不再成为一个问题。
二、程序实现
1、关键函数
public static void cvCanny(
IntPtr image,
IntPtr edges,
double threshold1,
double threshold2,
int apertureSize
)
第一个参数image,Input image
表示输入图像,必须为单通道灰度图
第二个参数edges,Image to store the edges found by the function
表示输出的边缘图像,为单通道黑白图
第三个参数threshold1,The first threshold
第四个参数threshold2,The second threshold.
第三个参数和第四个参数表示阈值,这二个阈值中当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割,即如果一个像素的梯度大与上限值,则被认为是边缘像素,如果小于下限阈值,则被抛弃。如果该点的梯度在两者之间则当这个点与高于上限值的像素点连接时我们才保留,否则删除。
第五个参数aperture,Aperture parameter for Sobel operator
表示Sobel 算子大小,默认为3即表示一个3*3的矩阵。Sobel 算子与高斯拉普拉斯算子都是常用的边缘算子,详细的数学原理可以查阅专业书籍。 2、编程实现
//canny算子边缘检测
IntPtr Cannyimg = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(Histimg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, );
CvInvoke.cvCanny(Histimg, Cannyimg, trackBar1.Value, trackBar1.Value * , );
MIplImage cannymi = (MIplImage)Marshal.PtrToStructure(Cannyimg, typeof(MIplImage));
Image<Gray, Byte> cannyimage = new Image<Gray, Byte>(cannymi.width, cannymi.height, cannymi.widthStep, cannymi.imageData);
pictureBox5.Image = cannyimage.ToBitmap();
三、结果分析
调整阈值与原文《【OpenCV入门指南】第三篇Canny边缘检测》使用Opencv的方法进行比较结果。
原文的图片和处理之后的图片,阈值设定为100.
本文利用emgucv方法,按照阈值为100解算获得的结果。
从两张图比对看,利用emgucv方法获取的细节更多一些,需要根据项目需要和自身设定场合进行适应性调整。
[转载+原创]Emgu CV on C# (六) —— Emgu CV on Canny边缘检测的更多相关文章
- [转载+原创]Emgu CV on C# (三) —— Emgu CV on 均衡化
本文简要描述了均衡化原理及数学实现等理论问题,最终利用emgucv实现图像的灰度均衡. 直方图的均衡化,这是图像增强的常用方法. 一.均衡化原理及数学实现(转载) 均衡化原理及数学实现可重点参看——& ...
- [转载+原创]Emgu CV on C# (一) —— Emgu CV on Visual C# 2010
2014-08-16 最近要进行图像识别,准备利用几天的时间研究一下Emgu CV,花了一晚上功夫进行调试环境安装,期间遇到了不少问题,现梳理一下安装过程和调试过程中出现的问题. 中间有转载别人的部分 ...
- [转载+原创]Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化
局部自适应阈值二值化 相对全局阈值二值化,自然就有局部自适应阈值二值化,本文利用Emgu CV实现局部自适应阈值二值化算法,并通过调节block大小,实现图像的边缘检测. 一.理论概述(转载自< ...
- [转载+原创]Emgu CV on C# (二) —— Emgu CV on 灰度化
本文主要对彩色图片灰度化的方法及其实现过程进行总结,最终给出Emgu CV实现的代码. 一.灰度化原理及数学实现(转载自——<图像灰度化方法总结及其VC实现> 该篇文章使用opencv实现 ...
- 【opencv】cv::Mat转std::vector<cv::Point2d> (注意两容器中数据类型的一致性)
获取cv::Mat大小: mymat.size() 获取cv::Mat指定位置的值:需指定数据类型,且注意数据类型应与存入时的数据类型一致,否则会导致不抛出异常的数据错误 mymat.at<,i ...
- [转载+原创]Emgu CV on C# (七) —— Emgu CV on 轮廓检测
轮廓检测 对于查找轮廓我们一般要对图像Canny检测.但是对于很特殊的场合其实我们还可以直接对二值化的图像进行轮廓的提取. 关键函数 1. cvFindContours Retrieves conto ...
- [转载+原创]Emgu CV on C# (四) —— Emgu CV on 全局固定阈值二值化
重点介绍了全局二值化原理及数学实现,并利用emgucv方法编程实现. 一.理论概述(转载,如果懂图像处理,可以略过,仅用作科普,或者写文章凑字数) 1.概述 图像二值化是图像处理中的一项基本技术,也 ...
- Linux安装mysql(Redhat6.5+MySQL5.7)(转载+原创补漏)
一.下载 这里我创建了一目录software用于存放我们待会要下载的mysql包,先去到该目录 命令:cd /software命令:wget http://mirrors.sohu.com/mysql ...
- WdatePicker()时间控制方式(转载+原创)
控制时间在制定范围内: <input class="wzsrk" name="startDateStr" id="startDateStr ...
随机推荐
- Spring事务传递性探讨
本篇主要讨论下面几点获取[下载地址] : 一: Spring 事务的传递性介绍 二: 第三方调用含有事务的Service抛异常方法探讨 一: Spring 事务的传递性介绍 事务传播行为,所谓事务的 ...
- 使用c#将多个文件放入文件夹中,并压缩下载
ZipClass.cs 这个是一个压缩文件的类,可直接复制使用,使用到的命名空间是 using System.IO;using ICSharpCode.SharpZipLib;using ICSha ...
- 【转载】在 Visual Studio 2012 中创建 ASP.Net Web Service
在 Visual Studio 2012 中创建 ASP.Net Web Service,步骤非常简单.如下: 第一步:创建一个“ASP.Net Empty Web Application”项目 创建 ...
- 每天一道LeetCode--434. Number of Segments in a String
Count the number of segments in a string, where a segment is defined to be a contiguous sequence of ...
- Android处理Bitmap使其能够不失真等比缩放裁剪后显示在ImageView上
Android开发过程中,我们有时需要动态得显示一些图片,并且这些图片的大小差距会十分大,如果需求并不是需要图片完整显示,但是需要不失真,并且要图片中间部分的情况下,我们需要做一系列处理,因为这个时候 ...
- MVC4 使用 ckfinder+ckeditor编辑器
配置ckfinder for asp.net 版本下载地址 http://cksource.com/ckfinder/downloadckeditor下载地址 http://ckeditor.com ...
- JS数据类型转换
JS 数据类型转换 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把 ...
- 网站的配置文件XML读写
网站的配置信息一般都写入到XML中,以下是简单的对xml的读写操作,仅供参考. 读操作: XmlDocument xmlDoc = new XmlDocument(); XmlReaderSettin ...
- Ajax_2
<script> var xmlHttp;//创建一个对象 function queryDetail(id){ if(window.ActiveXObject){ xmlHttp = ne ...
- ARM你必须知道的事儿——为啥“PC = PC + 8”?
为啥是“PC = PC + 8”: “PC = PC + 8”其实这样写容易让人蒙了.“PC = PC + 8”真正含义应该是: 执行处代码地址 = PC - 8: 也就是说,”PC指向的地址“领先“ ...