瀏覽代碼

initial version of mex interface for felzenszwalb segm

Alexander Freytag 12 年之前
當前提交
836d1e0baa
共有 2 個文件被更改,包括 232 次插入0 次删除
  1. 204 0
      segmentFelzenszwalb.cpp
  2. 28 0
      segmentFelzenszwalb.m

+ 204 - 0
segmentFelzenszwalb.cpp

@@ -0,0 +1,204 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <mex.h>
+
+#include "./image.h"
+#include "./misc.h"
+#include "./pnmfile.h"
+#include "./image.h"
+#include "./segment-image.h"
+
+void mexFunction(int nOutput, mxArray *pOutput[], /* Output variables */
+  int nInput, const mxArray *pInput[]) /* Input variables */
+{
+  mexPrintf("Let's run the segmentation program of Felzenszwalb and Huttenlocher :) !\n"); 
+    
+   /* -----------------------------------------------------------------
+   *                         Check the arguments
+   * -------------------------------------------------------------- */
+
+  if (nInput < 1) {
+    mexErrMsgTxt ( "To few input arguments.");
+    return;
+  }
+  
+  if (nOutput > 1) {
+    mexErrMsgTxt ( "Too many output arguments.");
+    return;
+  }
+  
+  if ( (nOutput == 0) && (nInput < 5) ) {
+    mexErrMsgTxt ( "No destination for segmentation result specified - chose either return value or string for destination!");
+    return;
+  }  
+  
+  
+   /* -----------------------------------------------------------------
+   *                      Get the arguments
+   * -------------------------------------------------------------- */  
+  
+   bool verbose ( false );
+   if ( nInput >= 6)
+    verbose = mxGetLogicals( pInput[5] );
+   
+  /* Get string of input image*/  
+  image<rgb> * imgInput;
+  
+  /* was the input image given as a string?*/ 
+  if ( mxGetM( pInput[0] ) == 1 )
+  {
+    char *input;     
+    input = (char *) mxCalloc( mxGetN(pInput[0] )+1, sizeof(char) );
+    mxGetString(pInput[0], input, mxGetN( pInput[0] )+1);
+    if ( verbose ) 
+      mexPrintf("The input string is:  %s\n", input);    
+    
+    imgInput = loadPPM( input );
+  }
+  /* the image was directly passed as matlab matrix*/ 
+  else
+  {    
+    /*double * imgInputMatlab = mxGetPr( pInput[0] );*/
+    signed char* imgInputMatlab = (signed char *)mxGetData( pInput[0] );
+    
+    size_t K = mxGetNumberOfDimensions(  pInput[0] );
+    const mwSize *N = mxGetDimensions(  pInput[0] );
+    
+    uint width  ( N[0] );
+    uint height ( N[1] );
+  
+    
+    imgInput = new image<rgb>( height, width, 0 );
+    
+     /* start with RED channel*/     
+     /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
+     for ( uint y = 0; y < width; y++)
+     {
+       for ( uint x = 0; x < height; x++)
+       {
+	  imRef(imgInput, x, y).r = imgInputMatlab[y + width*(x + height*0) ];
+	  imRef(imgInput, x, y).g = imgInputMatlab[y + width*(x + height*1) ];
+	  imRef(imgInput, x, y).b = imgInputMatlab[y + width*(x + height*2) ];
+       }
+     }    
+  }     
+  
+  char buf [1024] ;
+  
+  /* Get sigma */  
+  double sigma;
+  sigma = mxGetScalar( pInput[1] ); 
+  if ( verbose ) 
+    mexPrintf("The sigma value is:  %f\n", sigma);
+    
+  /* Get k */  
+  int k = mxGetScalar( pInput[2] );
+  if ( verbose ) 
+    mexPrintf("The k is:  %i\n", k);
+   
+  /* Get minSize*/  
+  int minSize = mxGetScalar(  pInput[3] );
+  if ( verbose ) 
+    mexPrintf("The minSize is:  %i\n", minSize);
+   
+
+   
+  /* Get string of output image if given*/  
+  char * output;
+  if (nInput >=  5)
+  {
+    output = (char *) mxCalloc(mxGetN(pInput[4])+1, sizeof(char));
+    mxGetString(pInput[4], output, mxGetN(pInput[4])+1);
+    
+    if ( verbose ) 
+      mexPrintf("The output string is:  %s\n", output);
+  }
+    
+  if ( verbose )
+    mexPrintf("image loaded, now start segmentation\n");  
+   
+   /* -----------------------------------------------------------------
+   *                       Do the main stuff 
+   *                        >segmentation<
+   * -------------------------------------------------------------- */   
+   
+   int num_ccs; 
+   image<rgb> * imgResult = segment_image(imgInput, sigma, k, minSize, &num_ccs); 
+   if ( verbose )
+     mexPrintf("segmentation done\n");
+  
+   
+   /* -----------------------------------------------------------------
+   *                      Conversion to Matlab structures
+   * -------------------------------------------------------------- */      
+   
+   if ( nOutput == 0 )
+   {
+     savePPM( imgResult, output );
+     mexPrintf("save results\n"); 
+   }
+   else
+   {
+     mexPrintf("convert to matlab structure and hand result back to main program\n"); 
+     /* convert segmentation result to matlax matrix*/
+     int width ( imgResult->width() );
+     int height (imgResult->height() );
+        
+     int numberOfPixels ( width * height * sizeof(rgb)  );
+     
+     if ( verbose )
+       mexPrintf("The number of Pixel in your resulting image is:  %i -- summing over all color channels\n", numberOfPixels);
+     
+     /*if ( verbose )*/
+       mexPrintf(" width: %i, height: %i\n", width, height);
+     
+     /* keep in mind that matlab stores images  height × width × color, whereas C does it the other way round*/
+     int dims[] = {height, width,3};
+     pOutput[0] = mxCreateNumericArray (3, dims, mxUINT8_CLASS, mxREAL);
+     unsigned char *out1; /* pointer to output 1 */
+     out1 = (unsigned char *)mxGetPr( pOutput[0] ); /* pointer to output 1 */
+
+          
+     /* start with RED channel*/     
+     /* keep in mind that matlab stores images col by width, whereas C does it the other way round*/
+     for ( uint x = 0; x < width; x++)
+     {
+       uint rowOffset ( x*height );
+       for ( uint y = 0; y < height; y++)
+       {
+	  out1[rowOffset + y ] = (double) (imRef(imgResult, x, y)).r;
+       }
+     }
+     
+     /* GREEN channel*/
+     uint channelOffsetG ( width * height );
+     for ( uint x = 0; x < width; x++)
+     {
+       uint rowOffset ( x*height );
+        for ( uint y = 0; y < height; y++)
+	{
+	   out1[channelOffsetG + rowOffset + y ] = (double) (imRef(imgResult, x, y)).g;
+	}
+     }
+     
+     /* BLUE channel*/
+     uint channelOffsetB ( 2 * width * height );
+     for ( uint x = 0; x < width; x++)
+     {
+       uint rowOffset ( x*height );
+        for ( uint y = 0; y < height; y++)
+	{
+	   out1[channelOffsetB + rowOffset + y ] = (double) (imRef(imgResult, x, y)).b;
+	}
+     }
+
+    /* done */
+   }
+   
+   /* don't waste memory*/
+   if ( imgInput != NULL )
+     delete imgInput;
+  
+  return;
+}

+ 28 - 0
segmentFelzenszwalb.m

@@ -0,0 +1,28 @@
+% function segImg = segmentFelzenszwalb(imgInput, sigma, k, minSize, destination, verbose)
+%
+% BRIEF: segmentFelzenszwalb Run the region segmentation algorithm of Felzenszwalb
+% and Huttonlocher
+%   V = segmentFelzenszwalb(X, N) 
+%
+%   The function accepts the following options:
+%   INPUT: 
+%        imgInput         --   (string or 3d-matrix)
+%        sigma            --   (optional, scalar) bandwidth of Gaussian kernel to
+%        smooth the image, default: 0.5
+%        k                --   (optional, scalar) influences the threshold accept a
+%        boundary between regions (larger k -> larger regions), default:
+%        500
+%        minSize          --   (optional, scalar), minimum component size (enforced by post-processing stage), default: 20
+%        destination      --   (optional, string) 
+%        verbose          --   (optional, bool) 
+%   OUTPUT: 
+%
+%
+%   Example::
+%
+%   Note::
+
+
+% Authors: Alexander Freytag
+% Copyright (C) 2013 Alexander Freytag
+% All rights reserved.