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

简介:
直接使用递归方法来搜索连通区域,如果连通区域是大的整块的值,这样就会出现递归溢出的问题,所以我使用了边界递归的思路,建立一个图像大小的二值数组,保存图像的每个像素的值(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;
  }
相关文章
|
11月前
|
存储 编解码 搜索推荐
如何在Windows和Mac上免费将蓝光转换为MKV?
蓝光光盘因能提供高质量的视频和音频内容而备受青睐,但其使用上的局限性却不容忽视。相比之下,MKV作为一种广受支持的视频格式,与大多数播放设备和平台都能完美兼容,为用户带来了更大的便利性和灵活性。
2141 0
|
应用服务中间件 nginx Docker
微服务实战之春云与刀客(四)—— docker swarm 集群实战
概述 docker swarm 是一个非常简单的docker 原生集群部署环境。在docker swarm 出来之前,要搭建一个docker 集群需要复杂的网络运维和配置能力,而docker swarm 把这一切都解放了。
3979 0
|
Web App开发 Ubuntu Linux
Linux包系列的知识(附:Ubuntu16.04升级到18.04的案例)
Linux基础:https://www.cnblogs.com/dunitian/p/4822808.html#linux 之前看到朋友还动不动 apt-get update upgrade,就很纳闷,后来发现原来他只是知道这个更新命令却不知其意,所以每次安装个包就把所有apt-get的常用清除+...
2983 0
|
Web App开发 数据中心 Windows
【镜像更新】Windows Server 2016 数据中心版
信息摘要: Windows Server 2016 数据中心版镜像更新适用客户: 使用Windows Server 2016的用户版本/规格功能: 镜像ID: win2016_64_dtc_1607_zh-cn_40G_alibase_20190318.
4896 0
|
应用服务中间件 nginx
|
Java Android开发 Maven
Android Studio 中无法下载com.android.tools.build:gradle:3.0.1
异常 异常.png Android Studio中无法依赖com.android.tools.build:gradle:3.0.1 解决办法 进入Maven仓库, 并进入指定版本号的Gradle页面,下载pom与jar文件,进入\studio\gradle\m2repository\com\android\tools\build\gradle\文件夹下,创建对应的版本,并将下载好的pom与jar复制进此文件夹。
5366 0