图像分割-区域增长算法及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
测试分割水体结果如下: