RegionSegmentationMethod.cpp 8.1 KB

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