ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:208.79KB ,
资源ID:7147979      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7147979.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Canny边缘检测与轮廓提取.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Canny边缘检测与轮廓提取.docx

1、Canny边缘检测与轮廓提取摘要边缘检测是图像处理和计算机视觉中的基本问题,它的目的是标识出数字图像中亮度变化明显的点。图像经过边沿检测处理之后,不仅大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。事实上,边缘存在于图像的不规则结构和不平稳现象中,也即存在于信号的突变点处,这些点给出了图像轮廓的位置。这些轮廓常常是我们在图像边缘检测时,所需要的非常重要的一些特征条件,这就需要我们对一幅图像检测并提取出它的边缘。可用于图像边缘检测和轮廓提取的方法有很多,其中包括有常见的Robert 边缘算子、Prewitt 边缘算子、Sobel 边缘算子等等。本文首先将会从数字图

2、像处理的角度,对几种边缘检测算法进行详细的分析,然后会并选择其中一种边缘检测算法进行实验。考虑到以后进一步的学习,本文将会使用openCV对算法进行实现。最后,本文将会把实验获得的实际效果,与理论分析的结果进行比对,并以此对本次实验进行总结。关键字:边缘检测 轮廓提取 图像处理 openCVAbstractEdge detection is the basic problem in image processing and computer vision, its purpose is to identify the digital image brightness changes in th

3、e obvious points.Image after edge detection processing, not only greatly reduces the amount of data, and eliminated can think irrelevant information, keep the structure of the image important attribute.Edge of image, in fact, exist in the image of the irregular structure and unstable phenomenon, whi

4、ch exists in the abrupt change point of the signal, the point the location of the image contour is presented.These contours are often in image edge detection, we need some important characteristics of the condition, this needs us to the edge of an image detection and extract it.There are so many met

5、hod can be used in image edge detection and contour extraction, including common Robert edge operator, Prewitt edge operator, Sobel edge operator and so on.At first, this paper will, from the perspective of digital image processing and analysis of several kinds of edge detection algorithms in detail

6、, and then select one of the edge detection algorithm for experiments.After considering the further study, this paper implemented the algorithm will use openCV.Finally, this article will obtain the actual effect of the experiment, and compares the results of theoretical analysis, and then to summari

7、ze this experiment.Keywords: Edge detection Contour extraction Image processing openCV1 绪论数字图像处理技术的迅猛发展,其应用前景得到了不可限量的扩展,如今各行各业都在积极发展与图像相关的技术。其应用逐渐凸显其魅力,其应用如医学影像、航天航空、无人驾驶、自动导航、工业控制、导弹制导、文化艺术等。边缘检测在图像处理和计算机视觉等领域骑着重要的作用,是图像分析、模式识别、目标检测与分割等的前期处理。前期边缘检测的好坏,直接影响后期更高级处理的精度。自从1986年John Canny提出了最优边缘检测算子的三条准

8、则并推导出了一个近似实现。但是在实际中,真正实现这一目标尚有较大的难度。这是因为:(1)实际图像一般都含有噪声,并且噪声的分布信息业是未知的,同时噪声和边缘都属于高频信息,在进行滤波的同时,虽然能够在一定程度上抑制噪声,却也丢失了边缘信息。(2)由于场景、光照条件的边缘等原因,同一场景在不同光照条件下得到的边缘可能也是不同的,设置的阈值也可能是不同的。针对这些问题,如何进行改进,并得到较理想的边缘检测算子是有必要的。另一方面,轮廓提取技术是图像分割、目标区域识别区域行状提取等图像分析处理领域十分重要的基础。寻求非接触、精度高、具有综合分析能力的识别方法来代替人工目测,解决图像表面的模式识别和测

9、量问题,是图像加工行业面临的一大难题,也是值得我们长期探讨的科研课题。2 设计内容与OpenCV简介2.1 设计任务内容针对一幅图像,利用边缘检测算子(如Robert算子、Sobel算子、Prewitt算子、Laplace算子、Kirsch算子和Marr算子)检测出图像的边缘,然后采取轮廓提取算法得到封闭的二值图像轮廓。2.2 OpenCV简介OpenCV的全称是:Open Source Computer Vision Library,是一个基于开源发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效由一系列 C 函数和少量 C+ 类构成,同

