canny边缘检测算子的c源代码_第1页
canny边缘检测算子的c源代码_第2页
canny边缘检测算子的c源代码_第3页
canny边缘检测算子的c源代码_第4页
canny边缘检测算子的c源代码_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

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

文档简介

1、canny边缘检测算子的c源代码canny算子代码voidCreatGauss(doublesigma,double*pdKernel,int*pnWidowSize);voidGaussianSmooth(SIZEsz,LPBYTEpGray,LPBYTEpResult,doublesigma);voidGrad(SIZEsz,LPBYTEpGray,int*pGradX,int*pGradY,int*pMag);voidNonmaxSuppress(int*pMag,int*pGradX,int*pGradY,SIZEsz,LPBYTEpNSRst);voidEstimateThresho

2、ld(int*pMag,SIZEsz,int*pThrHigh,int*pThrLow,LPBYTEpGray,doubledRatHigh,doubledRatLow);voidHysteresis(int*pMag,SIZEsz,doubledRatLow,doubledRatHigh,LPBYTEpResult);voidTraceEdge(inty,intx,intnThrLow,LPBYTEpResult,int*pMag,SIZEsz);voidCanny(LPBYTEpGray,SIZEsz,doublesigma,doubledRatLow,doubledRatHigh,LPB

3、YTEpResult);#includeafx.h#includemath.h#includecanny.h/一维高斯分布函数,用于平滑函数中生成的高斯滤波系数voidCreatGauss(doublesigma,double*pdKernel,int*pnWidowSize)LONGi;/数组中心点intnCenter;/数组中一点到中心点距离doubledDis;/中间变量doubledValue;doubledSum;dSum=0;/-3*sigma,3*sigma以内数据,会覆盖绝大部分滤波系数pnWidowSize=1+2*ceil(3*sigma);nCenter=(*pnWido

