邊緣檢測與影象分割
阿新 • • 發佈:2019-01-04
void sobel (unsignedchar* des, constunsignedchar* src, int width, int height) { for (int y=0; y<height; y++) for (int x=0; x<width; x++) des[y * width + x]=255; /* Now compute the convolution, scaling */ for (int y=1; y<height-1; y++) for (int x=1; x<width-1; x++) { double n = (src[(y+1)*width+x-1]+2*src[(y+1)*width+x]+src[(y+1)*width+x+1]) - (src[(y-1)*width+x-1]+2*src[(y-1)*width+x]+src[(y-1)*width+x+1]); double m = (src[(y-1)*width+x+1]+2*src[y*width+x+1]+src[(y+1)*width+x+1])- (src[(y-1)*width+x-1]+2*src[y*width+x-1]+src[(y+1)*width+x-1]); double k = (int)( sqrt( (double)(n*n + m*m) )/4.0 ); des[y * width + x] = k; } thresh (des, width,height); } Roberts運算元: void roberts(unsignedchar* des, constunsignedchar* src, int width, int height) { for (int y=0; y<height; y++) for (int x=0; x<width; x++) des[y * width + x]=255; /* Now compute the convolution, scaling */ for (int y=1; y<height-1; y++) for (int x=1; x<width-1; x++) { double n = src[y*width+x] - src[(y+1)*width+x+1]; double m = src[(y+1)*width+x] - src[y*width+x+1]; double k = abs(m)+abs(n); des[y * width + x] = k; } thresh (des, width,height); } Kirsch運算元: void kirsch(unsigned char* des, const unsigned char* src, int width, int height) { // TODO: Add your command handler code here //顯示數值 long int i,j,Ns; static int nWeight[8][3][3];//對一個靜態整型陣列賦初值,模板 double dGrad[8]; int nTmp[3][3],xx,yy;//每畫素點的鄰域值 nWeight[0][0][0] = -1 ; nWeight[0][0][1] = 0 ; nWeight[0][0][2] = 1 ; nWeight[0][1][0] = -2 ; nWeight[0][1][1] = 0 ; nWeight[0][1][2] = 2 ; nWeight[0][2][0] = -1 ; nWeight[0][2][1] = 0 ; nWeight[0][2][2] = 1 ; nWeight[1][0][0] = -1 ; nWeight[1][0][1] = -2 ; nWeight[1][0][2] = -1 ; nWeight[1][1][0] = 0 ; nWeight[1][1][1] = 0 ; nWeight[1][1][2] = 0 ; nWeight[1][2][0] = 1 ; nWeight[1][2][1] = 2 ; nWeight[1][2][2] = 1 ;//負號上下??? 已改成8個方向模板的值 nWeight[2][0][0] = 0 ; nWeight[2][0][1] = -1 ; nWeight[2][0][2] = -2 ; nWeight[2][1][0] = 1 ; nWeight[2][1][1] = 0 ; nWeight[2][1][2] = -1 ; nWeight[2][2][0] = 2 ; nWeight[2][2][1] = 1 ; nWeight[2][2][2] = 0 ; nWeight[3][0][0] = 1 ; nWeight[3][0][1] = 0 ; nWeight[3][0][2] = -1 ; nWeight[3][1][0] = 2 ; nWeight[3][1][1] = 0 ; nWeight[3][1][2] = -2 ; nWeight[3][2][0] = 1 ; nWeight[3][2][1] = 0 ; nWeight[3][2][2] = -1 ; nWeight[4][0][0] = 2 ; nWeight[4][0][1] = 1 ; nWeight[4][0][2] = 0 ; nWeight[4][1][0] = 1 ; nWeight[4][1][1] = 0 ; nWeight[4][1][2] = -1 ; nWeight[4][2][0] = 0 ; nWeight[4][2][1] = -1 ; nWeight[4][2][2] = -2 ; nWeight[5][0][0] = 1 ; nWeight[5][0][1] = 2 ; nWeight[5][0][2] = 1 ; nWeight[5][1][0] = 0 ; nWeight[5][1][1] = 0 ; nWeight[5][1][2] = 0 ; nWeight[5][2][0] = -1 ; nWeight[5][2][1] = -2 ; nWeight[5][2][2] = -1 ; nWeight[6][0][0] = 0 ; nWeight[6][0][1] = 1 ; nWeight[6][0][2] = 2 ; nWeight[6][1][0] = -1 ; nWeight[6][1][1] = 0 ; nWeight[6][1][2] = 1 ; nWeight[6][2][0] = -2 ; nWeight[6][2][1] = -1 ; nWeight[6][2][2] = 0 ; nWeight[7][0][0] = -2 ; nWeight[7][0][1] = -1 ; nWeight[7][0][2] = 0 ; nWeight[7][1][0] = -1 ; nWeight[7][1][1] = 0 ; nWeight[7][1][2] = 1 ; nWeight[7][2][0] = 0 ; nWeight[7][2][1] = -1 ; nWeight[7][2][2] = 2 ; //注意:每行的位元組數必須是4的整數倍!!!先不考慮 Ns=height*width; unsigned char* kk = new unsigned char[width * height]; //開始變換 initiion for(i=0; i<height ; i++ ) //if(i==0)//tt change at 05.05.16 for(j=0 ; j<width ; j++ ) { des[i*width + j]=0;//*(pdGrad+y*nWidth+x) } for(i=1; i<height-1 ; i++ ) { for(j=1 ; j<width-1 ; j++ ) { dGrad[0] = 0 ; dGrad[1] = 0 ; dGrad[2] = 0 ; dGrad[3] = 0 ; dGrad[4] = 0 ; dGrad[5] = 0 ; dGrad[6] = 0 ; dGrad[7] = 0 ; // sobel運算元需要的各點象素值 // 模板第一行 nTmp[0][0] = src[(i-1)*width + j - 1 ]; nTmp[0][1] = src[(i-1)*width + j ] ; nTmp[0][2] = src[(i-1)*width + j + 1 ] ; // 模板第二行 nTmp[1][0] = src[i*width + j - 1 ] ; nTmp[1][1] = src[i*width + j ] ; nTmp[1][2] = src[i*width + j + 1 ] ; // 模板第三行 nTmp[2][0] = src[(i+1)*width + j - 1 ] ; nTmp[2][1] = src[(i+1)*width + j ] ; nTmp[2][2] = src[(i+1)*width + j + 1 ] ; // 計算梯度 for(yy=0; yy<3; yy++) for(xx=0; xx<3; xx++) { dGrad[0] += nTmp[yy][xx] * nWeight[0][yy][xx] ; dGrad[1] += nTmp[yy][xx] * nWeight[1][yy][xx] ; dGrad[2] += nTmp[yy][xx] * nWeight[2][yy][xx] ; dGrad[3] += nTmp[yy][xx] * nWeight[3][yy][xx] ; dGrad[4] += nTmp[yy][xx] * nWeight[4][yy][xx] ; dGrad[5] += nTmp[yy][xx] * nWeight[5][yy][xx] ; dGrad[6] += nTmp[yy][xx] * nWeight[6][yy][xx] ; dGrad[7] += nTmp[yy][xx] * nWeight[7][yy][xx] ; } for (xx=1;xx<8;xx++) { if (dGrad[xx]>dGrad[0]) dGrad[0]=dGrad[xx]; } des[i*width + j]=dGrad[0];// 梯度值寫入src[i] } } //設定閾值 int th[5120],newth[5120],shuN,newN,flagyuzhi;//winframe=32,ii,jj,initpos; double thk,kmin,mvalue[8]; shuN=0; thk=0.5; for (i=0;i<Ns;i++)//每層的每個點 { if ((i>=width) && (i<(Ns-width)))//若是非邊界點,則…… { if ((i%width!=0) && ((i+1)%width!=0)) { //每點做變換,首先求kirs(c)h運算元 mvalue[0]=fabs(double(des[i+1]+des[i+width+1]+des[i+width]+\ des[i+width-1]+des[i-1]-des[i-width-1]-\ des[i-width]-des[i-width+1])); mvalue[1]=fabs(double(des[i+width+1]+des[i+width]+\ des[i+width-1]+des[i-1]+des[i-width-1]-\ des[i-width]-des[i-width+1]-des[i+1])); mvalue[2]=fabs(double(des[i+width]+des[i+width-1]+des[i-1]+\ des[i-width-1]+des[i-width]-\ des[i-width+1]-des[i+1]-des[i+width+1])); mvalue[3]=fabs(double(des[i+width-1]+des[i-1]+\ des[i-width-1]+des[i-width]+\ des[i-width+1]-des[i+1]-des[i+width+1]-\ des[i+width])); mvalue[4]=fabs(double(des[i-1]+des[i-width-1]+\ des[i-width]+des[i-width+1]+des[i+1]-\ des[i+width+1]-des[i+width]-\ des[i+width-1])); mvalue[5]=fabs(double(des[i-width-1]+des[i-width]+\ des[i-width+1]+des[i+1]+des[i+width+1]-\ des[i+width]-des[i+width-1]-des[i-1])); mvalue[6]=fabs(double(des[i-width]+des[i-width+1]+des[i+1]+\ des[i+width+1]+des[i+width]-\ des[i+width-1]-des[i-1]-des[i-width-1])); mvalue[7]=fabs(double(des[i-width+1]+des[i+1]+des[i+width+1]+\ des[i+width]+des[i+width-1]-\ des[i-1]-des[i-width-1]-des[i-width])); for (j=1;j<8;j++) //比較得出運算元,mvalue[0]為最大 { if (mvalue[0]<mvalue[j]) mvalue[0]=mvalue[j]; } kk[i]=max(1,mvalue[0]/15); if (shuN==0) kmin=kk[i]; if (kk[i]>thk) { th[shuN]=i; kmin=min(kmin,kk[i]); shuN++; if (shuN>=5*height)//若大於5*H個點,則重新確定 { //AfxMessageBox("lll"); thk=kmin; newN=0; for (j=0;j<shuN;j++) { if (kk[th[j]]>thk) { if (newN==0) kmin=kk[th[j]]; newth[newN]=th[j]; kmin=min(kmin,kk[th[j]]); newN++; } //else des[th[j]]=0; } for (j=0;j<5120;j++) { th[j]=newth[j]; } shuN=newN; }//重新確定完 } //非邊界的每點變換結束 } } }//一層結束 for (i=0;i<Ns;i++)//每層的每個點 { if (des[i]<thk) des[i]=0; } thresh (des, width,height); //選單函式結束 }