10、时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。相对于matlab而言,OpenCV操作起来较为复杂,需要一定C+编程基础,对没有语言基础的初学者而言较为困难。但是OpenCV有很多不容忽视的优点:(1)具有更强大的数字图像处理能力;(2)具有良好的可移植性;(3)由于是一个C+的类库,因此在实际中运用更加广泛。考虑到上述因素,此次试验将选择OpenCV作为开发工具。3 理论分析3.1 边缘检测3.1.1 图像的边缘在数字图像中,边缘是指图像局部变化最显著的部分,边缘主要存在于目标与目标,目标与背景之间,是图像局部特性的不连续性,如灰度的

11、突变、纹理结构的图标、颜色的图标等。尽管图像的边缘点产生的原因各不相同,但他们都是图形上灰度不连续或灰度几句辩护的点,图像边缘分为阶跃状、斜坡状和屋顶状。从成因上看,一般图像边缘主要由四个方面的因素形成:(1)图像灰度在表面法向变化的不连续造成的边缘;(2)图像对像素在空间上不一致形成的边缘;(3)在光滑的表面上由于颜色的不一致形成的边缘;(4)物体的光影造成的边缘。图像边缘提取的作用有:(1)改良图像质量;(2)分离对象;(3)理解和重构视觉场景;(4)识别特征。3.1.2 边缘检测的基本步骤(1)滤波:边缘检测主要基于导数计算,会受到噪声的影响,可以通过设计滤波器来降低噪声,但滤波器在降低

12、噪声的同时也会导致边缘精度的损失。(2)增强:增强算法将邻域中灰度有显著变化的点突出显示。一般通过计算梯度幅值来完成。(3)检测:在有些图像中梯度幅值较大的并不是边缘点。最简单的边缘检测是梯度幅值阈值判定。(4)定位:精确确定边缘的位置。3.2 轮廓提取图像的轮廓作为图像的一种基本特征,经常被应用到较高层次的图像应用中去。它在图像识别,图像分割,图像增强以及图像压缩等的领域有广泛应用,也是图像处理的基础。图像的轮廓往往携带着一幅图像的大部分信息。而轮廓即在于图像的不规则结构和不稳定上,也存在于信号的突变点处,这些点给出了图像轮廓的位置,这些轮廓常常是我们在图像边缘检测时所需的非常重要的特征条件

13、,因而这就需要我们对一幅图像检测并提取出它的轮廓。经典的轮廓提取技术大都基于微分运算。首先通过平滑来滤除图像中的噪声,然后进行一阶微分或二阶微分运算,求得梯度最大值或二阶导数的过零点,最后选取适当的阈值来提取边界。本次课设所用的轮廓提取算法非常简单,就是掏空内部点:如果原图中有一点为黑,且它的8个相邻点都是黑色时(此时该点是内部点),则将该点删除。要注意的是,我们处理的虽然是二值图,但实际上是256级灰度图,不过只用到了0和255两种颜色。4 边缘检测的算法比较特征提取作为图像边缘检测的一个重要内容,发展了众多的方法。这些方法经过实践的检验,成为了经典的内容。经典的边缘检测算子包括:Rober

14、ts算子、Prewitt算子、Sobel算子、Log算子、Canny算子等,这些经典的边缘提取算子在使用时都是使用预定义的边缘模型去匹配。4.1 Reborts算子Reboerts算子是一种利用局部差分来寻找边缘的算子,Roberts 梯度算子所采用的是对角方向相邻两像素值之差,算子形式如下:Roberts梯度算子对应的卷积模版为: 用以上两个卷积算子与图像运算后,可求出图像的梯度幅值 G ( x,y),然后选择适当的阈值 ,若 G ( x,y),则 (i ,j)为边缘点,否则,判断 (i ,j)为非边缘点。由此得到一个二值图像 g (i,j),即边缘图像。Roberts 算子采用的是用对角线

