//非最大抑制
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<sz.cx;x++)
{
pNSRst[x] = 0;
pNSRst[(sz.cy-1)*sz.cx+x] = 0;
}
for(y=0;y<sz.cy;y++)
{
pNSRst[y*sz.cx] = 0;
pNSRst[y*sz.cx + sz.cx-1] = 0;
}
for(y=1;y<sz.cy-1;y++)
{
for(x=1;x<sz.cx-1;x++)
{
//当前点
nPos = y*sz.cx + x;
//如果当前像素梯度幅度为0,则不是边界点
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*gy>0)
{
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 * gy > 0)
{
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;
//当前像素的梯度是局部的最大值
//该点可能是边界点
if(dTmp>=dTmp1 && dTmp>=dTmp2)
{
pNSRst[nPos] = 128;
}
else
{
//不可能是边界点
pNSRst[nPos] = 0;
}
}
}
}
}
}