小孔判定與最短距識別

來源:互聯網
上載者:User

Question:以下兩幅映像,判斷出哪個有孔,並計算出圖中勺子的最窄處的寬度?


我用vc++編寫的識別架構如下:

1.運行介面開啟映像:

2.點擊地區分割與提取:

3.進行多次中值濾波,然後進行一次一階微分運算,運算結果放大兩倍,然後去25二值化得到邊界圖:

然後計算最後操那個圖的像素總值,2.bmp顯示結果為接近6000;求得最短就離為31個像素點,利用length=nmin/28.346這個即可求出距離。

關鍵代碼:

/*----Threshold----二值化處理------------------------

image_in 輸入映像資料指標

image_out 輸出映像資料指標

xsize   映像寬度

ysize   映像高度

thresh  閾值(0-255)

mode    處理方法(1,2)

--------------------------------------------------*/

 

void Threshold(BYTE *image_in,BYTE*image_out,int xsize,int ysize,int thresh,int mode)

       {

              inti,j;

              for(j=0;j<ysize;j++)

              {

                     for(i=0;i<xsize;i++)

                     {

                            switch(mode)

                            {

                            case2:

                                   if(*(image_in+i+j*xsize)<=thresh)

                                          *(image_out+i+j*xsize)=HIGH;

                                   else

                                          *(image_out+i+j*xsize)=LOW;

                                   break;

                            default:

                                   if(*(image_in+i+j*xsize)>=thresh)

                                          *(image_out+i+j*xsize)=HIGH;

                                   else

                                          *(image_out+i+j*xsize)=LOW;

                                   break;

                            }

                     }    

              }

       }

//中值子函數

int median_value(BYTE c[9])

{

       inti,j,buf;

       for(j=0;j<8;j++){

              for(i=0;i<8;i++){

                     if(c[i+1]<c[i]){

                            buf=c[i+1];

                            c[i+1]=c[i];

                            c[i]=buf;

                     }

              }

       }

       returnc[4];

}

//中值濾波

void Median(BYTE *image_in, BYTE*image_out, int xsize, int ysize)

{

       inti,j;

       unsignedchar c[9];

       for(i=1;i<ysize-1;i++){

              for(j=1;j<xsize-1;j++){

              c[0]=*(image_in+(i-1)*xsize+j-1);

              c[1]=*(image_in+(i-1)*xsize+j);

              c[2]=*(image_in+(i-1)*xsize+j+1);

              c[3]=*(image_in+i*xsize+j-1);

              c[4]=*(image_in+i*xsize+j);

              c[5]=*(image_in+i*xsize+j+1);

              c[6]=*(image_in+(i+1)*xsize+j-1);

              c[7]=*(image_in+(i+1)*xsize+j);

              c[8]=*(image_in+(i+1)*xsize+j+1);

              *(image_out+i*xsize+j)=median_value(c);

              }

       }

}

 

/*--------------------------提取輪廓-----------------------------*

 

//1階微分邊沿檢出(梯度運算元)

amp    //輸出像素值倍數

roberts運算元:g(x,y)=abs(f(x,y)-f(x+1,y+1))+abs(f(x,y+1)-f(x+1,y))

Roberts邊緣檢測運算元是一種利用局部差分運算元尋找邊緣的運算元,Robert運算元影像處理後結果邊緣不是很平滑。

經分析,由於Robert運算元通常會在映像邊緣附近的地區內 產生較寬的響應,

故採用上述運算元檢測的邊緣映像常需做細化處理,邊緣定位的精度不是很高。

 

卷積運算:可看作是加權求和的過程,使用到的映像地區中的每個像素

分別於卷積核(權矩陣)的每個元素對應相乘,所有乘積之和作為地區中心像素的新值。

 

連續空間的卷積定義是f(x)與g(x)的卷積是 f(t-x)g(x) 在t從負無窮到正無窮的積分值.t-x要在f(x)定義域內

所以看上去很大的積分實際上還是在一定範圍的

把積分符號換成求和就是離散空間的卷積定義了.那麼在映像中卷積卷積地是什麼意思呢,

就是映像就是映像f(x),模板是g(x),然後將模版g(x)在模版中移動,每到一個位置,

就把f(x)與g(x)的定義域相交的元素進行乘積並且求和,得出新的映像一點,就是被卷積後的映像.

------------------------------------------------------------------*/

void Differential(BYTE *image_in, BYTE*image_out, int xsize, int ysize, float amp)

