图像分割-区域增长算法及IDL实现

作者:Sinsonglew 出处:http://www.cnblogs.com/sinsonglew 欢迎转载,也请保留这段声明。thanks :)

 

1.  区域增长算法原理

  参考文献: 维基词条区域增长算法;

  从种子点seed出发,遍历seed的4邻域,如果某邻域像素符合阈值设定,则标定为增长点并作为新的增长种子插入到种子队列,并移除老种子,一直循环直到种子队列为空,像素空间(一张图片)便分割完毕。如下图所示,红色格子为初始种子;

  

 

2.  区域增长示例

      

 

3.  代码实现

     注: 开发语言为IDL,ENVI 4.8版本自带开发语言

  区域增长算法类文件 RegionGrow__define.pro

  1 FUNCTION RegionGrow::init, REGION=region, SEEDS=seeds
  2   
  3   self._region   = PTR_NEW(/ALLOCATE_HEAP);
  4   *(self._region) = region;
  5   
  6   dims = size(region, /DIMENSIONS);
  7   self._width = dims[0];
  8   self._height = dims[1];
  9   
 10   self._ifront = 0L;
 11   self._iback = N_ELEMENTS(seeds);
 12   self._seeds = PTR_NEW(/ALLOCATE_HEAP);
 13   *(self._seeds) = MAKE_ARRAY(self._width * self._height, /LONG, VALUE=0);
 14   (*(self._seeds))[INDGEN(self._iback)] = seeds;
 15   
 16   self._hseeds = HASH(seeds, MAKE_ARRAY(self._iback, /BYTE, VALUE=0));
 17   
 18   RETURN, 1
 19   
 20 END
 21 
 22 PRO RegionGrow::setthreshold, mint, maxt
 23   self._mint = mint;
 24   self._maxt = maxt;
 25 END
 26 
 27 FUNCTION RegionGrow::isgrowable, value
 28   RETURN, (self._mint LE value && value LE self._maxt)
 29 END
 30 
 31 FUNCTION RegionGrow::hasseeds
 32   RETURN, (self._ifront LT self._iback);
 33 END
 34 
 35 FUNCTION RegionGrow::isnotseed, index
 36   RETURN, ((self._hseeds).hasKey(index) EQ 0);
 37 END
 38 
 39 FUNCTION RegionGrow::popseed
 40   seed = (*(self._seeds))[self._ifront];
 41   self._ifront = self._ifront + 1;
 42   RETURN, seed;
 43 END
 44 
 45 PRO RegionGrow::pushseed, index
 46    (self._hseeds)[index] = 0;
 47    (*(self._seeds))[self._iback] = index;
 48    self._iback = self._iback + 1;
 49 END
 50 
 51 FUNCTION RegionGrow::grow
 52     
 53     growImg = make_array(self._width, self._height, /BYTE, VALUE=0);
 54      k = 0;
 55     WHILE (self->hasseeds()) DO BEGIN
 56        k = k+1;
 57        ;print,"==========================>", k;
 58        seed = self->popseed();
 59        i = FLOOR(seed / self._width);
 60        j = seed - i * self._width;
 61        growImg[j,i] = 255;
 62        
 63        ;;;;;LEFT
 64        index = seed - 1;
 65        IF (j-1 GE 0) && (self->isnotseed(index)) && self->isgrowable((*(self._region))[j-1,i]) THEN BEGIN
 66          self->pushseed, index;
 67        ENDIF
 68        
 69        ;;;;;RIGHT
 70        index = seed + 1;
 71        IF ((j+1) LT self._width) && (self->isnotseed(index)) && self->isgrowable((*(self._region))[j+1,i]) THEN BEGIN
 72          self->pushseed, index;
 73        ENDIF
 74        
 75        ;;;;;UP
 76        index = seed + self._width;
 77        IF ((i+1) LT self._height) && (self->isnotseed(index)) && self->isgrowable((*(self._region))[j,i+1]) THEN BEGIN
 78          self->pushseed, index;
 79        ENDIF
 80        
 81        ;;;;;DOWN
 82        index = seed - self._width;
 83        IF ((i-1) GE 0) && (self->isnotseed(index)) && self->isgrowable((*(self._region))[j,i-1]) THEN BEGIN
 84          self->pushseed, index;
 85        ENDIF
 86        
 87     ENDWHILE
 88     
 89     RETURN, growImg
 90     
 91 END
 92 
 93 PRO RegionGrow::cleanup
 94   
 95   *(self._region) = !NULL;
 96   
 97   PTR_FREE, self._seeds;
 98   
 99   DELVAR, self._seeds;
100   DELVAR, self._hseeds;
101   
102   RETURN
103 END
104 
105 PRO RegionGrow__define
106 
107   struct = {RegionGrow, _region:PTR_NEW(), _seeds:PTR_NEW(), _hseeds:HASH(), _ifront:0L, _iback:0L, _width:0L, _height:0L, _mint:0, _maxt:0}
108   RETURN
109 END

 

    区域增长测试主函数文件Region.pro

 1 PRO Region
 2   grayIMG = READ_TIFF('D:\ndvi.tif');
 3   ;help, grayImg
 4   seeds = WHERE(grayImg EQ 221);
 5   
 6   executer = OBJ_NEW("RegionGrow", REGION=grayImg, SEEDS=seeds);
 7   executer.setthreshold,186,230;
 8   st = SYSTIME(1);
 9   result = executer.grow();
10   et = SYSTIME(1);
11   HELP, result;
12   print, "=====================>time: ", (et-st);
13   ;im = IMAGE(result);
14   
15   gr = MAKE_ARRAY(3, 2048, 1024, /BYTE, VALUE=0);
16   gr[0,*,*] = result[*,*];
17   gr[1,*,*] = result[*,*];
18   gr[2,*,*] = result[*,*];
19   WRITE_JPEG, "grow.jpg", gr, /TRUE
20 END

 

测试分割水体结果如下:

    区域增长水体分割

 

posted @ 2015-07-25 00:35  walle搬砖  阅读(2858)  评论(0编辑  收藏  举报