segmentFelzenszwalb.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <mex.h>
  5. #include "./image.h"
  6. #include "./misc.h"
  7. #include "./pnmfile.h"
  8. #include "./image.h"
  9. #include "./segment-image.h"
  10. #include "./segment-image-labelOutput.h"
  11. #ifndef MIN
  12. #define MIN(x, y) (((x) < (y)) ? (x) : (y)) /* min and max value macros */
  13. #endif
  14. #ifndef MAX
  15. #define MAX(x, y) (((x) > (y)) ? (x) : (y))
  16. #endif
  17. void mexFunction(int nOutput, mxArray *pOutput[], /* Output variables */
  18. int nInput, const mxArray *pInput[]) /* Input variables */
  19. {
  20. /* -----------------------------------------------------------------
  21. * Check the arguments
  22. * -------------------------------------------------------------- */
  23. if (nInput < 1) {
  24. mexErrMsgTxt ( "To few input arguments.");
  25. return;
  26. }
  27. if (nOutput > 2) {
  28. mexErrMsgTxt ( "Too many output arguments.");
  29. return;
  30. }
  31. if ( (nOutput == 0) && (nInput < 5) ) {
  32. mexErrMsgTxt ( "No destination for segmentation result specified - chose either return value or string for destination!");
  33. return;
  34. }
  35. /* -----------------------------------------------------------------
  36. * Get the arguments
  37. * -------------------------------------------------------------- */
  38. bool b_verbose ( false );
  39. if ( nInput >= 7)
  40. {
  41. if ( mxIsLogicalScalar( pInput[6] ) && mxIsLogicalScalarTrue( pInput[6] ) )
  42. {
  43. b_verbose = true;
  44. }
  45. else
  46. b_verbose = false;
  47. }
  48. /* Get string of input image*/
  49. image<rgb> * imgInput;
  50. /* was the input image given as a string?*/
  51. if ( mxGetM( pInput[0] ) == 1 )
  52. {
  53. char *input;
  54. input = (char *) mxCalloc( mxGetN(pInput[0] )+1, sizeof(char) );
  55. mxGetString(pInput[0], input, mxGetN( pInput[0] )+1);
  56. if ( b_verbose )
  57. mexPrintf("The input string is: %s\n", input);
  58. imgInput = loadPPM( input );
  59. mxFree ( input );
  60. }
  61. /* the image was directly passed as matlab matrix*/
  62. else
  63. {
  64. /*double * imgInputMatlab = mxGetPr( pInput[0] );*/
  65. signed char* imgInputMatlab = (signed char *)mxGetData( pInput[0] );
  66. size_t K = mxGetNumberOfDimensions( pInput[0] );
  67. const mwSize *N = mxGetDimensions( pInput[0] );
  68. uint height ( N[0] ); // matlab gives first height
  69. uint width ( N[1] ); // matlab gives then width
  70. imgInput = new image<rgb>( width, height, 0 );
  71. /* start with RED channel*/
  72. /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
  73. for ( uint y = 0; y < height; y++)
  74. {
  75. for ( uint x = 0; x < width; x++)
  76. {
  77. imRef(imgInput, x, y).r = imgInputMatlab[y + height*(x + width*0) ];
  78. imRef(imgInput, x, y).g = imgInputMatlab[y + height*(x + width*1) ];
  79. imRef(imgInput, x, y).b = imgInputMatlab[y + height*(x + width*2) ];
  80. }
  81. }
  82. }
  83. char buf [1024] ;
  84. /* Get sigma */
  85. double d_sigma;
  86. if ( nInput < 2)
  87. {
  88. d_sigma = 0.5;
  89. }
  90. else
  91. d_sigma = mxGetScalar( pInput[1] );
  92. if ( b_verbose )
  93. mexPrintf("The sigma value is: %f\n", d_sigma);
  94. /* Get k */
  95. int i_k;
  96. if ( nInput < 3)
  97. {
  98. i_k = 500;
  99. }
  100. else
  101. i_k = mxGetScalar( pInput[2] );
  102. if ( b_verbose )
  103. mexPrintf("The k is: %i\n", i_k);
  104. /* Get minSize*/
  105. int i_minSize;
  106. if ( nInput < 4)
  107. {
  108. i_minSize = 50;
  109. }
  110. else
  111. i_minSize = mxGetScalar( pInput[3] );
  112. if ( b_verbose )
  113. mexPrintf("The minSize is: %i\n", i_minSize);
  114. /* Get bool whether to compute the label img (int) or colored img (rgb)*/
  115. bool b_computeColorOutput;
  116. if (nInput >= 5)
  117. {
  118. if ( mxIsLogicalScalar( pInput[4] ) && mxIsLogicalScalarTrue( pInput[4] ) )
  119. {
  120. b_computeColorOutput = true;
  121. }
  122. else
  123. b_computeColorOutput = false;
  124. }
  125. else
  126. {
  127. b_computeColorOutput = false;
  128. }
  129. if ( b_verbose )
  130. mexPrintf("To we compute RGB colored segmentation result? : %i\n", b_computeColorOutput );
  131. /* Get string of output image if given*/
  132. char * output;
  133. if (nInput >= 6)
  134. {
  135. output = (char *) mxCalloc(mxGetN(pInput[5])+1, sizeof(char));
  136. mxGetString(pInput[5], output, mxGetN(pInput[5])+1);
  137. if ( b_verbose )
  138. mexPrintf("The output string is: %s\n", output);
  139. }
  140. if ( b_verbose )
  141. mexPrintf("image loaded, now start segmentation\n");
  142. /* -----------------------------------------------------------------
  143. * Do the main stuff
  144. * >segmentation<
  145. * -------------------------------------------------------------- */
  146. int num_ccs;
  147. image<rgb> * imgResultRGB = NULL;
  148. image<unsigned short> * imgResult = NULL;
  149. if ( b_computeColorOutput )
  150. {
  151. imgResultRGB = segment_image(imgInput, d_sigma, i_k, i_minSize, &num_ccs);
  152. }
  153. else
  154. {
  155. imgResult = segment_image_labelOutput(imgInput, d_sigma, i_k, i_minSize, &num_ccs);
  156. }
  157. if ( b_verbose )
  158. mexPrintf("segmentation done\n");
  159. /* -----------------------------------------------------------------
  160. * Conversion to Matlab structures
  161. * -------------------------------------------------------------- */
  162. if ( nOutput == 0 )
  163. {
  164. //was a filename given to store the image in?
  165. if (nInput >= 6)
  166. {
  167. if ( b_computeColorOutput )
  168. savePPM( imgResultRGB, output );
  169. else
  170. save_image( imgResult, output );
  171. mexPrintf("save results\n");
  172. }
  173. else
  174. {
  175. mexPrintf("ATTENTION -- Neither output variables nor filename to store the result to given!");
  176. }
  177. }
  178. else
  179. {
  180. if ( b_verbose )
  181. mexPrintf("convert to matlab structure and hand result back to main program\n");
  182. /* convert segmentation result to matlab matrix*/
  183. if ( b_computeColorOutput )
  184. {
  185. int width ( imgResultRGB->width() );
  186. int height (imgResultRGB->height() );
  187. /* keep in mind that matlab stores images height × width × color, whereas C does it the other way round*/
  188. int dims[] = {height, width,3};
  189. pOutput[0] = mxCreateNumericArray (3, dims, mxUINT8_CLASS, mxREAL);
  190. //unsigned char *out1; /* pointer to output 1 */
  191. //out1 = (unsigned char *)mxGetPr( pOutput[0] ); /* pointer to output 1 */
  192. //unsigned char *out1; /* pointer to output 1 */
  193. //out1 = (unsigned char *)mxGetPr( pOutput[0] ); /* pointer to output 1 */
  194. unsigned char *out1; /* pointer to output 1 */
  195. out1 = (unsigned char *)mxGetData( pOutput[0] ); /* pointer to output 1 *
  196. /* start with RED channel*/
  197. /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
  198. for ( uint x = 0; x < width; x++)
  199. {
  200. uint rowOffset ( x*height );
  201. for ( uint y = 0; y < height; y++)
  202. {
  203. out1[rowOffset + y ] = (unsigned char) (imRef(imgResultRGB, x, y)).r;
  204. }
  205. }
  206. /* GREEN channel*/
  207. uint channelOffsetG ( width * height );
  208. for ( uint x = 0; x < width; x++)
  209. {
  210. uint rowOffset ( x*height );
  211. for ( uint y = 0; y < height; y++)
  212. {
  213. out1[channelOffsetG + rowOffset + y ] = (unsigned char) (imRef(imgResultRGB, x, y)).g;
  214. }
  215. }
  216. /* BLUE channel*/
  217. uint channelOffsetB ( 2 * width * height );
  218. for ( uint x = 0; x < width; x++)
  219. {
  220. uint rowOffset ( x*height );
  221. for ( uint y = 0; y < height; y++)
  222. {
  223. out1[channelOffsetB + rowOffset + y ] = (unsigned char) (imRef(imgResultRGB, x, y)).b;
  224. }
  225. }
  226. }
  227. else /* do not compute colored rgb segmentation image, but only an unsigned short-int img*/
  228. {
  229. int width ( imgResult->width() );
  230. int height (imgResult->height() );
  231. int dims[] = {height, width};
  232. if (num_ccs < 255)
  233. {
  234. pOutput[0] = mxCreateNumericArray (2, dims, mxUINT8_CLASS, mxREAL);
  235. unsigned char *out1; /* pointer to output 1 */
  236. out1 = (unsigned char *)mxGetPr( pOutput[0] ); /* pointer to output 1 */
  237. /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
  238. for ( uint x = 0; x < width; x++)
  239. {
  240. uint rowOffset ( x*height );
  241. for ( uint y = 0; y < height; y++)
  242. {
  243. out1[rowOffset + y ] = (unsigned char) (imRef(imgResult, x, y));
  244. }
  245. }
  246. }
  247. else
  248. {
  249. pOutput[0] = mxCreateNumericArray (2, dims, mxUINT16_CLASS, mxREAL);
  250. unsigned short *out1; /* pointer to output 1 */
  251. out1 = (unsigned short *)mxGetData( pOutput[0] ); /* pointer to output 1 *
  252. /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
  253. for ( uint x = 0; x < width; x++)
  254. {
  255. uint rowOffset ( x*height );
  256. for ( uint y = 0; y < height; y++)
  257. {
  258. out1[rowOffset + y ] = (unsigned short) (imRef(imgResult, x, y));
  259. }
  260. }
  261. }
  262. }
  263. /* return number of segments*/
  264. if ( nOutput >= 2 )
  265. {
  266. int dims[] = {1};
  267. if (num_ccs < 255)
  268. {
  269. pOutput[1] = mxCreateNumericArray(1,dims,mxUINT8_CLASS,mxREAL);
  270. unsigned char *out2; /* pointer to output 2 */
  271. out2 = (unsigned char *)mxGetPr( pOutput[1] ); /* pointer to output 2 */
  272. out2[0] = num_ccs;
  273. }
  274. else
  275. {
  276. pOutput[1] = mxCreateNumericArray(1,dims,mxINT16_CLASS,mxREAL);
  277. //unsigned char *out2; /* pointer to output 2 */
  278. //out2 = (unsigned char *)mxGetPr( pOutput[1] ); /* pointer to output 2 */
  279. unsigned short *out2; /* pointer to output 2 */
  280. out2 = (unsigned short *) mxGetData( pOutput[1] ); /* pointer to output 2 */
  281. out2[0] = num_ccs;
  282. }
  283. if ( b_verbose )
  284. mexPrintf("number of components: %i", num_ccs);
  285. }
  286. /* done */
  287. }
  288. /* don't waste memory*/
  289. if ( imgInput != NULL )
  290. delete imgInput;
  291. if ( imgResultRGB != NULL )
  292. delete imgResultRGB;
  293. if ( imgResult != NULL )
  294. delete imgResult;
  295. return;
  296. }