15、方向上相邻两像素的差近似梯度幅值来检测边缘,它的定位精度高,对于水平和垂直方向的边缘,检测效果较好,而对于有一定倾角的斜边缘,检测效果则不理想,存在着许多的漏检。另外,在含噪声的情况下,Roberts 算子不能有效的抑制噪声,容易产生一些伪边缘。因此,该算子适合于对低噪声且具有陡峭边缘的图像提取边缘。4.2 Sobel算子Sobel算子在边缘检测算子扩大了其模版,在边缘检测的同时尽量削弱了噪声。其模版大小为33,其将方向差分运算与局部加权平均相结合来提取边缘。在求取图像梯度之前,先进行加权平均,然后进行未分,加强了对噪声的一致。Sobel算子所对应的卷积模版为: 图像中的每个像素点和以上水平和

16、垂直两个卷积算子做卷积运算后,再计算得到梯度幅值 G ( x,y),然后选取适当的阈值 ,若 G ( x,y),则 (i ,j)为边缘点,否则,判断 (i ,j)为非边缘点。由此得到一个二值图像 g (i,j),即边缘图像。Sobel 算子在空间上比较容易实现,不但产生较好的边缘检测效果,同时,由于其引入了局部平均,使其受噪声的影响也较小。若使用较大的邻域,抗噪性会更好,但也增加了计算量,并且得到的边缘比较粗。在对精度要求不是很高的场合下,Sobel 算子是一种较为常用的边缘检测算法。4.3 Prewitt 算子同 Sobel 算子相似,Prewitt 算子也是一种将方向的差分运算和局部平均相

17、结合的方法,也是取水平和垂直两个卷积核来分别对图像中各个像素点做卷积运算,所不同的是,Sobel 算子是先做加权平均然后再微分,Prewitt 算子是先平均后求微分,其对应的卷积模版为: (2.3.8)图像中的每个像素点和以上水平和垂直两个卷积算子做卷积运算后,再计算得到梯度幅值 G ( x,y),然后选取适当的阈值 ,若 G ( x,y),则 (i,j)为边缘点,否则,判断 (i,j)为非边缘点。由此得到一个二值图像 g (i,j),即边缘图像。在此基础上,有人提出了改进的Prewitt算子,将其扩展到八个方向,依次用这些边缘模板去检测图像,与被检测区域最为相似的样板给出最大值。用这个最大值

18、作为算子的输出值 P i ,j,这样就可将边缘像素检测出来。Prewitt 算子通过对图像上的每个像素点的八方向邻域的灰度加权差之和来进行检测边缘,对噪声有一定抑制作用,抗噪性较好,但由于采用了局部灰度平均,因此容易检测出伪边缘,并且边缘定位精度较低。4.4 Kirsch 算子Kirsch 算子是一种 33 的非线性方向算子。其基本思想是希望改进取平均值的过程,从而尽量使边缘两侧的像素各自与自己同类的像素取平均值,然后再求平均值之差,来减小由于取平均值所造成的边缘细节丢失。通常采用八方向 Kirsch 模板的方法进行检测,取其中最大的值作为边缘强度,而将与之对应的方向作为边缘方向。常用的八方向

19、 Kirsch 模板如下所示: 实际的应用中,通常都是利用简单的卷积核来计算方向差分的,不同的算子对应着不同的卷积核。它们在图像的像素点上所产生的两个方向的偏导数用均方值或者绝对值求和的形式来近似代替梯度幅值,然后选取一个合适的阈值,用所得到的梯度幅值和所设定的阈值进行比较来判断边缘点。若大于所取的阈值,则判断为边缘点;否则,判断为非边缘点。很显然,在提取边缘的过程中,阈值的选取特别重要,尤其在含噪图像中,阈值的选择要折衷考虑噪声造成的伪边缘和有效边缘的丢失。4.5 LOG算子LOG算子基本思想是:先在一定的范围内做平滑滤波,然后再利用差分算子来检测在相应尺度上的边缘。滤波器的选择要考虑以下两

