本文主要是介绍Canny边缘检测算法原理及其VC实现详解(三),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
转载自:http://blog.csdn.net/likezhaobin/article/details/6892629
3.3 图像增强——计算图像梯度及其方向
- //同样可以用不同的检测器/
- /
P[i,j]=(S[i,j+1]-S[i,j]+S[i+1,j+1]-S[i+1,j])/2 / - /
Q[i,j]=(S[i,j]-S[i+1,j]+S[i,j+1]-S[i+1,j+1])/2 / - /
- double*
P new= double[nWidth*nHeight]; - double*
Q new= double[nWidth*nHeight]; - int*
M new= int[nWidth*nHeight]; - double*
Theta new= double[nWidth*nHeight]; - //计算x,y方向的偏导数
- for(i=0;
i<(nHeight-1); i++) - {
-
for(j=0; j<(nWidth-1); j++) -
{ -
P[i*nWidth+j] = (double)(pCanny[i*nWidth + min(j+1, nWidth-1)] - pCanny[i*nWidth+j] + pCanny[min(i+1, nHeight-1)*nWidth+min(j+1, nWidth-1)] - pCanny[min(i+1, nHeight-1)*nWidth+j])/2; -
Q[i*nWidth+j] = (double)(pCanny[i*nWidth+j] - pCanny[min(i+1, nHeight-1)*nWidth+j] + pCanny[i*nWidth+min(j+1, nWidth-1)] - pCanny[min(i+1, nHeight-1)*nWidth+min(j+1, nWidth-1)])/2; -
} - }
- //计算梯度幅值和梯度的方向
- for(i=0;
i<nHeight; i++) - {
-
for(j=0; j<nWidth; j++) -
{ -
M[i*nWidth+j] = (int)(sqrt(P[i*nWidth+j]*P[i*nWidth+j] + Q[i*nWidth+j]*Q[i*nWidth+j])+0.5); -
Theta[i*nWidth+j] = atan2(Q[i*nWidth+j], P[i*nWidth+j]) * 57.3; -
if(Theta[i*nWidth+j] < 0) -
Theta[i*nWidth+j] += 360; //将这个角度转换到0~360范围 -
} - }
3.4 非极大值抑制
- unsigned
char* N new= unsigned char[nWidth*nHeight]; - int
g1=0, //用于进行插值,得到亚像素点坐标值g2=0, g3=0, g4=0; - double
dTmp1=0.0, //保存两个亚像素点插值得到的灰度数据dTmp2=0.0; - double
dWeight=0.0; //插值的权重
- for(i=0;
i<nWidth; i++) - {
-
N[i] = 0; -
N[(nHeight-1)*nWidth+i] = 0; - }
- for(j=0;
j<nHeight; j++) - {
-
N[j*nWidth] = 0; -
N[j*nWidth+(nWidth-1)] = 0; - }
- for(i=1;
i<(nWidth-1); i++) - {
-
for(j=1; j<(nHeight-1); j++) -
{ -
int nPointIdx //当前点在图像数组中的索引值= i+j*nWidth; -
if(M[nPointIdx] == 0) -
N[nPointIdx] = 0; //如果当前梯度幅值为0,则不是局部最大对该点赋为0 -
else -
{ -
首先判断属于那种情况,然后根据情况插值/// -
第一种情况/// -
/ g1 g2 / -
/ C / -
/ g3 g4 / -
/ -
if( ((Theta[nPointIdx]>=90)&&(Theta[nPointIdx]<135)) || -
((Theta[nPointIdx]>=270)&&(Theta[nPointIdx]<315))) -
{ -
//根据斜率和四个中间值进行插值求解 -
g1 = M[nPointIdx-nWidth-1]; -
g2 = M[nPointIdx-nWidth]; -
g3 = M[nPointIdx+nWidth]; -
g4 = M[nPointIdx+nWidth+1]; -
dWeight = fabs(P[nPointIdx])/fabs(Q[nPointIdx]); //反正切 -
dTmp1 = g1*dWeight+g2*(1-dWeight); -
dTmp2 = g4*dWeight+g3*(1-dWeight); -
} -
第二种情况/// -
/ g1 / -
/ g2 C g3 / -
/ g4 / -
/ -
else if( ((Theta[nPointIdx]>=135)&&(Theta[nPointIdx]<180)) || -
((Theta[nPointIdx]>=315)&&(Theta[nPointIdx]<360))) -
{ -
g1 = M[nPointIdx-nWidth-1]; -
g2 = M[nPointIdx-1]; -
g3 = M[nPointIdx+1]; -
g4 = M[nPointIdx+nWidth+1]; -
dWeight = fabs(Q[nPointIdx])/fabs(P[nPointIdx]); //正切 -
dTmp1 = g2*dWeight+g1*(1-dWeight); -
dTmp2 = g4*dWeight+g3*(1-dWeight); -
} -
第三种情况/// -
/ g1 g2 / -
/ C / -
/ g4 g3 / -
/ -
else if( ((Theta[nPointIdx]>=45)&&(Theta[nPointIdx]<90)) || -
((Theta[nPointIdx]>=225)&&(Theta[nPointIdx]<270))) -
{ -
g1 = M[nPointIdx-nWidth]; -
g2 = M[nPointIdx-nWidth+1]; -
g3 = M[nPointIdx+nWidth]; -
g4 = M[nPointIdx+nWidth-1]; -
dWeight = fabs(P[nPointIdx])/fabs(Q[nPointIdx]); //反正切 -
dTmp1 = g2*dWeight+g1*(1-dWeight); -
dTmp2 = g3*dWeight+g4*(1-dWeight); -
} -
第四种情况/// -
/ g1 / -
/ g4 C g2 / -
/ g3 / -
/ -
else if( ((Theta[nPointIdx]>=0)&&(Theta[nPointIdx]<45)) || -
((Theta[nPointIdx]>=180)&&(Theta[nPointIdx]<225))) -
{ -
g1 = M[nPointIdx-nWidth+1]; -
g2 = M[nPointIdx+1]; -
g3 = M[nPointIdx+nWidth-1]; -
g4 = M[nPointIdx-1]; -
dWeight = fabs(Q[nPointIdx])/fabs(P[nPointIdx]); //正切 -
dTmp1 = g1*dWeight+g2*(1-dWeight); -
dTmp2 = g3*dWeight+g4*(1-dWeight); -
} -
} -
//进行局部最大值判断,并写入检测结果 -
if((M[nPointIdx]>=dTmp1) && (M[nPointIdx]>=dTmp2)) -
N[nPointIdx] = 128; -
else -
N[nPointIdx] = 0; -
} - }
这篇关于Canny边缘检测算法原理及其VC实现详解(三)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!