实验二 OpenCv实现Canny边缘检测、实验目的1、了解如何在VC++6.0上安装与配置opencv2、了解canny边缘检测的原理与 opencv的实现二、 实验引言边缘是一幅图像最重要的特征之一, 图像边缘部分集中了图像的大部分信息 因此,边缘的确定对于图像场景的识别与理解非常重要; 同时在图像分割中也有重要应用 可以利用边缘对图像进行区域分析边缘在图像体现为局部区域亮度的显著变化, 可见这种变化是为灰度面的阶跃有很多种方法可以用来对图像边缘进行检测本实验中采用 Canny边缘检测三、 实验原理检测阶跃边缘的基本思想是在图像中找出具有局部最大梯度值的像素点, 其大部分的工作集中在寻找能够用于实际图像的梯度数字逼近图像梯度逼近必须满足要求:1、 逼近必须能够抑制噪声效应2、 必须尽量精确的确定边缘的位置Canny检测的基本过程高斯平滑滤波平滑图像▼平滑与计算Canny边缘检测器就是高斯函数的一阶导数,是对信噪比与定位之间最优化的逼近算 子高斯平滑和梯度逼近结合的算子不是旋转对称的 高斯平滑和梯度逼近结合的算子不是旋转对称的在边缘方向是对称的 ,在垂直边缘方向是反对称的(梯度方向)。
该算子在对最急剧变化方向上的边缘很敏感,沿边缘方向不敏感非极大值抑制前面的计算得到梯度的幅度图像阵列为 M[i,j] ,此值的值越大,其对应的图像梯度值 也越大但还不能精确的确定边缘 为了确定边缘, 必须细化幅度值图像中的屋脊带 (ridge ), 即只保 留幅度值局部变化最大的点此过程称为非极 大值 抑制 ( non-maxima suppression,NMS ),其结果会产生细化的边缘非极大值抑制 通过抑制梯度线上所有的非 屋脊峰值的幅度值 来细化M[i,j]中的梯度幅值屋脊算法使用一个3X 3邻域作用在幅值阵列M [i, j]的所有点上;每一个点上,邻域的中心像素M [i, j]与沿着梯度线的两个元素进行 比较,其中梯度线是由邻域的中心点处的扇区值 Z [i,j ]给出如果在邻域中心点处的幅值M[i, j]不比梯度线方向上的两个相邻点幅值大, 则M[i,j]赋值为零,否则维持原值;此过程可以把 M[i,j] 宽屋脊带细化成只有一个像素点宽,即保留屋脊的高度值非极大值抑制公式为:N[i,j]= NMS(M[i, j],z[i,j])N[i, j]中的非零值对应着图像强度阶跃变化处对比度,其坐标对应着图像梯度值经过 非极大值抑制后细化得到的边缘。
虽然在边缘检测前经过了图像的高斯平滑, 但是经过NMS^仍然会 包含许多噪声和细纹理引起的假边缘段 所以要经过阈值化处理阈值化去除假边缘的方法是对 N[i,j]使用阈值处理,将低于某一阈值的所有值赋值零, 得到图像边缘阵列 I[i, j]单阈值t太低造成的假阳性以及阴影会使边缘对比度减弱; 单阈值t太高造成的假阴性会使部分轮廓丢失; 常用双阈值11和12 = 2t 1对非极大值抑制图像 N[i, j]处理得到两个边缘图像Ti[i, j]和T2[i, j] T2[i, j]用高阈值得到,所以含有较少的假边缘,但其中有轮廓的间断双阈值要在 T2[i, j]中把边缘连接成轮廓,当到达轮廓端点时,就在 T,[i,j]的8邻点位置寻找可以连接到轮廓上的边缘综述整个算法的主要步骤是: 不断的在T1[i,j]中收集边缘,直到T2【i,j]中的所有间隙连接起来位置从而得出 Canny 算法的具体实现步骤:Step1 : 用高斯滤波器平滑图像, 去除图像噪声 一般选择方差为 1.4 的高斯函数模板和 图像进行卷积运算Step2:用一阶偏导的有限差分来计算梯度的幅值和方向使用 的梯度算子计算 x和y方向的偏导数 和 ,方向角 ,梯度幅值 。
Step3 :对梯度幅值应用非极大值抑制 幅值M越大,其对应的图像梯度值也越大, 但这为确还不足以确定边缘,因为这里仅把图像快速变化的问题转化成求幅值局部最大值问题,定边缘,必须细化幅值图像中的屋脊带,只保留幅值局部变化最大的点,生成细化的边缘Step4:用双阈值算法检测并且连接边缘 双阈值法使Canny算子提取的边缘点更具有鲁棒性,高低阈值分别表示为 Hth和Lth,对于高阈值Hth的选折,基于计算出的图像梯度值对应的直方图进行选取三.实验过程1、 按手册正确安装 VC++6.0和opencvl.0并对VC++6.0添加一系列库文件完成配置2、 在VC++6.0上添加工程,根据算法编写程序并执行3、 运行并观察结果四.程序流程图五、实验结果下面是第一阈值为 1,不同第二阈值下阈值下检测出来的图像(第二阈值递增) 可见阈值越大原图像中变化越不太显的部分渐渐消失, 当阈值最大时剩下的就是图像中亮暗变化最明显的部分192 六、参考文献与资料贾云得,机器视觉,科学出版社, 2000中国Opencv官网: 浏览时间:2011 年 5 月 29 日七、附录 代码:Ipragu package linclude ^cv.h" ■include "higliqiii.tr char wndnane[]「枪J]惦图像冷 char tbarnane[]= “询值"; int edge thresh = 1;Ipllnage *inage, *cedge> *grapf *edge;void on trackbarfint i){ cvSmothCgrajf Pedge .CV.BLUR J J10.1); "CUBLUR:对每个象素 3X3帶域求和并做尺度变换 1/(3-3).cvCannylgrap.edge,(float)edge_thieshf(float)edge thresh*313) ; // 做canny^fji]cedge ); "图働|零cuGopp( inage, cedge, edge ); "从inag呻复制Mge部分到cMgpMfw和财gw(帅dna昵,cedge); "显示医片int nain(){"涙图芥判断iiage = cuLoadlwgeC'G: WLugetl .BHP11);if (tillage){return -1;}//建立图像空间cedge ■ cuCreateInage(cuSize(inage->width,inage->height), IPL DEPTH 8U, 3);gray = cuCreatelnagetcuSizetinage-^widthjFiage^height), IPLJEPTH^U, 1);pdge = cuCrpatPlnidg&(cvSize(image->u)idthlinage->h?ight),【PL_DEPTH_8U| 1);CuCutColor(inage( gray, CMGR2GRAV); //inege色彩空|'a]^RC0j|gray转梅给qwy cvNampdMindowtwndndFie, 1); // 创建奇口cuNanedUindowC1^图像”,2); _cvShowlnageC'^gf", inagp);//fi示原图像oitrackbar(fl); // j cuUaitKey(O);〃释腿醐毁窗口cvCreateTrackbar(tbarnam f NndnaK, ftedge_thresh, 3呱 on_trackbar); // 仓腱滑块栏cvReleaseluge(ftiRage); cvDestroyttindowfiindnaH); | cuDestroyUindaw("^ 图像“);return 0;。