segmentFelzenszwalb.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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. sigma = mxGetScalar( pInput[1] );
  73. if ( verbose )
  74. mexPrintf("The sigma value is: %f\n", sigma);
  75. /* Get k */
  76. int k = mxGetScalar( pInput[2] );
  77. if ( verbose )
  78. mexPrintf("The k is: %i\n", k);
  79. /* Get minSize*/
  80. int minSize = mxGetScalar( pInput[3] );
  81. if ( verbose )
  82. mexPrintf("The minSize is: %i\n", minSize);
  83. /* Get string of output image if given*/
  84. char * output;
  85. if (nInput >= 5)
  86. {
  87. output = (char *) mxCalloc(mxGetN(pInput[4])+1, sizeof(char));
  88. mxGetString(pInput[4], output, mxGetN(pInput[4])+1);
  89. if ( verbose )
  90. mexPrintf("The output string is: %s\n", output);
  91. }
  92. if ( verbose )
  93. mexPrintf("image loaded, now start segmentation\n");
  94. /* -----------------------------------------------------------------
  95. * Do the main stuff
  96. * >segmentation<
  97. * -------------------------------------------------------------- */
  98. int num_ccs;
  99. image<rgb> * imgResult = segment_image(imgInput, sigma, k, minSize, &num_ccs);
  100. if ( verbose )
  101. mexPrintf("segmentation done\n");
  102. /* -----------------------------------------------------------------
  103. * Conversion to Matlab structures
  104. * -------------------------------------------------------------- */
  105. if ( nOutput == 0 )
  106. {
  107. savePPM( imgResult, output );
  108. mexPrintf("save results\n");
  109. }
  110. else
  111. {
  112. mexPrintf("convert to matlab structure and hand result back to main program\n");
  113. /* convert segmentation result to matlax matrix*/
  114. int width ( imgResult->width() );
  115. int height (imgResult->height() );
  116. int numberOfPixels ( width * height * sizeof(rgb) );
  117. if ( verbose )
  118. mexPrintf("The number of Pixel in your resulting image is: %i -- summing over all color channels\n", numberOfPixels);
  119. /*if ( verbose )*/
  120. mexPrintf(" width: %i, height: %i\n", width, height);
  121. /* keep in mind that matlab stores images height × width × color, whereas C does it the other way round*/
  122. int dims[] = {height, width,3};
  123. pOutput[0] = mxCreateNumericArray (3, dims, mxUINT8_CLASS, mxREAL);
  124. unsigned char *out1; /* pointer to output 1 */
  125. out1 = (unsigned char *)mxGetPr( pOutput[0] ); /* pointer to output 1 */
  126. /* start with RED channel*/
  127. /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
  128. for ( uint x = 0; x < width; x++)
  129. {
  130. uint rowOffset ( x*height );
  131. for ( uint y = 0; y < height; y++)
  132. {
  133. out1[rowOffset + y ] = (double) (imRef(imgResult, x, y)).r;
  134. }
  135. }
  136. /* GREEN channel*/
  137. uint channelOffsetG ( width * height );
  138. for ( uint x = 0; x < width; x++)
  139. {
  140. uint rowOffset ( x*height );
  141. for ( uint y = 0; y < height; y++)
  142. {
  143. out1[channelOffsetG + rowOffset + y ] = (double) (imRef(imgResult, x, y)).g;
  144. }
  145. }
  146. /* BLUE channel*/
  147. uint channelOffsetB ( 2 * width * height );
  148. for ( uint x = 0; x < width; x++)
  149. {
  150. uint rowOffset ( x*height );
  151. for ( uint y = 0; y < height; y++)
  152. {
  153. out1[channelOffsetB + rowOffset + y ] = (double) (imRef(imgResult, x, y)).b;
  154. }
  155. }
  156. /* done */
  157. }
  158. /* don't waste memory*/
  159. if ( imgInput != NULL )
  160. delete imgInput;
  161. return;
  162. }