{

       staticint cx[9]={0,0,0,0,1,0,0,0,-1};  //運算元X(roberts)

       staticint cy[9]={0,0,0,0,0,1,0,-1,0};  //運算元y(roberts)

       intd[9];

       inti,j,dat;

       floatxx,yy,zz;

 

       for(j=1;j<ysize-1;j++)

       {

              for(i=1;i<xsize;i++)

              {

                     d[0]=*(image_in+(j-1)*xsize+i-1);

                     d[1]=*(image_in+(j-1)*xsize+i);

                     d[2]=*(image_in+(j-1)*xsize+i+1);

                     d[3]=*(image_in+j*xsize+i-1);

                     d[4]=*(image_in+j*xsize+i);

                     d[5]=*(image_in+j*xsize+i+1);

                     d[6]=*(image_in+(j+1)*xsize+i-1);

                     d[7]=*(image_in+(j+1)*xsize+i);

                     d[8]=*(image_in+(j+1)*xsize+i+1);//在映像上取出3*3的像素值

 

                     xx=(float)(cx[0]*d[0]+cx[1]*d[1]+cx[2]*d[2]+cx[3]*d[3]+cx[4]*d[4]+

                            cx[5]*d[5]+cx[6]*d[6]+cx[7]*d[7]+cx[8]*d[8]);

                     yy=(float)(cy[0]*d[0]+cy[1]*d[1]+cy[2]*d[2]+cy[3]*d[3]+cy[4]*d[4]+

                            cy[5]*d[5]+cy[6]*d[6]+cy[7]*d[7]+cy[8]*d[8]);

                    

                     zz=(float)(amp*sqrt(xx*xx+yy*yy));

                     dat=(int)zz;

 

                     if(dat>255)dat=255;

                     *(image_out+j*xsize+i)=dat;

              }

       }

 

}

//膨脹

void Dilation(BYTE *image_in, BYTE*image_out, int xsize, int ysize)

{

       inti,j;

       for(j=1;j<ysize-1;j++){

              for(i=1;i<xsize-1;i++){

                     *(image_out+j*xsize+i)=*(image_in+j*xsize+i);

                     if(*(image_in+(j-1)*xsize+i-1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j-1)*xsize+i)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j-1)*xsize+i+1)==HIGH)

                     *(image_out+j*xsize+i+1)=HIGH;

                     if(*(image_in+j*xsize+i-1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+j*xsize+i+1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+j*xsize+i)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j+1)*xsize+i-1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j+1)*xsize+i+1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j+1)*xsize+i)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

              }

       }

 

}

//腐蝕

void Erodible(BYTE *image_in, BYTE*image_out, int xsize, int ysize)

{

       inti,j;

       for(j=1;j<ysize-1;j++){

              for(i=1;i<xsize-1;i++){

                     *(image_out+j*xsize+i)=*(image_in+j*xsize+i);

                     if(*(image_in+(j-1)*xsize+i-1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j-1)*xsize+i)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j-1)*xsize+i+1)==LOW)

                     *(image_out+j*xsize+i+1)=LOW;

                     if(*(image_in+j*xsize+i-1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+j*xsize+i+1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+j*xsize+i)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j+1)*xsize+i-1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j+1)*xsize+i+1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j+1)*xsize+i)==LOW)

                     *(image_out+j*xsize+i)=LOW;

              }

       }

}

/********************************************************************/

//求像素總和

int i,j;

       for(j=1;j<m_nysize-1;j++){

              for(i=1;i<m_nxsize-1;i++){

                     *(m_pImage_out+j*m_nxsize+i)=*(m_pImage_in+j*m_nxsize+i);

                     if(*(m_pImage_in+j*m_nxsize+i-1)==HIGH)

                            m_nSum++;

              }

       }

 

       SetDlgItemInt(IDC_SUM,m_nSum,TRUE);

 

/**********************************************************************/

求最短距離

int i,j;

       intxx,yy;

       intjj=0;

       intii=0;

       intsumiy[429]={0};

       intsumjy[429]={0};

       intsum[429]={1};

       intiy[116]={0};

       intjy[116]={0};

       intnmin=100;//最短距離初值

 

       for(j=1;j<m_nysize-1;j++)

       {

              for(i=1;i<m_nxsize-1;i++)//求出某一行在橫座標方向上的左起像素豈起始點

              {

                     //*(m_pImage_out+j*m_nxsize+i)=*(m_pImage_in+j*m_nxsize+i);

                     if(*(m_pImage_in+j*m_nxsize+i-1)==HIGH)

                            xx=1;

                     if(xx==1)

                     {

                            iy[jj]=i;

                            jj++;

                     }

              }

              sumiy[j]=iy[1];

 

      

              for(i=m_nxsize-1;i>1;i--)//求出某一行在橫座標方向上的右起像素豈起始點

              {

                     if(*(m_pImage_in+j*m_nxsize+i-1)==HIGH)

                            yy=1;

                     if(ii==1)

                     {

                            jy[ii]=i;

                            ii++;

                     }

              }

              sumjy[j]=jy[1];

 

              sum[j]=abs(sumjy[j]-sumiy[j]);//求出某一行在橫座標方向上的像素區間

       }

 

 

       for(j=1;j<427;j++)

       {

        //求出所有行中在在橫座標方向像素區間最小的距離

              if((sum[j]>30) && (sum[j]<100))//排除錯誤成分

                     {

                            if( sum[j]<nmin )

                            {

                                   nmin=sum[j];

 

                            }

                     }

       }

       SetDlgItemInt(IDC_MIN,nmin,TRUE);

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.