segmentFelzenszwalb.cpp 7.7 KB

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