segmentFelzenszwalb.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. void mexFunction(int nOutput, mxArray *pOutput[], /* Output variables */
  11. int nInput, const mxArray *pInput[]) /* Input variables */
  12. {
  13. mexPrintf("Let's run the segmentation program of Felzenszwalb and Huttenlocher :) !\n");
  14. /* -----------------------------------------------------------------
  15. * Check the arguments
  16. * -------------------------------------------------------------- */
  17. if (nInput < 1) {
  18. mexErrMsgTxt ( "To few input arguments.");
  19. return;
  20. }
  21. if (nOutput > 1) {
  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 >= 6)
  34. verbose = mxGetLogicals( pInput[5] );
  35. /* Get string of input image*/
  36. image<rgb> * imgInput;
  37. /* was the input image given as a string?*/
  38. if ( mxGetM( pInput[0] ) == 1 )
  39. {
  40. char *input;
  41. input = (char *) mxCalloc( mxGetN(pInput[0] )+1, sizeof(char) );
  42. mxGetString(pInput[0], input, mxGetN( pInput[0] )+1);
  43. if ( verbose )
  44. mexPrintf("The input string is: %s\n", input);
  45. imgInput = loadPPM( input );
  46. }
  47. /* the image was directly passed as matlab matrix*/
  48. else
  49. {
  50. /*double * imgInputMatlab = mxGetPr( pInput[0] );*/
  51. signed char* imgInputMatlab = (signed char *)mxGetData( pInput[0] );
  52. size_t K = mxGetNumberOfDimensions( pInput[0] );
  53. const mwSize *N = mxGetDimensions( pInput[0] );
  54. uint width ( N[0] );
  55. uint height ( N[1] );
  56. imgInput = new image<rgb>( height, width, 0 );
  57. /* start with RED channel*/
  58. /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
  59. for ( uint y = 0; y < width; y++)
  60. {
  61. for ( uint x = 0; x < height; x++)
  62. {
  63. imRef(imgInput, x, y).r = imgInputMatlab[y + width*(x + height*0) ];
  64. imRef(imgInput, x, y).g = imgInputMatlab[y + width*(x + height*1) ];
  65. imRef(imgInput, x, y).b = imgInputMatlab[y + width*(x + height*2) ];
  66. }
  67. }
  68. }
  69. char buf [1024] ;
  70. /* Get sigma */
  71. double sigma;
  72. if ( nInput < 2)
  73. {
  74. sigma = 0.5;
  75. }
  76. else
  77. sigma = mxGetScalar( pInput[1] );
  78. if ( verbose )
  79. mexPrintf("The sigma value is: %f\n", sigma);
  80. /* Get k */
  81. int k;
  82. if ( nInput < 3)
  83. {
  84. k = 500;
  85. }
  86. else
  87. k = mxGetScalar( pInput[2] );
  88. if ( verbose )
  89. mexPrintf("The k is: %i\n", k);
  90. /* Get minSize*/
  91. int minSize;
  92. if ( nInput < 4)
  93. {
  94. minSize = 20;
  95. }
  96. else
  97. minSize = mxGetScalar( pInput[3] );
  98. if ( verbose )
  99. mexPrintf("The minSize is: %i\n", minSize);
  100. /* Get string of output image if given*/
  101. char * output;
  102. if (nInput >= 5)
  103. {
  104. output = (char *) mxCalloc(mxGetN(pInput[4])+1, sizeof(char));
  105. mxGetString(pInput[4], output, mxGetN(pInput[4])+1);
  106. if ( verbose )
  107. mexPrintf("The output string is: %s\n", output);
  108. }
  109. if ( verbose )
  110. mexPrintf("image loaded, now start segmentation\n");
  111. /* -----------------------------------------------------------------
  112. * Do the main stuff
  113. * >segmentation<
  114. * -------------------------------------------------------------- */
  115. int num_ccs;
  116. image<rgb> * imgResult = segment_image(imgInput, sigma, k, minSize, &num_ccs);
  117. if ( verbose )
  118. mexPrintf("segmentation done\n");
  119. /* -----------------------------------------------------------------
  120. * Conversion to Matlab structures
  121. * -------------------------------------------------------------- */
  122. if ( nOutput == 0 )
  123. {
  124. savePPM( imgResult, output );
  125. mexPrintf("save results\n");
  126. }
  127. else
  128. {
  129. mexPrintf("convert to matlab structure and hand result back to main program\n");
  130. /* convert segmentation result to matlax matrix*/
  131. int width ( imgResult->width() );
  132. int height (imgResult->height() );
  133. int numberOfPixels ( width * height * sizeof(rgb) );
  134. if ( verbose )
  135. mexPrintf("The number of Pixel in your resulting image is: %i -- summing over all color channels\n", numberOfPixels);
  136. /*if ( verbose )*/
  137. mexPrintf(" width: %i, height: %i\n", width, height);
  138. /* keep in mind that matlab stores images height × width × color, whereas C does it the other way round*/
  139. int dims[] = {height, width,3};
  140. pOutput[0] = mxCreateNumericArray (3, dims, mxUINT8_CLASS, mxREAL);
  141. unsigned char *out1; /* pointer to output 1 */
  142. out1 = (unsigned char *)mxGetPr( pOutput[0] ); /* pointer to output 1 */
  143. /* start with RED channel*/
  144. /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
  145. for ( uint x = 0; x < width; x++)
  146. {
  147. uint rowOffset ( x*height );
  148. for ( uint y = 0; y < height; y++)
  149. {
  150. out1[rowOffset + y ] = (double) (imRef(imgResult, x, y)).r;
  151. }
  152. }
  153. /* GREEN channel*/
  154. uint channelOffsetG ( width * height );
  155. for ( uint x = 0; x < width; x++)
  156. {
  157. uint rowOffset ( x*height );
  158. for ( uint y = 0; y < height; y++)
  159. {
  160. out1[channelOffsetG + rowOffset + y ] = (double) (imRef(imgResult, x, y)).g;
  161. }
  162. }
  163. /* BLUE channel*/
  164. uint channelOffsetB ( 2 * width * height );
  165. for ( uint x = 0; x < width; x++)
  166. {
  167. uint rowOffset ( x*height );
  168. for ( uint y = 0; y < height; y++)
  169. {
  170. out1[channelOffsetB + rowOffset + y ] = (double) (imRef(imgResult, x, y)).b;
  171. }
  172. }
  173. /* done */
  174. }
  175. /* don't waste memory*/
  176. if ( imgInput != NULL )
  177. delete imgInput;
  178. return;
  179. }