• 用递归方法来搜索连通区域


     直接使用递归方法来搜索连通区域,如果连通区域是大的整块的值,这样就会出现递归溢出的问题,所以我使用了边界递归的思路,建立一个图像大小的二值数组,保存图像的每个像素的值(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;
      }
  • 相关阅读:
    类的组合
    类的派生
    类的继承
    对象的高度整合
    类和数据类型
    对象的绑定方法
    对象属性查找顺序
    C++中struct和class的区别 [转]
    curl_setopt函数相关应用及介绍(转)
    linux 下如何查看和踢除正在登陆的其它用户 ==>Linux下用于查看系统当前登录用户信息的4种方法
  • 原文地址:https://www.cnblogs.com/feisky/p/1586639.html
Copyright © 2020-2023  润新知