4、wSize)/2;*pdKernel=newdouble*pnWidowSize;/生成高斯数据for(i=0;i(*pnWidowSize);i+)dDis=double(i-nCenter);dValue=exp(-(1/2)*dDis*dDis/(sigma*sigma)/(sqrt(2*3.1415926)*sigma);(*pdKernel)i=dValue;dSum+=dValue;/归一化for(i=0;i(*pnWidowSize);i+)(*pdKernel)i/=dSum;/用高斯滤波器平滑原图像voidGaussianSmooth(SIZEsz,LPBYTEpGray,L

5、PBYTEpResult,doublesigma)LONGx,y;LONGi;/高斯滤波器长度intnWindowSize;/窗口长度intnLen;/一维高斯滤波器double*pdKernel;/高斯系数与图像数据的点乘doubledDotMul;/滤波系数总和doubledWeightSum;double*pdTemp;pdTemp=newdoublesz.cx*sz.cy;/产生一维高斯数据CreatGauss(sigma,&pdKernel,&nWindowSize);nLen=nWindowSize/2;/X方向滤波for(y=0;ysz.cy;y+)for(X=0;Xsz.cX;

6、X+)dDotMul=0;dWeightSum=0;for(i=(-nLen);i=0&(i+X)sz.cX)dDotMul+=(double)pGrayy*sz.cX+(i+X)*pdKernelnLen+i;dWeightSum+=pdKernelnLen+i;pdTempy*sz.cX+X=dDotMul/dWeightSum;/y方向滤波for(X=0;Xsz.cX;X+)for(y=0;ysz.cy;y+)dDotMul=0;dWeightSum=0;for(i=(-nLen);i=0&(i+y)sz.cy)dDotMul+=(double)pdTemp(y+i)*sz.cX+X*p

7、dKernelnLen+i;dWeightSum+=pdKernelnLen+i;pResulty*sz.cX+X=(unsignedchar)dDotMul/dWeightSum;deletepdKernel;pdKernel=NULL;deletepdTemp;pdTemp=NULL;/方向导数,求梯度voidGrad(SIZEsz,LPBYTEpGray,int*pGradX,int*pGradY,int*pMag)LONGy,x;/X方向的方向导数for(y=1;ysz.cy-1;y+)for(X=1;Xsz.cX-1;X+)pGradXy*sz.cX+X=(int)(pGrayy*s

8、z.cX+X+1-pGrayy*sz.cX+X-1);/y方向方向导数for(X=1;Xsz.cX-1;X+)for(y=1;ysz.cy-1;y+)pGradYy*sz.cX+X=(int)(pGray(y+1)*sz.cX+X-pGray(y-1)*sz.cX+X);/求梯度/中间变量doubledSqt1;doubledSqt2;for(y=0;ysz.cy;y+)for(X=0;Xsz.cX;X+)/二阶范数求梯度dSqt1=pGradXy*sz.cx+x*pGradXy*sz.cx+x;dSqt2=pGradYy*sz.cx+x*pGradYy*sz.cx+x;pMagy*sz.cx

9、+x=(int)(sqrt(dSqt1+dSqt2)+0.5);/非最大抑制voidNonmaxSuppress(int*pMag,int*pGradX,int*pGradY,SIZEsz,LPBYTEpNSRst)LONGy,x;intnPos;/梯度分量intgx;intgy;/中间变量intg1,g2,g3,g4;doubleweight;doubledTmp,dTmp1,dTmp2;/设置图像边缘为不可能的分界点for(x=0;xsz.cx;x+)pNSRstx=0;pNSRst(sz.cy-1)*sz.cx+x=0;for(y=0;ysz.cy;y+)pNSRsty*sz.cx=0;

10、pNSRsty*sz.cx+sz.cx-1=0;for(y=1;ysz.cy-1;y+)for(x=1;xabs(gx)/计算插值比例weight=fabs(gx)/fabs(gy);g2=pMagnPos-sz.cx;g4=pMagnPos+sz.cx;/如果x,y两个方向导数的符号相同/C为当前像素,与g1-g4的位置关系为:/g1g2/C/g4g3if(gx*gy0)g1=pMagnPos-sz.cx-1;g3=pMagnPos+sz.cx+1;如果x,y两个方向的方向导数方向相反/C是当前像素,与g1-g4的关系为:/g2g1/C/g3g4elseg1=pMagnPos-sz.cx+1

11、;g3=pMagnPos+sz.cx-1;如果方向导数x分量比y分量大,说明导数的方向趋向于x分量else/插值比例weight=fabs(gy)/fabs(gx);g2=pMagnPos+1;g4=pMagnPos-1;如果x,y两个方向的方向导数符号相同当前像素C与gl-g4的关系为/g3/g4Cg2/g1if(gx*gy0)g1=pMagnPos+sz.cx+1;g3=pMagnPos-sz.cx-1;如果x,y两个方向导数的方向相反/C与g1-g4的关系为/g1/g4Cg2/g3elseg1=pMagnPos-sz.cx+1;g3=pMagnPos+sz.cx-1;/利用g1-g4对梯

12、度进行插值dTmp1=weight*g1+(1-weight)*g2;dTmp2=weight*g3+(1-weight)*g4;/当前像素的梯度是局部的最大值/该点可能是边界点if(dTmp=dTmp1&dTmp=dTmp2)pNSRstnPos=128;else/不可能是边界点pNSRstnPos=0;/统计pMag的直方图,判定阈值voidEstimateThreshold(int*pMag,SIZEsz,int*pThrHigh,int*pThrLow,LPBYTEpGray,doubledRatHigh,doubledRatLow)LONGy,x,k;/该数组的大小和梯度值的范围有关

13、,如果采用本程序的算法/那么梯度的范围不会超过pow(2,10)intnHist256;/可能边界数intnEdgeNum;/最大梯度数intnMaxMag;intnHighCount;nMaxMag=0;/初始化for(k=0;k256;k+)nHistk=0;/统计直方图,利用直方图计算阈值for(y=0;ysz.cy;y+)for(x=0;xsz.cx;x+)if(pGrayy*sz.cx+x=128)nHistpMagy*sz.cx+x+;nEdgeNum=nHist0;nMaxMag=0;/统计经过“非最大值抑制”后有多少像素for(k=1;k256;k+)if(nHistk!=0)

14、nMaxMag=k;/梯度为0的点是不可能为边界点的/经过non-maximumsuppression后有多少像素nEdgeNum+=nHistk;梯度比高阈值*pThrHigh小的像素点总书目nHighCount=(int)(dRatHigh*nEdgeNum+0.5);k=1;nEdgeNum=nHist1;/计算高阈值while(k(nMaxMag-1)&(nEdgeNumnHighCount)k+;nEdgeNum+=nHistk;*pThrHigh=k;/低阈值*pThrLow=(int)(*pThrHigh)*dRatLow+0.5);/利用函数寻找边界起点voidHysteres

15、is(int*pMag,SIZEsz,doubledRatLow,doubledRatHigh,LPBYTEpResult)LONGy,x;intnThrHigh,nThrLow;intnPos;/估计TraceEdge函数需要的低阈值,以及Hysteresis函数使用的高阈值EstimateThreshold(pMag,sz,&nThrHigh,&nThrLow,pResult,dRatHigh,dRatLow);寻找大于dThrHigh的点,这些点用来当作边界点,/然后用TraceEdge函数跟踪该点对应的边界for(y=0;ysz.cy;y+)for(x=0;x=nThrHigh)/设置

16、该点为边界点pResultnPos=255;TraceEdge(y,x,nThrLow,pResult,pMag,sz);/其他点已经不可能为边界点for(y=0;ysz.cy;y+)for(x=0;xsz.cx;x+)nPos=y*sz.cx+x;if(pResultnPos!=255)pResultnPos=0;根据Hysteresis执行的结果,从一个像素点开始搜索,搜索以该像素点为边界起点的一条边界的/一条边界的所有边界点,函数采用了递归算法/从(x,y)坐标出发,进行边界点的跟踪,跟踪只考虑pResult中没有处理并且可能是边界/点的像素(=128),像素值为0表明该点不可能是边界点

17、,像素值为255表明该点已经是边界点voidTraceEdge(inty,intx,intnThrLow,LPBYTEpResult,int*pMag,SIZEsz)/对8邻域像素进行查询intxNum8=1,1,0,-1,-1,-1,0,1;intyNum8=0,1,1,1,0,-1,-1,-1;LONGyy,xx,k;for(k=0;k=nThrLow)/该点设为边界点pResultyy*sz.cx+xx=255;/以该点为中心再进行跟踪TraceEdge(yy,xx,nThrLow,pResult,pMag,sz);/Canny算子voidCanny(LPBYTEpGray,SIZEsz

18、,doublesigma,doubledRatLow,doubledRatHigh,LPBYTEpResult)/经过高斯滤波后的图像LPBYTEpGaussSmooth;pGaussSmooth=newunsignedcharsz.cx*sz.cy;/x方向导数的指针int*pGradX;pGradX=newintsz.cx*sz.cy;/y方向int*pGradY;pGradY=newintsz.cx*sz.cy;/梯度的幅度int*pGradMag;pGradMag=newintsz.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

温馨提示

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

评论

0/150

提交评论