C语言canny算子函数 c语言里的算法( 二 )


{
for(y=0; ysz.cy; y++)
{
dDotMul = 0;
dWeightSum = 0;
for(i=(-nLen);i=nLen;i++)
{
if((i+y)=0(i+y) sz.cy)
{
dDotMul += (double)pdTemp[(y+i)*sz.cx+x]*pdKernel[nLen+i];
dWeightSum += pdKernel[nLen+i];
}
}
pResult[y*sz.cx+x] = (unsigned char)dDotMul/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;ysz.cy-1;y++)
{
for(x=1;xsz.cx-1;x++)
{
pGradX[y*sz.cx +x] = (int)( pGray[y*sz.cx+x+1]-pGray[y*sz.cx+ x-1]);
}
}
//y方向方向导数
for(x=1;xsz.cx-1;x++)
{
for(y=1;ysz.cy-1;y++)
{
pGradY[y*sz.cx +x] = (int)(pGray[(y+1)*sz.cx +x] - pGray[(y-1)*sz.cx +x]);
}
}
//求梯度
//中间变量
double dSqt1;
double dSqt2;
for(y=0; ysz.cy; y++)
{
for(x=0; xsz.cx; x++)
{
//二阶范数求梯度
dSqt1 = pGradX[y*sz.cx + x]*pGradX[y*sz.cx + x];
dSqt2 = pGradY[y*sz.cx + x]*pGradY[y*sz.cx + x];
pMag[y*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;xsz.cx;x++)
{
pNSRst[x] = 0;
pNSRst[(sz.cy-1)*sz.cx+x] = 0;
}
for(y=0;ysz.cy;y++)
{
pNSRst[y*sz.cx] = 0;
pNSRst[y*sz.cx + sz.cx-1] = 0;
}
for(y=1;ysz.cy-1;y++)
{
for(x=1;xsz.cx-1;x++)
{
//当前点
nPos = y*sz.cx + x;
//如果当前像素梯度幅度为0C语言canny算子函数 , 则不是边界点
if(pMag[nPos] == 0)
{
pNSRst[nPos] = 0;
}
else
{
//当前点的梯度幅度
dTmp = pMag[nPos];
//x,y方向导数
gx = pGradX[nPos];
gy = pGradY[nPos];
//如果方向导数y分量比x分量大 , 说明导数方向趋向于y分量
if(abs(gy)abs(gx))
{
//计算插值比例
weight = fabs(gx)/fabs(gy);
g2 = pMag[nPos-sz.cx];
g4 = pMag[nPos+sz.cx];
//如果x,y两个方向导数的符号相同
//C 为当前像素,与g1-g4 的位置关系为:
//g1 g2
//C
//g4 g3
if(gx*gy0)
{
g1 = pMag[nPos-sz.cx-1];
g3 = pMag[nPos+sz.cx+1];
}
//如果x,y两个方向的方向导数方向相反
//C是当前像素,与g1-g4的关系为:
//g2 g1
//C
//g3 g4
else
{
g1 = pMag[nPos-sz.cx+1];
g3 = pMag[nPos+sz.cx-1];
}
}
//如果方向导数x分量比y分量大,说明导数的方向趋向于x分量
else
{
//插值比例
weight = fabs(gy)/fabs(gx);
g2 = pMag[nPos+1];
g4 = pMag[nPos-1];
//如果x,y两个方向的方向导数符号相同
//当前像素C与 g1-g4的关系为
//g3
//g4 C g2
//g1
if(gx * gy0)
{
g1 = pMag[nPos+sz.cx+1];
g3 = pMag[nPos-sz.cx-1];
}
//如果x,y两个方向导数的方向相反
// C与g1-g4的关系为
//g1
//g4 C g2
//g3
else
{
g1 = pMag[nPos-sz.cx+1];
g3 = pMag[nPos+sz.cx-1];
}
}
//利用 g1-g4 对梯度进行插值
{
dTmp1 = weight*g1 + (1-weight)*g2;
dTmp2 = weight*g3 + (1-weight)*g4;
//当前像素的梯度是局部的最大值

推荐阅读