图象边缘检测中边闭合性分析与探讨.doc_第1页
图象边缘检测中边闭合性分析与探讨.doc_第2页
图象边缘检测中边闭合性分析与探讨.doc_第3页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

个人资料整理 仅限学习使用图象边缘检测中边界闭合性的分析与探讨摘 要 在图象边缘检测中往往要求所检测到的边缘具有封闭特性,本文详细地分析了目前常用的两种算法:哈夫变换和Canny边缘检测算法,最后,探讨边缘算子应满足的准则。关键词 边缘检测;闭合性;哈夫变换;Canny算子1引言 图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值。图象的边缘部分集中了图象的大部分信息,图象边缘的确定与提取对于整个图象场景的识别与理解是非常重要的,同时也是图象分割所依赖的重要特征,边缘检测主要是图象的灰度变化的度量、检测和定位,自从1959提出边缘检测以来,经过五十多年的发展,已有许多中不同的边缘检测方法。在我们常用的几种用于边缘检测的算子中Laplace算子常常会产生双边界;而其他一些算子如Sobel算子又往往会形成不闭合区域。本文主要讨论了在边缘检测中,获取封闭边界区域的算法。2 图象边缘检测的基本步骤 1)滤波。边缘检测主要基于导数计算,但受噪声影响。但滤波器在降低噪声的同时也导致边缘强度的损失。 2)增强。增强算法将邻域中灰度有显著变化的点突出显示。一般通过计算梯度幅值完成。 3)检测。但在有些图象中梯度幅值较大的并不是边缘点。最简单的边缘检测是梯度幅值阈值判定。 在象素(x,y的领域且它们的梯度幅度与梯度方向在给定的阈值下满足:T是幅度阈值;A是角度阈值; 那么,如对所有的边缘象素都进行上述的判断和连接就可以得到一个闭合的边界。哈夫变换方法是利用图像得全局特性而对目标轮廓进行直接检测的方法,在已知区域形状的条件下,哈夫变换可以准确地捕获到目标的边界。通过变换将图象从图像控件转换到参数空间,在图像空间中一条过点(x,y的直线方程为y=px+q,通过代数变换可以转换为另一种形式p=-px+y,即参数空间中过点(p,q的一条直线,如果在图像空间中保持直线的斜率和截距的不变,其在参数空间必定过点(p,q,这也就说明,在图像空间中共线的点对应参数空间共点的线. 哈夫变换就是根据上述点线的对偶性把在图象空间中存在的直线检测问题转换为参数空间中存在的点检测问题,后者的处理要比前者简单易行得多,只需简单地累加统计即可实现对边缘的检测.哈夫变换不仅能检测直线等一阶曲线的目标,对于园、椭圆等高阶的曲线都可以检测出来。如圆的方程为: 其参数空间是一个3D空间A(a,b,r,原理与检测直线上的点相同,只是复杂性增加了。如果圆的半径r己知,则问题又回到了2D空间A(a,b 哈夫变换对已知目标的检测过程受随机噪声和曲线中断等不利因素的影响很小,而且分割出的目标是直接放到另一个“干净”的缓存中的,因此可以做到零噪声,是相当有优势的。常规的哈夫变换在理论上能对所有可以写出具体解读表达式的曲线进行目标检测,但是在实际处理时,经常待检测的目标不规则或是很难获取甚至根本没有解读式,此时就要采取广义上的哈夫变换来检测目标,32最优的阶梯型边缘检测算法(canny边缘检测 1.Canny边缘检测基本原理 (1图象边缘检测必须满足两个条件:一能有效地抑制噪声;二必须尽量精确确定边缘的位置。 (2根据对信噪比与定位乘积进行测度,得到最优化逼近算子。这就是Canny边缘检测算子。 (3类似与MarrLoG)边缘检测方法,也属于先平滑后求导数的方法。 2.Canny边缘检测算法: step1:用高斯滤波器平滑图象; step2:用一阶偏导的有限差分来计算梯度的幅值和方向; step3:对梯度幅值进行非极大值抑制; step4:用双阈值算法检测和连接边缘。 step1:高斯平滑函数 step3:非极大值抑制 仅仅得到全局的梯度并不足以确定边缘,因此为确定边缘,必须保留局部梯度最大的点,而抑制非极大值。双阈值法要在N2i,j中把边缘连接成轮廓,当到达轮廓的端点时,该算法就在N1i,j的8邻点位置寻找可以连接到轮廓上的边缘,这样,算法不断地在N1i,j中收集边缘,直到将N2i,j连接起来为止。4 边缘算子应满足的准则 若满足此准则,就能保证单边缘只有一个响应。对一个算法的性能评价可分为两个阶段进行:计算假边缘与丢失边缘的数目;测量用于估计位置和方向的误差(或误差分布。边缘检测算法的优劣也可用品质因数(Figure of Merit来描述。Pratt品质因数是其中一种,它着重考虑了丢失了有效的边缘、边缘定位误差和将噪声判断为边缘等三种误差。5 结束语 边缘检测在图象分割、机器视觉等中都有重要作用,人们已研究出很多种边缘检测算法,而哈夫变换和canny边缘算子等是最经典的算法,人们已在这些经典算法基础上提出一些新的改进算法。参考文献1贾云德机器视觉北京:科学出版社,20002章毓晋图象处理和分析北京:清华大学出版社,19993郎锐数字图象处理学北京:希望电子出版社,20024王娜,李霞一种新的改进Canny边缘检测算法深圳大学学报,2005,4中,边缘提取就是前提步骤。这里我们只考虑灰度图像,用于图像识别的边缘提取比起仅仅用于视觉效果增强的边缘提取要复杂一些。要给图像的边缘下一个定义还挺困难的,从人的直观感受来说,边缘对应于物体的边界。图像上灰度变化剧烈的区域比较符合这个要求,我们一般会以这个特征来提取图像的边缘。但在遇到包含纹理的图像上,这有点问题,比如说,图像中的人穿了黑白格子的衣服,我们往往不希望提取出来的边缘包括衣服上的方格。但这个比较困难,涉及到纹理图像的处理等方法。好了,既然边缘提取是要保留图像的灰度变化剧烈的区域,从数学上,最直观的方法就是微分(对于数字图像来说就是差分,在信号处理的角度来看,也可以说是用高通滤波器,即保留高频信号。这是最关键的一步,在此之前有时需要对输入图像进行消除噪声的处理。用于图像识别的边缘提取往往需要输出的边缘是二值图像,即只有黑白两个灰度的图像,其中一个灰度代表边缘,另一个代表背景。此外,还需要把边缘细化成只有一个像素的宽度。总的说来边缘提取的步骤如下:1,去噪声2,微分运算3,2值化处理4,细化第二步是关键,有不少书把第二步就直接称为边缘提取。实现它的算法也有很多,一般的图像处理教科书上都会介绍好几种,如拉普拉兹算子,索贝尔算子,罗伯特算子等等。这些都是模板运算,首先定义一个模板,模板的大小以3*3的较常见,也有2*2,5*5或更大尺寸的。运算时,把模板中心对应到图像的每一个像素位置,然后按照模板对应的公式对中心像素和它周围的像素进行数学运算,算出的结果作为输出图像对应像素点的值。需要说明的是,模板运算是图像的一种处理手段-邻域处理,有许多图像增强效果都可以采用模板运算实现,如平滑效果,中值滤波(一种消除噪声的方法,油画效果,图像的凹凸效果等等。这些算法都比较简单,为人们常用。关于前面提到的几种边缘提取算子(拉普拉兹算子,索贝尔算子,罗伯特算子,教科书上都有较为详细的介绍,我这里不多说了,(手头上没有教科书,也懒得翻译英文资料,如果你们有时间,可以把这些方法的具体情况仔细介绍一下。这里对拉普拉兹算子和索贝尔算子补充两句。拉普拉兹算子是2阶微分算子,也就是说,相当于求取2次微分,它的精度还算比较高,但对噪声过于敏感(有噪声的情况下效果很差是它的重大缺点,所以这种算子并不是特别常用。索贝尔算子是最常用的算子之一(它是一种一阶算子,方法简单效果也不错,但提取出的边缘比较粗,要进行细化处理。另外,索贝尔算子也可提取出图像边缘的方向信息来,有文章论证过,在不考虑噪声的情况下,它取得的边缘信息误差不超过7度。顺便说一句,往往我们在进行边缘提取时只注意到位置信息,而忽略了边缘的方向。事实上,图像的边缘总有一定的走向,我们可以用边缘曲线的法线方向(和切线垂直的直线来代表边缘点的方向。在图像识别的应用中,这个方向是非常重要的信息。上面的几种算子是属于比较简单的方法,边缘提取的精度都不算特别高,下面介绍几种高级算法。首先是马尔(Marr算子,马尔是计算机视觉这门学问的奠基人,很了不起,但这些理论很难懂。他提出的边缘提取方法可以看成两个步骤,一个是平滑作用来消除噪声,另一个是微分提取边缘,也可以说是由两个滤波器组成,低通滤波去除噪声,高通滤波提取边缘。人们也称这种方法为LOG滤波器,这也是根据它数学表达式和滤波器形状起的名字。也可以采用模板运算来实现这种算法,但模板的大小一般要在7*7以上,所以运算复杂程度比索贝尔算子等要大不少,运算时间当然也长许多。另外一种非常重要的算法是坎尼(Canny算子,这是坎尼在1986年写的一篇论文里仔细论述的。他给出了判断边缘提取方法性能的指标。而坎尼算子也是图像处理领域里的标准方法,也可以说是默认的方法。比较奇怪的是,国内的图像处理教科书中,介绍坎尼算子的很少。本人见过的书中,郑南宁的计算机视觉与模式识别(1998年,算是介绍的比较详细的。坎尼算子在使用时要提供给一些参数,用于控制算法的性能,实际上,对于不同的图像或不同的边缘提取目的,应该提供不同的参数,以达到最佳效果。它也有模板运算方法,模板的大小也比较大,和提供的参数有关,标准的大小差不多是17*17,可以根据算子的可分离性用快速算法(否则就会慢的一塌糊涂,坎尼算子的2值化也很有特色,具有一定的智能性。还有一种算法:Shen-Castan算子,大概可称为沈峻算子,总之是中国人的成果,效果和坎尼算子不相上下,这种算法在对边缘提取好坏的判别标准上有些不同。(这种方法我没用过,好象编起程序来,要比坎尼算子还复杂在实际的图像处理与识别应用中,有时需要根据被处理图像的种类以及实际目的,量身定做算法,边缘提取也是一样,但是基本原理都是一样的。canny算子代码void CreatGauss(double sigma, double *pdKernel, int *pnWidowSize。void GaussianSmooth(SIZE sz, LPBYTE pGray, LPBYTE pResult, double sigma。void Grad(SIZE sz, LPBYTE pGray, int *pGradX, int *pGradY, int *pMag。void NonmaxSuppress(int *pMag, int *pGradX, int *pGradY, SIZE sz, LPBYTE pNSRst。void EstimateThreshold(int *pMag, SIZE sz, int *pThrHigh, int *pThrLow, LPBYTE pGray, double dRatHigh, double dRatLow。void Hysteresis(int *pMag, SIZE sz, double dRatLow, double dRatHigh, LPBYTE pResult。void TraceEdge(int y, int x, int nThrLow, LPBYTE pResult, int *pMag, SIZE sz。void Canny(LPBYTE pGray, SIZE sz, double sigma, double dRatLow, double dRatHigh, LPBYTE pResult。#include afx.h#include math.h#include canny.h/ 一维高斯分布函数,用于平滑函数中生成的高斯滤波系数void CreatGauss(double sigma, double *pdKernel, int *pnWidowSize LONG i。 /数组中心点 int nCenter。 /数组中一点到中心点距离 double dDis。 /中间变量 double dValue。 double dSum。 dSum = 0。 / -3*sigma,3*sigma 以内数据,会覆盖绝大部分滤波系数 *pnWidowSize = 1+ 2*ceil(3*sigma。 nCenter = (*pnWidowSize/2。 *pdKernel = new double*pnWidowSize。 /生成高斯数据 for(i=0。i。i+ dDis = double(i - nCenter。 dValue = exp(-(1/2*dDis*dDis/(sigma*sigma/(sqrt(2*3.1415926*sigma。 (*pdKerneli = dValue。 dSum+=dValue。 /归一化 for(i=0。i。i+ (*pdKerneli/=dSum。 /用高斯滤波器平滑原图像void GaussianSmooth(SIZE sz, LPBYTE pGray, LPBYTE pResult, double sigma LONG x, y。 LONG i。 /高斯滤波器长度 int nWindowSize。 /窗口长度 int nLen。 /一维高斯滤波器 double *pdKernel。 /高斯系数与图像数据的点乘 double dDotMul。 /滤波系数总和 double dWeightSum。 double *pdTemp。 pdTemp = new doublesz.cx*sz.cy。 /产生一维高斯数据 CreatGauss(sigma, &pdKernel, &nWindowSize。 nLen = nWindowSize/2。 /x方向滤波 for(y=0。y for(x=0。x dDotMul = 0。 dWeightSum = 0。 for(i=(-nLen。i /判断是否在图像内部 if(i+x=0 & (i+x dDotMul+=(doublepGrayy*sz.cx+(i+x * pdKernelnLen+i。 dWeightSum += pdKernelnLen+i。 pdTempy*sz.cx+x = dDotMul/dWeightSum。 /y方向滤波 for(x=0。 x for(y=0。 y dDotMul = 0。 dWeightSum = 0。 for(i=(-nLen。i if(i+y=0 & (i+y dDotMul += (doublepdTemp(y+i*sz.cx+x*pdKernelnLen+i。 dWeightSum += pdKernelnLen+i。 pResulty*sz.cx+x = (unsigned chardDotMul/dWeightSum。 delete pdKernel。 pdKernel = NULL。 delete pdTemp。 pdTemp = NULL。/ 方向导数,求梯度void Grad(SIZE sz, LPBYTE pGray,int *pGradX, int *pGradY, int *pMag LONG y,x。 /x方向的方向导数 for(y=1。y for(x=1。x pGradXy*sz.cx +x = (int( pGrayy*sz.cx+x+1-pGrayy*sz.cx+ x-1 。 /y方向方向导数 for(x=1。x for(y=1。y pGradYy*sz.cx +x = (int(pGray(y+1*sz.cx +x - pGray(y-1*sz.cx +x。 /求梯度 /中间变量 double dSqt1。 double dSqt2。 for(y=0。 y for(x=0。 x /二阶范数求梯度 dSqt1 = pGradXy*sz.cx + x*pGradXy*sz.cx + x。 dSqt2 = pGradYy*sz.cx + x*pGradYy*sz.cx + x。 pMagy*sz.cx+x = (int(sqrt(dSqt1+dSqt2+0.5。 /非最大抑制void NonmaxSuppress(int *pMag, int *pGradX, int *pGradY, SIZE sz, LPBYTE pNSRst LONG y,x。 int nPos。 /梯度分量 int gx。 int gy。 /中间变量 int g1,g2,g3,g4。 double weight。 double dTmp,dTmp1,dTmp2。 /设置图像边缘为不可能的分界点 for(x=0。x pNSRstx = 0。 pNSRst(sz.cy-1*sz.cx+x = 0。 for(y=0。y pNSRsty*sz.cx = 0。 pNSRsty*sz.cx + sz.cx-1 = 0。 for(y=1。y for(x=1。x /当前点 nPos = y*sz.cx + x。 /如果当前像素梯度幅度为0,则不是边界点 if(pMagnPos = 0 pNSRstnPos = 0。 else /当前点的梯度幅度 dTmp = pMagnPos。 /x,y方向导数 gx = pGradXnPos。 gy = pGradYnPos。 /如果方向导数y分量比x分量大,说明导数方向趋向于y分量 if(abs(gy abs(gx /计算插值比例 weight = fabs(gx/fabs(gy。 g2 = pMagnPos-sz.cx。 g4 = pMagnPos+sz.cx。 /如果x,y两个方向导数的符号相同 /C 为当前像素,与g1-g4 的位置关系为: /g1 g2 / C / g4 g3 if(gx*gy0 g1 = pMagnPos-sz.cx-1。 g3 = pMagnPos+sz.cx+1。 /如果x,y两个方向的方向导数方向相反 /C是当前像素,与g1-g4的关系为: / g2 g1 / C / g3 g4 else g1 = pMagnPos-sz.cx+1。 g3 = pMagnPos+sz.cx-1。 /如果方向导数x分量比y分量大,说明导数的方向趋向于x分量 else /插值比例 weight = fabs(gy/fabs(gx。 g2 = pMagnPos+1。 g4 = pMagnPos-1。 /如果x,y两个方向的方向导数符号相同 /当前像素C与 g1-g4的关系为 / g3 / g4 C g2 / g1 if(gx * gy 0 g1 = pMagnPos+sz.cx+1。 g3 = pMagnPos-sz.cx-1。 /如果x,y两个方向导数的方向相反 / C与g1-g4的关系为 / g1 / g4 C g2 / g3 else g1 = pMagnPos-sz.cx+1。 g3 = pMagnPos+sz.cx-1。 /利用 g1-g4 对梯度进行插值 dTmp1 = weight*g1 + (1-weight*g2。 dTmp2 = weight*g3 + (1-weight*g4。 /当前像素的梯度是局部的最大值 /该点可能是边界点 if(dTmp=dTmp1 & dTmp=dTmp2 pNSRstnPos = 128。 else /不可能是边界点 pNSRstnPos = 0。 / 统计pMag的直方图,判定阈值void EstimateThreshold(int *pMag, SIZE sz, int *pThrHigh, int *pThrLow, LPBYTE pGray, double dRatHigh, double dRatLow LONG y,x,k。 /该数组的大小和梯度值的范围有关,如果采用本程序的算法 /那么梯度的范围不会超过pow(2,10 int nHist256。 /可能边界数 int nEdgeNum。 /最大梯度数 int nMaxMag。 int nHighCount。 nMaxMag = 0。 /初始化 for(k=0。k nHistk = 0。 /统计直方图,利用直方图计算阈值 for(y=0。y for(x=0。x if(pGrayy*sz.cx+x=128 nHistpMagy*sz.cx+x+。 nEdgeNum = nHist0。 nMaxMag = 0。 /统计经过“非最大值抑制”后有多少像素 for(k=1。k if(nHistk != 0 nMaxMag = k。 /梯度为0的点是不可能为边界点的 /经过non-maximum suppression后有多少像素 nEdgeNum += nHistk。 /梯度比高阈值*pThrHigh 小的像素点总书目 nHighCount = (int(dRatHigh * nEdgeNum + 0.5。 k=1。 nEdgeNum = nHist1。 /计算高阈值 while(k & (nEdgeNum k+。 nEdgeNum += nHistk。 *pThrHigh = k。 /低阈值 *pThrLow = (int(*pThrHigh * dRatLow + 0.5。/利用函数寻找边界起点void Hysteresis(int *pMag, SIZE sz, double dRatLow, double dRatHigh, LPBYTE pResult LONG y,x。 int nThrHigh,nThrLow。 int nPos。 /估计TraceEdge 函数需要的低阈值,以及Hysteresis函数使用的高阈值 EstimateThreshold(pMag, sz,&nThrHigh,&nThrLow,pResult,dRatHigh,dRatLow。 /寻找大于dThrHigh的点,这些点用来当作边界点, /然后用TraceEdge函数跟踪该点对应的边界 for(y=0。y for(x=0。x nPos = y*sz.cx + x。 /如果该像素是可能的边界点,并且梯度大于高阈值, /该像素作为一个边界的起点 if(pResultnPos=128 & (pMagnPos = nThrHigh /设置该点为边界点 pResultnPos = 255。 TraceEdge(y,x,nThrLow,pResult,pMag,sz。 /其他点已经不可能为边界点 for(y=0。y for(x=0。x nPos = y*sz.cx + x。 if(pResultnPos != 255 pResultnPos = 0。 /根据Hysteresis 执行的结果,从一个像素点开始搜索,搜索以该像素点为边界起点的一条边界的/一条边界的所有边界点,函数采用了递归算法/ 从坐标出发,进行边界点的跟踪,跟踪只考虑pResult中没有处理并且可能是边界/ 点的像素 /对8邻域像素进行查询 int xNum8 = 1,1,0,-1,-1,-1,0,1。 int yNum8 = 0,1,1,1,0,-1,-1,-1。 LONG yy,xx,k。 for(k=0。k yy = y+yNumk。 xx = x+xNumk。 if(pResultyy*sz.cx+xx=128 & pMagyy*sz.cx+xx=nThrLow /该点设为边界点 pResultyy*sz.cx+xx = 255。 /以该点为中心再进行跟踪 TraceEdge(yy,xx,nThrLow,pResult,pMag,sz。 / Canny算子void Canny(LPBYTE pGray, SIZE sz, double sigma, double dRatLow, double dRatHigh, LPBYTE pResult /经过高斯滤波后的图像 LPBYTE pGaussSmooth。 pGaussSmooth = new unsigned charsz.cx*sz.cy。 /x方向导数的指针 int *pGradX。 pGradX = new intsz.cx*sz.cy。 /y方向 int *pGradY。 pGradY = new intsz.cx*sz.cy。 /梯度的幅度 int *pGradMag。 pGradMag = new intsz.cx*sz.cy。 /对原图高斯滤波 GaussianSmooth(sz,pGray,pGaussSmooth,sigma。 /计算方向导数和梯度的幅度 Grad(sz,pGaussSmooth,pGradX,pGradY,pGradMag。 /应用非最大抑制 NonmaxSuppress(pGradMag,pGradX,pGradY,sz,pResult。 /应用Hysteresis,找到所有边界 Hysteresis(pGradMag,sz,dRatLow,dRatHigh,pResult。 delete pGradX。 pGradX = NULL。 delete pGradY。 pGradY = NULL。 delete pGradMag。 pGradMag = NULL。 delete pGaussSmooth。 pGaussSmooth = NULL。 /*void CChildWnd:OnCanny( if (! m_fOpenFile return。 m_fDone = TRUE。 RGBToGray(szImg, aRGB, aGray, BPP。 Canny(aGray,szImg,0.1,0.9,0.76,aBinImg。 ShowGrayImage(l,szImg,aBinImg。/*/所谓边缘就是指图像局部亮度变化最显著的部分,它是检测图像局部变化显著变化的最基本的运算。对于数字图像,图像灰度灰度值的显著变化可以用梯度来表示,以边缘检测Sobel算子为例来讲述数字图像处理中边缘检测的实现: 对于数字图像,可以用一阶差分代替一阶微分;xf(x,y=f(x,y-f(x-1,y。yf(x,y=f(x,y-f(x,y-1求梯度时对于平方和运算及开方运算,可以用两个分量的绝对值之和表示,即:Gf(x,y=xf(x,y +yf(x,y |xf(x,y|+|yf(x,y|。Sobel梯度算子是先做成加权平均,再微分,然后求梯度,即:xf(x,y= f(x-1,y+1 + 2f(x,y+1 + f(x+1,y+1- f(x-1,y-1 - 2f(x,y-1 - f(x+1,y-1。yf(x,y= f(x-1,y-1 + 2f(x-1,y + f(x-1,y+1- f(x+1,y-1 - 2f(x+1,y - f(x+1,y+1。Gf(x,y=|xf(x,y|+|yf(x,y|。上述各式中的像素之间的关系见图f(x-1,y-1f(x,y-1f(x+1,y-1f(x-1,yf(x,yf(x+1,yf(x-1,y+1f(x,y+1f(x+1,y+1我在视图类中定义了响应菜单命令的边缘检测Sobel算子实现灰度图像边缘检测的函数:void CDibView:OnMENUSobel( /灰度图像数据的获得参见天极网9.10日发表的拙作/VC数字图像处理一文HANDLE data1handle。LPBITMAPINFOHEADER lpBi。CDibDoc *pDoc=GetDocument(。HDIB hdib。unsigned char *hData。unsigned char *data。hdib=pDoc-m_hDIB。BeginWaitCursor(。lpBi=(LPBITMAPINFOHEADERGlobalLock(HGLOBALhdib。hData= lpbi +* (LPDWORDlpbi + 256*sizeof(RGBQUAD。/得到指向位图像素值的指针pDoc-SetModifiedFlag(TRUE。/设修改标志为TRUEdata1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi-biWidth*8*lpBi-biHeight。/申请存放处理后的像素值的缓冲区data=(unsigned char*GlobalLock(HGLOBALdata1handle。AfxGetApp(-BeginWaitCursor(。int i,j,buf,buf1,buf2。for( j=0。 jbiHeight。 j+/以下循环求(x,y位置的灰度值for( i=0。 ibiWidth。 i+ if(i-1=0&(i+1biWidth&(j-1=0&(j+1biHeight/对于图像四周边界处的向素点不处理buf1=(int*(hData+(i+1*WIDTHBYTES(lpBi-biWidth*8+(j-1+2*(int*(hData+(i+1*WIDTHBYTES(lpBi-biWidth*8+(j+(int(int*(hData+(i+1*WIDTHBYTES(lpBi-biWidth*8+(j+1。buf1=buf1-(int(int*(hData+(i-1*WIDTHBYTES(lpBi-biWidth*8+(j-1-2*(int(int*(hData+(i-1*WIDTHBYTES(lpBi-biWidth*8+(j-(int(int*(hData+(i-1*WIDTHBYTES(lpBi-biWidth*8+(j+1。/x方向加权微分buf2=(int(int*(hData+(i-1*WIDTHBYTES(lpBi-biWidth*8+(j+1+2*(int(int*(hData+(i*WIDTHBYTES(lpBi-biWidth*8+(j+1+(int(int*(hData+(i+1*WIDTHBYTES(lpBi-biWidth*8+(j+1。buf2=buf2-(int(int*(hData+(i-1*WIDTHBYTES(lpBi-biWidth*8+(j-1-2*(int(int*(hData+(i*WIDTHBYTES(lpBi-biWidth*8+(j-1-(int(int*(hData+(i+1*WIDTHBYTES(lpBi-biWidth*8+(j-1。/y方向加权微分buf=abs(buf1+abs(buf2。/求梯度if(buf255 buf=255。if(bufbuf=0。*(data+i*WIDTHBYTES(lpBi-biWidth*8+j=(BYTEbuf。else *(data+i*lpBi-biWidth+j=(BYTE0。for( j=0。 jbiHeight。 j+for( i=0。 ibiWidth。 i+*(hData+i*WIDTHBYTES(lpBi-biWidth*8+j=*(data+i*WIDTHBYTES(lpBi-biWidth*8+j。 /处理后的数据写回原缓冲区AfxGetApp(-EndWaitCursor(。GlobalUnlock(HGLOBALhdib。GlobalUnlock(data1handle。GlobalFree(date1handle。EndWaitCursor(。Invalidate(TRUE。上述的数学分析读者可能看起来有些吃力,不过不要紧,对与边缘检测,大家只要知道有若干个检测模板+fi,j-1-4fi,j|。其中Gi,j表示处理后(i,j点的灰度值,fi,j表示处理前该点的灰度值。笔者开发的该图像处理程序在Windows2000环境下编译通过,下面图2给出了依据图像处理算法得到的图像二值化、高通滤波、Sobel边缘算子的处理结果,读者需要注意的是我在进行Sobel算子进行处理后,又对它进行了二值化处理,这才得到C图。关于如何实现二值化图像,我会后续撰文对相关知识进行介绍。=void CreatGauss(double sigma, double *pdKernel, int *pnWidowSize。void GaussianSmooth(SIZE sz, LPBYTE pGray, LPBYTE pResult, double sigma。void Grad(SIZE sz, LPBYTE pGray, int *pGradX, int *pGradY,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论