RegionSegmentationMethod.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #include "RegionSegmentationMethod.h"
  2. #include <core/image/CrossT.h>
  3. #include <core/image/LineT.h>
  4. #include <core/image/CircleT.h>
  5. #include <core/imagedisplay/ImageDisplay.h>
  6. using namespace OBJREC;
  7. using namespace NICE;
  8. using namespace std;
  9. RegionSegmentationMethod::RegionSegmentationMethod()
  10. {
  11. }
  12. RegionSegmentationMethod::RegionSegmentationMethod ( const Config *c )
  13. {
  14. conf = c;
  15. }
  16. RegionSegmentationMethod::~RegionSegmentationMethod()
  17. {
  18. }
  19. //überprüfe, ob Elterpixel neugelabelt wurde, wenn ja dann label auch Kind neu
  20. inline int rootOf ( int *l, int j )
  21. {
  22. while ( l[j] != j ) {
  23. // short path compression
  24. l[j] = l[l[j]];
  25. j = l[j];
  26. }
  27. return j;
  28. }
  29. int RegionSegmentationMethod::transformSegmentedImg ( const NICE::ColorImage & img, NICE::Matrix & mask ) const
  30. {
  31. int xsize = img.width();
  32. int ysize = img.height();
  33. int n = xsize * ysize;
  34. int *l = new int[n];
  35. int v[3], vo[3];
  36. int j = 0;
  37. for ( int y = 0 ; y < ysize ; y++ ) // horizontal
  38. {
  39. l[j] = j;
  40. vo[0] = img.getPixel ( 0, y, 2 );
  41. vo[1] = img.getPixel ( 0, y, 0 );
  42. vo[2] = img.getPixel ( 0, y, 1 );
  43. j++;
  44. for ( int x = 1 ; x < xsize ; x++, j++ )
  45. {
  46. v[0] = img.getPixel ( x, y, 2 );
  47. v[1] = img.getPixel ( x, y, 0 );
  48. v[2] = img.getPixel ( x, y, 1 );
  49. if ( v[0] == vo[0] && v[1] == vo[1] && v[2] == vo[2] )
  50. {
  51. l[j] = l[j-1];
  52. }
  53. else
  54. {
  55. l[j] = j;
  56. }
  57. vo[0] = v[0];
  58. vo[1] = v[1];
  59. vo[2] = v[2];
  60. }
  61. }
  62. j = 0;
  63. for ( int x = 0 ; x < xsize ; x++ ) //vertikal
  64. {
  65. vo[0] = img.getPixel ( x, 0, 2 );
  66. vo[1] = img.getPixel ( x, 0, 0 );
  67. vo[2] = img.getPixel ( x, 0, 1 );
  68. for ( int y = 1 ; y < ysize ; y++ )
  69. {
  70. j = y * ( xsize ) + x;
  71. v[0] = img.getPixel ( x, y, 2 );
  72. v[1] = img.getPixel ( x, y, 0 );
  73. v[2] = img.getPixel ( x, y, 1 );
  74. if ( v[0] == vo[0] && v[1] == vo[1] && v[2] == vo[2] ) {
  75. int rj = rootOf ( l, j );
  76. int rn = rootOf ( l, j - xsize );
  77. if ( rj != rn ) {
  78. l[rj] = rn;
  79. }
  80. }
  81. vo[0] = v[0];
  82. vo[1] = v[1];
  83. vo[2] = v[2];
  84. }
  85. }
  86. j = 0;
  87. for ( int x = 1 ; x < xsize ; x++ ) //links oben
  88. {
  89. vo[0] = img.getPixel ( x - 1, 0, 2 );
  90. vo[1] = img.getPixel ( x - 1, 0, 0 );
  91. vo[2] = img.getPixel ( x - 1, 0, 1 );
  92. for ( int y = 1 ; y < ysize ; y++ )
  93. {
  94. j = y * ( xsize ) + x;
  95. v[0] = img.getPixel ( x, y, 2 );
  96. v[1] = img.getPixel ( x, y, 0 );
  97. v[2] = img.getPixel ( x, y, 1 );
  98. if ( v[0] == vo[0] && v[1] == vo[1] && v[2] == vo[2] ) {
  99. int rj = rootOf ( l, j );
  100. int rn = rootOf ( l, j - xsize - 1 );
  101. if ( rj != rn ) {
  102. l[rj] = rn;
  103. }
  104. }
  105. vo[0] = img.getPixel ( x - 1, y, 2 );
  106. vo[1] = img.getPixel ( x - 1, y, 0 );
  107. vo[2] = img.getPixel ( x - 1, y, 1 );
  108. }
  109. }
  110. j = 0;
  111. for ( int x = xsize - 2 ; x >= 0 ; x-- ) //rechts oben
  112. {
  113. vo[0] = img.getPixel ( x + 1, 0, 2 );
  114. vo[1] = img.getPixel ( x + 1, 0, 0 );
  115. vo[2] = img.getPixel ( x + 1, 0, 1 );
  116. for ( int y = 1 ; y < ysize ; y++ )
  117. {
  118. j = y * ( xsize ) + x;
  119. v[0] = img.getPixel ( x, y, 2 );
  120. v[1] = img.getPixel ( x, y, 0 );
  121. v[2] = img.getPixel ( x, y, 1 );
  122. if ( v[0] == vo[0] && v[1] == vo[1] && v[2] == vo[2] ) {
  123. int rj = rootOf ( l, j );
  124. int rn = rootOf ( l, j - xsize + 1 );
  125. if ( rj != rn ) {
  126. l[rj] = rn;
  127. }
  128. }
  129. vo[0] = img.getPixel ( x + 1, y, 2 );
  130. vo[1] = img.getPixel ( x + 1, y, 0 );
  131. vo[2] = img.getPixel ( x + 1, y, 1 );
  132. }
  133. }
  134. int size = 0;
  135. // relabel
  136. std::map<int, int> bijection;
  137. for ( j = 0 ; j < n ; j++ )
  138. {
  139. if ( l[j] == j ) {
  140. bijection[j] = size;
  141. size++;
  142. }
  143. }
  144. if ( size <= 0 ) {
  145. fprintf ( stderr, "RegionSegmentationMethod:: no components of this color found !!\n" );
  146. return -1;
  147. }
  148. mask.resize ( xsize, ysize );
  149. for ( j = 0 ; j < n ; j++ )
  150. {
  151. int label = rootOf ( l, j );
  152. int x = j % ( xsize );
  153. int y = j / ( xsize );
  154. mask ( x, y ) = bijection[label];
  155. }
  156. delete [] l;
  157. return size;
  158. }
  159. void RegionSegmentationMethod::getGraphRepresentation ( const NICE::ColorImage & cimg, NICE::Matrix & mask, RegionGraph & rg )
  160. {
  161. int regioncount = segRegions ( cimg, mask );
  162. rg.computeGraph ( mask, regioncount );
  163. }
  164. int RegionSegmentationMethod::segRegions ( const NICE::ColorImage & cimg, NICE::Matrix & mask ) const
  165. {
  166. Image img ( cimg.width(), cimg.height() );
  167. for ( int y = 0; y < cimg.height(); y++ )
  168. {
  169. for ( int x = 0; x < cimg.width(); x++ )
  170. {
  171. int val = 0;
  172. for ( int i = 0; i < 3; i++ )
  173. val += cimg.getPixel ( x, y, i );
  174. val /= 3;
  175. img.setPixel ( x, y, val );
  176. }
  177. }
  178. cerr << "no color segmentation method, using grayimage segmentation instead" << endl;
  179. return segRegions ( img, mask );
  180. }
  181. int RegionSegmentationMethod::segRegions (
  182. const NICE::MultiChannelImage3DT<double> & img,
  183. NICE::MultiChannelImageT<int> & mask,
  184. const int isGray
  185. ) const
  186. {
  187. const int xsize = img.width();
  188. const int ysize = img.height();
  189. const int zsize = img.depth();
  190. int amountRegions = -1;
  191. mask.reInit( xsize, ysize, zsize );
  192. for (int z = 0; z < zsize; z++)
  193. {
  194. NICE::Matrix reg;
  195. int aR;
  196. if ( isGray )
  197. {
  198. NICE::Image slice = img.getChannel(z);
  199. aR = segRegions( slice, reg );
  200. } else {
  201. NICE::ColorImage slice = img.getColor(z);
  202. aR = segRegions( slice, reg );
  203. }
  204. if ( aR > amountRegions ) amountRegions = aR;
  205. for (int y = 0; y < ysize; y++)
  206. {
  207. for (int x = 0; x < xsize; x++)
  208. {
  209. mask.set( x, y, reg(x,y), (uint)z );
  210. }
  211. }
  212. }
  213. return amountRegions;
  214. }
  215. void RegionSegmentationMethod::markContours ( const NICE::ColorImage & cimg, NICE::Matrix & mask, std::vector<int> &color, NICE::ColorImage &marked )
  216. {
  217. // mark contours
  218. for ( int y = 1; y < cimg.height() - 1; y++ )
  219. {
  220. for ( int x = 1; x < cimg.width() - 1; x++ )
  221. {
  222. bool diff = false;
  223. for ( int i = -1; i < 2; i++ )
  224. {
  225. for ( int j = -1; j < 2; j++ )
  226. {
  227. if ( mask ( x, y ) != mask ( x + i, y + j ) )
  228. diff = true;
  229. }
  230. if ( diff )
  231. break;
  232. }
  233. if ( diff )
  234. {
  235. for(int c = 0; c < 3; c++)
  236. marked.setPixel ( x, y, c, color[c] );
  237. }
  238. else
  239. {
  240. for(int c = 0; c < 3; c++)
  241. marked.setPixel ( x, y, c, cimg.getPixel(x,y,c) );
  242. }
  243. }
  244. }
  245. }
  246. void RegionSegmentationMethod::visualizeGraphRepresentation ( const NICE::ColorImage & cimg, NICE::Matrix & mask )
  247. {
  248. RegionGraph rg;
  249. getGraphRepresentation ( cimg, mask, rg );
  250. vector<Node*> g;
  251. rg.get ( g );
  252. Image overlay ( cimg.width(), cimg.height() );
  253. overlay.set ( 0 );
  254. // mark contours
  255. for ( int y = 1; y < cimg.height() - 1; y++ )
  256. {
  257. for ( int x = 1; x < cimg.width() - 1; x++ )
  258. {
  259. bool diff = false;
  260. for ( int i = -1; i < 2; i++ )
  261. {
  262. for ( int j = -1; j < 2; j++ )
  263. {
  264. if ( mask ( x, y ) != mask ( x + i, y + j ) )
  265. diff = true;
  266. }
  267. if ( diff )
  268. break;
  269. }
  270. if ( diff )
  271. overlay.setPixel ( x, y, 3 );
  272. }
  273. }
  274. // mark graph
  275. for ( int i = 0 ; i < ( int ) g.size() ; i++ )
  276. {
  277. int x, y;
  278. g[i]->getCentroid ( x, y );
  279. Cross cross ( Coord ( x, y ) , 7 );
  280. overlay.draw ( cross, 1 );
  281. vector<Node*> nb;
  282. g[i]->getNeighbors ( nb );
  283. for ( int j = 0; j < ( int ) nb.size(); j++ )
  284. {
  285. int xn, yn;
  286. nb[j]->getCentroid ( xn, yn );
  287. Line line ( Coord ( x, y ), Coord ( xn, yn ) );
  288. overlay.draw ( line, 2 );
  289. }
  290. }
  291. showImageOverlay ( cimg, overlay, "Regions" );
  292. }