20、个因素:其一是滤波器在空间上要求平稳,即要求空间位置误差 x要小;其二是平滑滤波器本身要求是带通滤波器,并且在有限的带通内是平稳的,即要求频域误差 要小。根据信号处理中的测不准原理, x 和 是相互矛盾的,而达到测不准下限的滤波器就是高斯滤波器。Marr 和 Hildreth 提出的这种差分算子是各向同性的拉普拉斯二阶差分算子。该边缘检测器的基本特征是:(1) 所用的平滑滤波器是高斯滤波器(2) 增强步骤采用的是二阶导数(即二维拉普拉斯函数)(3) 边缘检测的判据是二阶导数过零点并且对应一阶导数的极大值该方法的特点是先用高斯滤波器与图像进行卷积,既平滑了图像又降低了噪声,使孤立的噪声点和较小的

21、结构组织被滤除。然而由于对图像的平滑会导致边缘的延展,因此只考虑那些具有局部梯度极大值的点作为边缘点,这可以用二阶导数的零交叉来实现。拉普拉斯函数可用作二维二阶导数的近似,因为它是一种标量算子。为了避免检测出非显著的边缘,所以应该选择一阶导数大于某一阈值的零交叉点来作为边缘点。实际应用中,常用的LOG算子的模版为:这说明, 高斯平滑运算不但可以滤除噪声,还会导致图像中的边缘和其它尖锐不连续部分模糊,而模糊程度取决于空间尺度因子 的大小。 越大,高斯滤波对噪声的滤除效果越好,但同时也会丢失重要的边缘信息,影响到边缘检测器的性能。如果 较小,又可能导致平滑作用不完全而留有较多的噪声。因此在实际应用

22、中,要根据情况选择适当的。4.6 Canny算子1986年,Canny从边缘检测算子应该满足的三个准则出发,推导出了最优边缘检测算子Canny算子,该算子是目前理论上相对最完善的一种边缘检测算法。Canny提出的评价边缘检测性能优劣的三个准则分别是:(1)好的信噪比准则。即将非边缘点判为边缘点的概率要低,将边缘点判为非边缘点的概率要低;(2)好的定位性能准则。即检测出的边缘点要尽可能在实际边缘的中心;(3)单边缘响应准则。即单一边缘具有唯一响应,单一边缘产生的多个响应的概率要低,并且对虚假边缘的响应应得到最大抑制。利用Canny算子检测边缘的算法如下:(1)用式所示的高斯函数h(r)对图像进行

23、平滑滤波,去除图像中的噪声。(2)在每一点计算出局部梯度和边缘方向,可以利用Sobel算子、Roberts算子等来计算。边缘点定义为梯度方向上其强度局部最大的点。(3)对梯度进行“非极大值抑制”。(4)双阐值化和边缘连接。5 实验仿真5.1算法设计通过以上各种边缘检测算法之间的比较可知,Canny算子使用两个阈值检测强信号和弱信号边缘,如果它们被连接到边缘,那么输出只包含弱边缘。因此,此方法更适合用于检测真实得弱边缘,本次实验决定采用Canny算子,算法具体步骤如下:(1)求图像与高斯平滑滤波器卷积:(2)使用一阶有限差分计算偏导数的两个阵列P与Q:(3)幅值和方位角:(4)非极大值抑制(NM

24、S ) :细化幅值图像中的屋脊带,即只保留幅值局部变化最大的点。将梯度角的变化范围减小到圆周的四个扇区之一,方向角和幅值分别为:非极大值抑制通过抑制梯度线上所有非屋脊峰值的幅值来细化Mi,j,中的梯度幅值屋脊这一算法首先将梯度角i,j的变化范围减小到圆周的四个扇区之一,如图5-1所示: 图5-1 圆周四个扇脚5.2 实验结果通过算法的设计,得到的图像如图5-2、图5-3和图5-4所示。其中图5-2为原图,图5-3为边缘检测后得到的图像,图5-4为对图5-3进行轮廓提取所得的图像。 图5-2 原图像 图5-3 边缘检测 图5-4 轮廓提取6 分析与总结由实验结果可知,Canny算子采用高斯函数对

25、图像作平滑处理,因此具有较强的抑制噪声能力,同样该算子也会将一些高频边缘平滑掉,造成边缘丢失。Canny算子也存在不足之处,一是为了得到较好的边缘检测结果,它通常需要使用较大的滤波尺度,这样容易丢失一些细节;二是Canny算子的双阈值要人为的选取,不能够自适应。通过此次课设让我对OpenCV有了一定的理解,尽管许多内部函数还不知道,程序设计也只是一知半解,但对以后的学习有了较好的指引。不仅在知识学习上有较多的收获,在学习态度和方法上也起到了端正和提高作用,为了寻求知识的那份执著。这次课程设计给我们提供了一个应用自己所学知识的机会,从到图书馆查找资料到对程序的设计和仿真,都对我们所学的知识进行了

26、检验。让我明白了设计系统程序的一些基本思想 。总体来说,这次课程设计让我受益匪浅。在摸索该如何设计程序使之实现所需功能的过程中,虽然很困难,但也很有趣,培养了我的设计思维,锻炼了操作能力。在让我体会到了设计的艰辛的同时,更让我体会到成功的喜悦和快乐。参考文献1 Canny. A Computational Approach to Edge Detection, IEEE Trans. on Pattern Analysis and Machine Intelligence, 8(6), pp. 679-698 (1986).2 刘泉编.通信电子线路.武汉理工出版社.2007年3 樊昌信等编.通

27、信原理.国防工业出版社.2007年4 数字信号处理.科学出版社.2007年5 于仕琪等编.OpenCV教程(基础篇).2006年 附录关键代码如下:void Canny( InputArray _src, OutputArray _dst, double low_thresh, double high_thresh, int aperture_size, bool L2gradient ) Mat src = _src.getMat(); CV_Assert( src.depth() = CV_8U ); _dst.create(src.size(), CV_8U); Mat dst = _d

28、st.getMat(); if (!L2gradient & (aperture_size & CV_CANNY_L2_GRADIENT) = CV_CANNY_L2_GRADIENT) /backward compatibility if (aperture_size & 1) = 0 | (aperture_size != -1 & (aperture_size 7) CV_Error(CV_StsBadFlag, ); const int cn = src.channels(); cv:Mat dx(src.rows, src.cols, CV_16SC(cn); cv:Mat dy(s

29、rc.rows, src.cols, CV_16SC(cn); cv:Sobel(src, dx, CV_16S, 1, 0, aperture_size, 1, 0, cv:BORDER_REPLICATE); cv:Sobel(src, dy, CV_16S, 0, 1, aperture_size, 1, 0, cv:BORDER_REPLICATE); if (low_thresh high_thresh) std:swap(low_thresh, high_thresh); if (L2gradient) low_thresh = std:min(32767.0, low_thres

30、h); high_thresh = std:min(32767.0, high_thresh); if (low_thresh 0) low_thresh *= low_thresh; if (high_thresh 0) high_thresh *= high_thresh; int low = cvFloor(low_thresh); int high = cvFloor(high_thresh); int* mag_buf3; mag_buf0 = (int*)(uchar*)buffer; mag_buf1 = mag_buf0 + mapstep*cn; mag_buf2 = mag

31、_buf1 + mapstep*cn; memset(mag_buf0, 0, /* cn* */mapstep*sizeof(int); uchar* map = (uchar*)(mag_buf2 + mapstep*cn); memset(map, 1, mapstep); memset(map + mapstep*(src.rows + 1), 1, mapstep); int maxsize = std:max(1 10, src.cols * src.rows / 10); std:vector stack(maxsize); uchar *stack_top = &stack0; uchar *stack_bottom = &stack0; #define CANNY_PUSH(d) *(d) = uchar(2), *stack_top+ = (d) #define CANNY_POP(d) (d) = *-stack_top / calculate magnitude an

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1