天天看點

用遞歸方法來搜尋連通區域

 直接使用遞歸方法來搜尋連通區域,如果連通區域是大的整塊的值,這樣就會出現遞歸溢出的問題,是以我使用了邊界遞歸的思路,建立一個圖像大小的二值數組,儲存圖像的每個像素的值(0或者1).這樣在遞歸的時候如果一個像素的4或者8方向都是跟自己值相同,就可以跳過這點繼續搜尋,因為他不在邊界上,同時為搜尋過的每個像素儲存狀态,後面就可以跳過搜尋過的點.

下面是C#描述算法:

private bool[][] sArr;

  private bool[][] vArr;

//

  private void findRect()

  {

   recArr = newArrayList();

   for (int i=0;i<bmp.Width; i++){

    for(int j=0; j<bmp.Height; j++)

     sArr[i][j]=false;

   }

   //

   for (int i=1;i<bmp.Width-1; i++) {

    for(int j=1; j<bmp.Height-1; j++) {

     if(vArr[i][j]) {

      rec= new Rectangle();

      rec.Y= j;

      rec.Height= j;

      rec.X= i;

      rec.Width= i;

      //

      if(findNext(i,j)) {

       if(rec.Width>0 && rec.Height>0) {

        rec.Height= rec.Height - rec.Y;

        rec.Width= rec.Width - rec.X;

        drawOneRec(rec);

        recArr.Add(rec);

       }

      }

      fnCount= 0;

     }

    }

  }

  private int fnCount=0;

  private bool findNext(int i,intj)

   fnCount++;

   if(fnCount> 10000)

   {

    //fnCount= 0;

    returntrue;

   try

    if(i<2||i>bmp.Width-2||j<2||j>bmp.Height-2)

    {

     //throw(newException("error"));

    elseif (vArr[i][j] && !sArr[i][j])

     if(j<rec.Y)

     {

      rec.Y=j;

     if(j>rec.Height)

      rec.Height=j;

     if(i<rec.X)

      rec.X=i;

     if(i>rec.Width)

      rec.Width=i;

     //

     sArr[i][j]= true;

     //if(!vArr[i+1][j+1] || !vArr[i+1][j-1])

     if(vArr[i+1][j] && !sArr[i+1][j])

      findNext(i+1,j);

     if(vArr[i-1][j] && !sArr[i-1][j])

      findNext(i-1,j);

     if(vArr[i][j+1] && !sArr[i][j+1])

      findNext(i,j+1);

     if(vArr[i][j-1] && !sArr[i][j-1])

      findNext(i,j-1);

     //findNext(i+1,j+1);

     //findNext(i-1,j-1);

     //findNext(i-1,j+1);

     //findNext(i+1,j-1);

   catch(Exception e)

    //MessageBox.Show(e.Message);

    //returntrue;

   returntrue;

本文轉自feisky部落格園部落格,原文連結:http://www.cnblogs.com/feisky/archive/2008/04/11/1586639.html,如需轉載請自行聯系原作者

繼續閱讀