Esempio n. 1
0
      virtual void fft(const float* data, float* re, float* im) override
      {
        // Convert into the format as required by the Ooura FFT
        ConvertBuffer(&_buffer[0], data, _size);

        rdft(static_cast<int>(_size), +1, _buffer.data(), _ip.data(), _w.data());

        // Convert back to split-complex
        {
          double* b = &_buffer[0];
          double* bEnd = b + _size;
          float *r = re;
          float *i = im;
          while (b != bEnd)
          {
            *(r++) = static_cast<float>(*(b++));
            *(i++) = static_cast<float>(-(*(b++)));
          }
        }
        const size_t size2 = _size / 2;
        re[size2] = -im[0];
        im[0] = 0.0;
        im[size2] = 0.0;
      }
Esempio n. 2
0
int GradientModulus( void *bufferIn,
		     bufferType typeIn,
		     void *bufferOut,
		     bufferType typeOut,
		     int *bufferDims,
		     int *borderLengths,
		     float *filterCoefs,
		     recursiveFilterType filterType )
{
  const char *proc = "GradientModulus";
  float *auxBuf = NULL;
  float *tmpBuf = NULL, *grdBuf = NULL;
  int sizeAuxBuf = 0;
  derivativeOrder derivatives[3];
  int i;


  sizeAuxBuf = bufferDims[0] * bufferDims[1] * bufferDims[2];
  if ( typeOut != CGAL_FLOAT || bufferIn == bufferOut )
    sizeAuxBuf *= 2;


  /* allocation des buffers de calcul
   */
  auxBuf = (float*)malloc( sizeAuxBuf * sizeof(float) );
  if ( auxBuf == NULL ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, "%s: unable to allocate auxiliary buffer\n", proc );
    return( EXIT_ON_FAILURE );
  }
  tmpBuf = auxBuf;
  if ( typeOut != CGAL_FLOAT || bufferIn == bufferOut ) {
    grdBuf  = tmpBuf;
    grdBuf += bufferDims[0] * bufferDims[1] * bufferDims[2];
  } else {
    grdBuf  = (float*)bufferOut;
  }
  
  /* cas 2D
   */
  if ( bufferDims[2] == 1 ) {

    derivatives[0] = DERIVATIVE_1; 
    derivatives[1] = DERIVATIVE_0;
    derivatives[2] = NODERIVATIVE;
    if ( RecursiveFilterOnBuffer( bufferIn, typeIn, (void*)grdBuf, CGAL_FLOAT,
				  bufferDims, borderLengths, derivatives,
				  filterCoefs, filterType ) != EXIT_ON_SUCCESS ) {
      if ( _VERBOSE_ ) 
	fprintf( stderr, "%s: unable to compute X derivative (2D)\n", proc );
      free( auxBuf );
      return( EXIT_ON_FAILURE );
    }

    derivatives[0] = DERIVATIVE_0; 
    derivatives[1] = DERIVATIVE_1;
    derivatives[2] = NODERIVATIVE;
    if ( RecursiveFilterOnBuffer( bufferIn, typeIn, (void*)tmpBuf, CGAL_FLOAT,
				  bufferDims, borderLengths, derivatives,
				  filterCoefs, filterType ) != EXIT_ON_SUCCESS ) {
      if ( _VERBOSE_ ) 
	fprintf( stderr, "%s: unable to compute Y derivative (2D)\n", proc );
      free( auxBuf );
      return( EXIT_ON_FAILURE );
    }
    
    sizeAuxBuf = bufferDims[0] * bufferDims[1] * bufferDims[2];
    for ( i = 0; i < sizeAuxBuf; i++ )
      grdBuf[i] = (float)sqrt( grdBuf[i]*grdBuf[i] + tmpBuf[i]*tmpBuf[i] );
    
  } else {
    
    derivatives[0] = NODERIVATIVE;
    derivatives[1] = NODERIVATIVE;
    derivatives[2] = DERIVATIVE_0;
    if ( RecursiveFilterOnBuffer( bufferIn, typeIn, (void*)tmpBuf, CGAL_FLOAT,
				  bufferDims, borderLengths, derivatives,
				  filterCoefs, filterType ) != EXIT_ON_SUCCESS ) {
      if ( _VERBOSE_ ) 
	fprintf( stderr, "%s: unable to compute Z smoothing (3D)\n", proc );
      free( auxBuf );
      return( EXIT_ON_FAILURE );
    }

    derivatives[0] = DERIVATIVE_1; 
    derivatives[1] = DERIVATIVE_0;
    derivatives[2] = NODERIVATIVE;
    if ( RecursiveFilterOnBuffer( (void*)tmpBuf, CGAL_FLOAT, (void*)grdBuf, CGAL_FLOAT,
				  bufferDims, borderLengths, derivatives,
				  filterCoefs, filterType ) != EXIT_ON_SUCCESS ) {
      if ( _VERBOSE_ ) 
	fprintf( stderr, "%s: unable to compute X derivative (3D)\n", proc );
      free( auxBuf );
      return( EXIT_ON_FAILURE );
    }

    derivatives[0] = DERIVATIVE_0; 
    derivatives[1] = DERIVATIVE_1;
    derivatives[2] = NODERIVATIVE;
    if ( RecursiveFilterOnBuffer( (void*)tmpBuf, CGAL_FLOAT, (void*)tmpBuf, CGAL_FLOAT,
				  bufferDims, borderLengths, derivatives,
				  filterCoefs, filterType ) != EXIT_ON_SUCCESS ) {
      if ( _VERBOSE_ ) 
	fprintf( stderr, "%s: unable to compute Y derivative (3D)\n", proc );
      free( auxBuf );
      return( EXIT_ON_FAILURE );
    }

    sizeAuxBuf = bufferDims[0] * bufferDims[1] * bufferDims[2];
    for ( i = 0; i < sizeAuxBuf; i++ )
      grdBuf[i] = grdBuf[i]*grdBuf[i] + tmpBuf[i]*tmpBuf[i];
    
    derivatives[0] = DERIVATIVE_0;
    derivatives[1] = DERIVATIVE_0;
    derivatives[2] = DERIVATIVE_1;
    if ( RecursiveFilterOnBuffer( bufferIn, typeIn, (void*)tmpBuf, CGAL_FLOAT,
				  bufferDims, borderLengths, derivatives,
				  filterCoefs, filterType ) != EXIT_ON_SUCCESS ) {
      if ( _VERBOSE_ ) 
	fprintf( stderr, "%s: unable to compute Z derivative (3D)\n", proc );
      free( auxBuf );
      return( EXIT_ON_FAILURE );
    }
    
    for ( i = 0; i < sizeAuxBuf; i++ )
      grdBuf[i] = (float)sqrt( grdBuf[i] + tmpBuf[i]*tmpBuf[i] );
    
  }

  if ( grdBuf != bufferOut ) 
    ConvertBuffer( grdBuf, CGAL_FLOAT, bufferOut, typeOut,
		   bufferDims[0]*bufferDims[1]*bufferDims[2] );
  free( auxBuf );
  return( EXIT_ON_SUCCESS );
}
Esempio n. 3
0
int GradientHessianGradient ( void *bufferIn,
		   bufferType typeIn,
		   void *bufferOut,
		   bufferType typeOut,
		   int *bufferDims,
		   int *borderLengths,
		   float *filterCoefs,
		   recursiveFilterType filterType )
{
  const char *proc = "GradientHessianGradient";



  float *theZZ = NULL;
  float *theZ  = NULL;
  float *theZ1 = NULL;
  float *theZ0 = NULL;

  float *theXZ = NULL;
  float *theYZ = NULL;

  float *theXX = NULL;
  float *theYY = NULL;
  float *theXY = NULL;

  float *theX  = NULL;
  float *theY  = NULL;


  derivativeOrder ZZderiv[3] = { SMOOTHING,    SMOOTHING,    DERIVATIVE_2 };
  derivativeOrder Zderiv[3]  = { SMOOTHING,    SMOOTHING,    DERIVATIVE_1 };
  derivativeOrder Z1deriv[3] = { NODERIVATIVE, NODERIVATIVE, DERIVATIVE_1 };
  derivativeOrder Z0deriv[3] = { NODERIVATIVE, NODERIVATIVE, SMOOTHING };

  derivativeOrder XZderiv[3] = { DERIVATIVE_1, SMOOTHING,    NODERIVATIVE };
  derivativeOrder YZderiv[3] = { SMOOTHING,    DERIVATIVE_1, NODERIVATIVE };

  derivativeOrder XXderiv[3] = { DERIVATIVE_2, SMOOTHING,    NODERIVATIVE };
  derivativeOrder YYderiv[3] = { SMOOTHING,    DERIVATIVE_2, NODERIVATIVE };
  derivativeOrder XYderiv[3] = { DERIVATIVE_1, DERIVATIVE_1, NODERIVATIVE };

  derivativeOrder Xderiv[3]  = { DERIVATIVE_1, SMOOTHING,    NODERIVATIVE };
  derivativeOrder Yderiv[3]  = { SMOOTHING,    DERIVATIVE_1, NODERIVATIVE };

  int sliceDims[3];
  int z, i, j, dimxXdimy;

  double gx, gy, gz, g;

  /* 
   * We check the buffers' dimensions.
   */
  if ( bufferDims[2] == 1 ) {
    return( GradientHessianGradient_2D ( bufferIn, typeIn, bufferOut, typeOut,
			   bufferDims, borderLengths, filterCoefs, filterType ) );
  }

  if ( (bufferDims[0] <= 0) || (bufferDims[1] <= 0) || (bufferDims[2] <= 0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: improper buffer's dimension.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  
  /*
   * test of the coefficients
   */
  if ( (filterCoefs[0] < 0.0) || (filterCoefs[1] < 0.0) ||
       (filterCoefs[2] < 0.0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Error in %s: negative coefficient's value.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  

  /*
   *
   */
  dimxXdimy = bufferDims[0] * bufferDims[1];
  sliceDims[0] = bufferDims[0];
  sliceDims[1] = bufferDims[1];
  sliceDims[2] = 1;
  

  if ( typeOut == CGAL_FLOAT ) {
    theX  = (float*)malloc( (7+3*bufferDims[2]) * dimxXdimy * sizeof( float ) );
  } else {
    theX = (float*)malloc( (7+4*bufferDims[2]) * dimxXdimy * sizeof( float ) );
  }

  
  if ( theX == NULL ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to allocate auxiliary buffer.\n" );
    }
    return( EXIT_ON_FAILURE );
  }
  
  /*
   * BUFFERS
   *
   * slices  : theX  theY  theXY theYY theXX theYZ theXZ
   *
   * volumes : theZ0 theZ1 theZ  theZZ
   *
   */

  theY  = theXX = theXY = theYY = theYZ = theXZ = theX;
  theZ0 = theZ1 = theZ  = theX;

  theY  +=   dimxXdimy;
  theXY += 2*dimxXdimy;
  theYY += 3*dimxXdimy;
  theXX += 4*dimxXdimy;
  theYZ += 5*dimxXdimy;
  theXZ += 6*dimxXdimy;
 
  theZ0 += 7*dimxXdimy;
  theZ1 += 7*dimxXdimy +   bufferDims[2]*dimxXdimy;
  theZ  += 7*dimxXdimy + 2*bufferDims[2]*dimxXdimy;

  if ( typeOut == CGAL_FLOAT ) {
    theZZ  = (float*)bufferOut;
  } else {
    theZZ  = theX;
    theZZ += 7*dimxXdimy + 3*bufferDims[2]*dimxXdimy;
  }
  
  
  
  /*
   *
   * 3D filtering / filtering along Z
   *
   */

  if ( RecursiveFilterOnBuffer( bufferIn, typeIn, theZ0, CGAL_FLOAT, 
				bufferDims, borderLengths,
				Z0deriv, filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Z^0 derivative.\n" );
    }
    free( theX );
    return( EXIT_ON_FAILURE );
  }
  
  if ( RecursiveFilterOnBuffer( bufferIn, typeIn, theZ1, CGAL_FLOAT, 
				bufferDims, borderLengths,
				Z1deriv, filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Z^1 derivative.\n" );
    }
    free( theX );
    return( EXIT_ON_FAILURE );
  }
  
  if ( RecursiveFilterOnBuffer( bufferIn, typeIn, theZ, CGAL_FLOAT, 
				bufferDims, borderLengths,
				Zderiv, filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Z^1 derivative (edge).\n" );
    }
    free( theX );
    return( EXIT_ON_FAILURE );
  }
  
  if ( RecursiveFilterOnBuffer( bufferIn, typeIn, theZZ, CGAL_FLOAT, 
				bufferDims, borderLengths,
				ZZderiv, filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Z^2 derivative.\n" );
    }
    free( theX );
    return( EXIT_ON_FAILURE );
  }


  /*
   * theZ0 : smoothed         along Z
   * theZ1 : first derivative along Z
   * theZ  : first derivative along Z, smoothed along X and Y
   * theZZ : second derivative along Z, smoothed along X and Y
   */



  for ( z=0; z<bufferDims[2]; z++ ) {
    fprintf( stderr, "%s: processing slice %3d/%d\r",
	     proc, z, bufferDims[2] );
    /*
     *
     * 2D filtering / filtering along X and Y
     *
     */
    
    if ( RecursiveFilterOnBuffer( theZ1+z*dimxXdimy, CGAL_FLOAT, theXZ, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  XZderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^1Z^1 derivative.\n" );
      }
      free( theX );
      return( EXIT_ON_FAILURE );
    }

    if ( RecursiveFilterOnBuffer( theZ1+z*dimxXdimy, CGAL_FLOAT, theYZ, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  YZderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y^1Z^1 derivative.\n" );
      }
      free( theX );
      return( EXIT_ON_FAILURE );
    }




    if ( RecursiveFilterOnBuffer( theZ0+z*dimxXdimy, CGAL_FLOAT, theXX, CGAL_FLOAT,
				  sliceDims, borderLengths,
				  XXderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^2 derivative.\n" );
      }
      free( theX );
      return( EXIT_ON_FAILURE );
    }

    if ( RecursiveFilterOnBuffer( theZ0+z*dimxXdimy, CGAL_FLOAT, theYY, CGAL_FLOAT,
				  sliceDims, borderLengths,
				  YYderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y^2 derivative.\n" );
      }
      free( theX );
      return( EXIT_ON_FAILURE );
    }

    if ( RecursiveFilterOnBuffer( theZ0+z*dimxXdimy, CGAL_FLOAT, theXY, CGAL_FLOAT,
				  sliceDims, borderLengths,
				  XYderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^1Y^1 derivative.\n" );
      }
      free( theX );
      return( EXIT_ON_FAILURE );
    }



    if ( RecursiveFilterOnBuffer( theZ0+z*dimxXdimy, CGAL_FLOAT, theX, CGAL_FLOAT,
				  sliceDims, borderLengths,
				  Xderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^1 derivative (edge).\n" );
      }
      free( theX );
      return( EXIT_ON_FAILURE );
    }

    if ( RecursiveFilterOnBuffer( theZ0+z*dimxXdimy, CGAL_FLOAT, theY, CGAL_FLOAT,
				  sliceDims, borderLengths,
				  Yderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y^1 derivative (edge).\n" );
      }
      free( theX );
      return( EXIT_ON_FAILURE );
    }

    
    
    for ( j=z*dimxXdimy, i=0; i<dimxXdimy; j++, i++ ) {
      gx = theX[i];
      gy = theY[i];
      gz = theZ[j];
      g = gx*gx + gy*gy + gz*gz;
      theZZ[j] = (float)(gx * ( theXX[i] * gx + theXY[i] * gy  + theXZ[i] * gz ) +
			 gy * ( theXY[i] * gx + theYY[i] * gy  + theYZ[i] * gz ) +
			 gz * ( theXZ[i] * gx + theYZ[i] * gy  + theZZ[j] * gz ));
      if ( g > 1e-10 ) theZZ[j] = (float)(theZZ[j] / g);

    }

  }

  if ( typeOut != CGAL_FLOAT ) {
    ConvertBuffer( theZZ, CGAL_FLOAT, bufferOut, typeOut, bufferDims[2]*dimxXdimy );
  }
  
  free( theX );

  return( EXIT_ON_SUCCESS );
}
Esempio n. 4
0
int Laplacian ( void *bufferIn,
		   bufferType typeIn,
		   void *bufferOut,
		   bufferType typeOut,
		   int *bufferDims,
		   int *borderLengths,
		   float *filterCoefs,
		   recursiveFilterType filterType )
{
  const char *proc = "Laplacian";
  float *theSL = NULL;
  float *theZZ = NULL;
  float *theZ0 = NULL;


  derivativeOrder XXderiv[3] = { DERIVATIVE_2, SMOOTHING, NODERIVATIVE };
  derivativeOrder YYderiv[3] = { SMOOTHING, DERIVATIVE_2, NODERIVATIVE };
  derivativeOrder Zsmooth[3] = { NODERIVATIVE, NODERIVATIVE, SMOOTHING };
  derivativeOrder ZZderiv[3] = { SMOOTHING, SMOOTHING, DERIVATIVE_2 };
  
  int sliceDims[3];
  int z, i, j, dimxXdimy;




  /* 
   * We check the buffers' dimensions.
   */
  if ( bufferDims[2] == 1 ) {
    return( Laplacian_2D ( bufferIn, typeIn, bufferOut, typeOut,
			   bufferDims, borderLengths, filterCoefs, filterType ) );
  }

  if ( (bufferDims[0] <= 0) || (bufferDims[1] <= 0) || (bufferDims[2] <= 0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: improper buffer's dimension.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  
  /*
   * test of the coefficients
   */
  if ( (filterCoefs[0] < 0.0) || (filterCoefs[1] < 0.0) ||
       (filterCoefs[2] < 0.0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Error in %s: negative coefficient's value.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  

  /*
   *
   */
  dimxXdimy = bufferDims[0] * bufferDims[1];
  sliceDims[0] = bufferDims[0];
  sliceDims[1] = bufferDims[1];
  sliceDims[2] = 1;

  

  if ( typeOut == CGAL_FLOAT ) {
    theSL = (float*)malloc( (1+bufferDims[2]) * dimxXdimy * sizeof( float ) );
  } else {
    theSL = (float*)malloc( (1+2*bufferDims[2]) * dimxXdimy * sizeof( float ) );
  }


  
  if ( theSL == NULL ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to allocate auxiliary buffer.\n" );
    }
    return( EXIT_ON_FAILURE );
  }



  theZ0 = theSL;
  theZ0 += dimxXdimy;


  
  if ( typeOut == CGAL_FLOAT ) {
    theZZ = (float*) bufferOut;
  } else {
    theZZ  = theZ0;
    theZZ += dimxXdimy * bufferDims[2];
  }
  
  
  
  /*
   *
   * 3D filtering / filtering along Z
   *
   */

  if ( RecursiveFilterOnBuffer( bufferIn, typeIn, theZ0, CGAL_FLOAT, 
				bufferDims, borderLengths,
				Zsmooth, filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Z^0 derivative.\n" );
    }
    free( theSL );
    return( EXIT_ON_FAILURE );
  }
  if ( RecursiveFilterOnBuffer( bufferIn, typeIn, theZZ, CGAL_FLOAT, 
				bufferDims, borderLengths,
				ZZderiv, filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Z^2 derivative.\n" );
    }
    free( theSL );
    return( EXIT_ON_FAILURE );
  }
  





  for ( z=0; z<bufferDims[2]; z++ ) {

    /*
     *
     * 2D filtering / filtering along X and Y
     *
     */

    if ( RecursiveFilterOnBuffer( theZ0+z*dimxXdimy, CGAL_FLOAT, theSL, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  XXderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^2 derivative.\n" );
      }
      free( theSL );
      return( EXIT_ON_FAILURE );
    }

    for ( j=z*dimxXdimy, i=0; i<dimxXdimy; j++, i++ ) {
      theZZ[j] += theSL[i];
    }

    if ( RecursiveFilterOnBuffer( theZ0+z*dimxXdimy, CGAL_FLOAT, theSL, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  YYderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y^2 derivative.\n" );
      }
      free( theSL );
      return( EXIT_ON_FAILURE );
    }
    
    for ( j=z*dimxXdimy, i=0; i<dimxXdimy; j++, i++ ) {
      theZZ[j] += theSL[i];
    }

  }

  if ( typeOut != CGAL_FLOAT ) {
    ConvertBuffer( theZZ, CGAL_FLOAT, bufferOut, typeOut, bufferDims[2]*dimxXdimy );
  }

  return( EXIT_ON_SUCCESS );
}
Esempio n. 5
0
/*
 *
 * Gradient . Hessian * Gradient
 *
 *
 */
int GradientHessianGradient_2D ( void *bufferIn,
		   bufferType typeIn,
		   void *bufferOut,
		   bufferType typeOut,
		   int *bufferDims,
		   int *borderLengths,
		   float *filterCoefs,
		   recursiveFilterType filterType )
{
  const char *proc = "GradientHessianGradient_2D";
  float *theXX = NULL;
  float *theYY = NULL;
  float *theXY = NULL;
  float *theX  = NULL;
  float *theY  = NULL;

  derivativeOrder Xsmooth[3] = { SMOOTHING,          NODERIVATIVE,       NODERIVATIVE };
  derivativeOrder Yderiv[3]  = { NODERIVATIVE,       DERIVATIVE_1_EDGES, NODERIVATIVE };
  derivativeOrder YYderiv[3] = { NODERIVATIVE,       DERIVATIVE_2,       NODERIVATIVE };

  derivativeOrder Ysmooth[3] = { NODERIVATIVE,       SMOOTHING,          NODERIVATIVE };
  derivativeOrder Xderiv[3]  = { DERIVATIVE_1_EDGES, NODERIVATIVE,       NODERIVATIVE };
  derivativeOrder XXderiv[3] = { DERIVATIVE_2,       NODERIVATIVE,       NODERIVATIVE };

  derivativeOrder XYderiv[3] = { DERIVATIVE_1,       DERIVATIVE_1,       NODERIVATIVE };

  int sliceDims[3];
  int z, i, dimxXdimy;

  void *sliceIn = NULL;
  void *sliceOut = NULL;

  double gx, gy, g;

  /* 
   * We check the buffers' dimensions.
   */
  if ( (bufferDims[0] <= 0) || (bufferDims[1] <= 0) || (bufferDims[2] <= 0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: improper buffer's dimension.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  
  /*
   * test of the coefficients
   */
  if ( (filterCoefs[0] < 0.0) || (filterCoefs[1] < 0.0) ||
       (filterCoefs[2] < 0.0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Error in %s: negative coefficient's value.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  

  /*
   *
   */
  dimxXdimy = bufferDims[0] * bufferDims[1];
  sliceDims[0] = bufferDims[0];
  sliceDims[1] = bufferDims[1];
  sliceDims[2] = 1;
  

  if ( typeOut == CGAL_FLOAT ) {
    theXX = (float*)malloc( 4 * dimxXdimy * sizeof( float ) );
  } else {
    theXX = (float*)malloc( 5 * dimxXdimy * sizeof( float ) );
  }
  
  if ( theXX == NULL ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to allocate auxiliary buffer.\n" );
    }
    return( EXIT_ON_FAILURE );
  }
  


  theX = theY = theYY = theXX;
  theYY +=   dimxXdimy;
  theX  += 2*dimxXdimy;
  theY  += 3*dimxXdimy;



  if ( typeOut != CGAL_FLOAT ) {
    theXY  =   theXX;
    theXY += 4*dimxXdimy;
  }
  
  
  
  for ( z=0; z<bufferDims[2]; z++ ) {

    switch( typeIn ) {
    default :
      break;
    case CGAL_UCHAR :
    case CGAL_SCHAR :
      sliceIn = (void*)( ((u8*)bufferIn) + z*dimxXdimy ); break;
    case CGAL_USHORT :
    case CGAL_SSHORT :
      sliceIn = (void*)( ((u16*)bufferIn) + z*dimxXdimy ); break;
    case CGAL_FLOAT :
      sliceIn = (void*)( ((float*)bufferIn) + z*dimxXdimy ); break;
    case CGAL_DOUBLE :
      sliceIn = (void*)( ((double*)bufferIn) + z*dimxXdimy ); break;
    }
    if ( typeOut == CGAL_FLOAT ) {
      theXY = ((float*)bufferOut) + z * dimxXdimy;
    }
    
    if ( RecursiveFilterOnBuffer( sliceIn, typeIn, theX, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  Ysmooth, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y^0 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }

    if ( RecursiveFilterOnBuffer( sliceIn, typeIn, theY, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  Xsmooth, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^0 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }




    if ( RecursiveFilterOnBuffer( sliceIn, typeIn, theXY, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  XYderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^1Y^1 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }




    if ( RecursiveFilterOnBuffer( theX, CGAL_FLOAT, theXX, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  XXderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^2 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }

    if ( RecursiveFilterOnBuffer( theY, CGAL_FLOAT, theYY, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  YYderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y^2 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }




    if ( RecursiveFilterOnBuffer( theX, CGAL_FLOAT, theX, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  Xderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^1 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }

    if ( RecursiveFilterOnBuffer( theY, CGAL_FLOAT, theY, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  Yderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y^1 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }


    
    
    for ( i=0; i<dimxXdimy; i++ ) {
      gx = theX[i];
      gy = theY[i];
      g = (gx*gx + gy*gy);
      theXY[i] = (float)(gx * ( theXX[i] * gx + theXY[i] * gy ) +
			 gy * ( theXY[i] * gx + theYY[i] * gy ));
      if ( g > 1e-10 ) theXY[i] = (float)(theXY[i] / g);
    }

    if ( typeOut != CGAL_FLOAT ) {
      switch ( typeOut ) {
      case CGAL_UCHAR :
	sliceOut = (((u8*)bufferOut) + z * dimxXdimy);
	break;
      case CGAL_SCHAR :
	sliceOut = (((s8*)bufferOut) + z * dimxXdimy);
	break;
      case CGAL_SSHORT :
	sliceOut = (((s16*)bufferOut) + z * dimxXdimy);
	break;
      case CGAL_DOUBLE :
	sliceOut = (((r64*)bufferOut) + z * dimxXdimy);
	break;
      default :
	if ( _VERBOSE_ > 0 )
	  fprintf( stderr, " Error in %s: such output type not handled.\n", proc );
	free( theXX );
	return( EXIT_ON_FAILURE );
      }
      ConvertBuffer( theXY, CGAL_FLOAT, sliceOut, typeOut, dimxXdimy );
    }
  }

  return( EXIT_ON_SUCCESS );
}
Esempio n. 6
0
int RecursiveFilterOnBuffer( void *bufferIn,
			     bufferType typeIn,
			     void *bufferOut,
			     bufferType typeOut,
			     int *bufferDims,
			     int *borderLengths,
			     derivativeOrder *derivatives,
			     float *filterCoefs,
			     recursiveFilterType filterType )
{
  const char *proc = "RecursiveFilterOnBuffer";
  register int dimx, dimxXdimy;
  int dimy, dimz;
  register int x, y, z;
  /* 
   *obviously, we need to perform the computation 
   * with float or double values. For this reason,
   * we allocate an auxiliary buffer if the output buffer
   * is not of type float or double.
   */
  void *bufferToBeProcessed = (void*)NULL;
  bufferType typeToBeProcessed = TYPE_UNKNOWN;
  void *bufferResult = (void*)NULL;
  bufferType typeResult = TYPE_UNKNOWN;
  /*
   * lines' lengths
   */
  int lengthX = 0;
  int lengthY = 0;
  int lengthZ = 0;
  int maxLengthline = 0;
  int borderXlength = 0;
  int borderYlength = 0;
  int borderZlength = 0;
  /*
   * 1D arrays for computations.
   */
  double *theLine = (double*)NULL;
  double *resLine = (double*)NULL;
  double *tmpLine = (double*)NULL;
  /*
   * pointers for computations;
   */
  register r32 *r32firstPoint = (r32*)NULL;
  register r64 *r64firstPoint = (r64*)NULL;
  register r32 *r32_pt = (r32*)NULL;
  register r64 *r64_pt = (r64*)NULL;
  register double *dbl_pt1 = (double*)NULL;
  register double *dbl_pt2 = (double*)NULL;
  register double dbl_first = 0.0;
  register double dbl_last = 0.0;
  int offsetLastPoint = 0;
  int offsetNextFirstPoint = 0;
  register r32 *r32firstPointResult = (r32*)NULL;
  register r64 *r64firstPointResult = (r64*)NULL;
  double *theLinePlusBorder = (double*)NULL;
  double *resLinePlusBorder = (double*)NULL;

  RFcoefficientType *RFC = NULL;

  /* 
   * We check the buffers' dimensions.
   */
  dimx = bufferDims[0];   dimy = bufferDims[1];   dimz = bufferDims[2];
  dimxXdimy = dimx * dimy;
  if ( (dimx <= 0) || (dimy <= 0) || (dimz <= 0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: improper buffer's dimension.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  /*
   * We check the pointers.
   */
  if ( (bufferIn == (void*)NULL) || (bufferOut == (void*)NULL) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: NULL pointer on buffer.\n", proc );
    return( EXIT_ON_FAILURE );
  }

  /* 
   * May we use the buffer bufferOut as the bufferResult?
   * If its type is CGAL_FLOAT or CGAL_DOUBLE, then yes.
   * If not, we have to allocate an auxiliary buffer.
   */
  if ( (typeOut == CGAL_FLOAT) || (typeOut == CGAL_DOUBLE) ) {
    bufferResult = bufferOut;
    typeResult = typeOut;
  } else {
    bufferResult = (void*)malloc( (dimx*dimy*dimz) * sizeof(r32) );
    if ( bufferResult == (void*)NULL ) {
      if ( _VERBOSE_ > 0 )
	fprintf( stderr, " Fatal error in %s: unable to allocate auxiliary buffer.\n", proc );
      return( EXIT_ON_FAILURE );
    }
    typeResult = CGAL_FLOAT;
  }
  
  /* 
   * May we consider the buffer bufferIn as the bufferToBeProcessed?
   * If its type is CGAL_FLOAT or CGAL_DOUBLE, then yes.
   * If not, we convert it into the buffer bufferResult, and this
   * last buffer is the bufferToBeProcessed.
   */
  if ( (typeIn == CGAL_FLOAT) || (typeIn == CGAL_DOUBLE) ) {
    bufferToBeProcessed = bufferIn;
    typeToBeProcessed = typeIn;
  } else {
    ConvertBuffer( bufferIn, typeIn, bufferResult, typeResult, (dimx*dimy*dimz) );
    bufferToBeProcessed = bufferResult;
    typeToBeProcessed = typeResult;
  }

  /*
   * Estimation of the lines' length along each direction.
   */
  if ( borderLengths != NULL ) {
    borderXlength = borderLengths[0];
    borderYlength = borderLengths[1];
    borderZlength = borderLengths[2];
    if ( borderXlength < 0 ) borderXlength = 0;
    if ( borderYlength < 0 ) borderYlength = 0;
    if ( borderZlength < 0 ) borderZlength = 0;
  }

  /*
   * Tue Jul  6 19:15:15 MET DST 1999 (gregoire Malandain)
   * changes 3 x dimx -> dimx, dimy, dimz
   */
  lengthX = dimx + 2 * borderXlength;
  lengthY = dimy + 2 * borderYlength;
  lengthZ = dimz + 2 * borderZlength;
  maxLengthline = lengthX;
  if ( maxLengthline < lengthY ) maxLengthline = lengthY;
  if ( maxLengthline < lengthZ ) maxLengthline = lengthZ;
  if ( maxLengthline <= 0 ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Error in %s: unable to deal with dimensions = 0.\n", proc );
    if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
      free( bufferResult );
    return( EXIT_ON_FAILURE );
  }
  /*
   * Allocations of work arrays. 
   * We will use them to process each line.
   */
  theLine = (double*)malloc( 3 * maxLengthline * sizeof(double) );
  if ( theLine == (double*)NULL ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: unable to allocate auxiliary work arrays.\n", proc );
    if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
      free( bufferResult );
    return( EXIT_ON_FAILURE );
  }
  resLine = theLine + maxLengthline;
  tmpLine = resLine + maxLengthline;

  /*
   * From now,
   * typeToBeProcessed is either CGAL_FLOAT or CGAL_DOUBLE
   * so is typeResult.
   */


  /*
   * Processing along X.
   */
  if ( dimx > 4 )
  if (derivatives[0] != NODERIVATIVE)
  if (filterCoefs[0] > 0.0) {

    if ( _VERBOSE_ != 0 )
      fprintf( stderr, " %s: processing along X.\n", proc );

    RFC = InitRecursiveCoefficients( (double)filterCoefs[0], filterType, derivatives[0] );

    if ( RFC == NULL ) {
      if ( _VERBOSE_ != 0 )
	fprintf( stderr, " %s: unable to allocate coefficients\n", proc );
      if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
	free( bufferResult );
      return( EXIT_ON_FAILURE );
    }
    
    r64firstPoint = (r64*)bufferToBeProcessed;
    r32firstPoint = (r32*)bufferToBeProcessed;

    r64firstPointResult = (r64*)bufferResult;
    r32firstPointResult = (r32*)bufferResult;

    offsetLastPoint = borderXlength + dimx - 1;

    theLinePlusBorder = theLine + borderXlength;
    resLinePlusBorder = resLine + borderXlength;

    /*
     * There are dimz*dimy X lines to be processed.
     */
    for ( z=0; z<dimz; z++ )
    for ( y=0; y<dimy; y++ ) {
      /*
       * Acquiring a X line.
       */ 
      dbl_pt1 = theLinePlusBorder;
      switch ( typeToBeProcessed ) {
      case CGAL_DOUBLE :
	(void)memcpy( (void*)dbl_pt1, (void*)r64firstPoint, dimx * sizeof(r64) );
	r64firstPoint += dimx;
	break;
      case CGAL_FLOAT :
      default :
	for ( x=0; x<dimx; x++, dbl_pt1++, r32firstPoint++ ) *dbl_pt1 = *r32firstPoint;
      }
      /*
       * Adding points at both ends of the line.
       */
      if ( borderXlength > 0 ) {
	dbl_pt1 = theLine + borderXlength;   dbl_first = *dbl_pt1;
	dbl_pt2 = theLine + offsetLastPoint; dbl_last  = *dbl_pt2;
	for ( x=0; x<borderXlength; x++ ) {
	  *--dbl_pt1 = dbl_first;
	  *++dbl_pt2 = dbl_last;
	}
      }
      /*
       * Processing the line.
       */
      if ( RecursiveFilter1D( RFC, theLine, resLine, tmpLine, resLine, lengthX ) == 0 ) {
	if ( _VERBOSE_ != 0 ) 
	  fprintf(stderr," Error in %s: unable to process X line (y=%d,z=%d).\n", proc, y, z);
	if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
	  free( bufferResult );
	free( (void*)theLine );
	return( EXIT_ON_FAILURE );
      }
      /*
       * Copy the result into the buffer bufferResult.
       */
      dbl_pt1 = resLinePlusBorder;
      switch ( typeResult ) {
      case CGAL_DOUBLE :
	(void)memcpy( (void*)r64firstPointResult, (void*)dbl_pt1, dimx * sizeof(r64) );
	r64firstPointResult += dimx;
	break;
      case CGAL_FLOAT :
      default :
	for ( x=0; x<dimx; x++, dbl_pt1++, r32firstPointResult++ )
	  *r32firstPointResult = (r32)(*dbl_pt1);
      }
    }
    
    /*
     * The next buffer to be processed is the buffer
     * bufferResult.
     */
    bufferToBeProcessed = bufferResult;
    typeToBeProcessed = typeResult;
    
    free( RFC );
    RFC = NULL;

  } /* end of Processing along X. */
  
  /*
   * Processing along Y.
   */
  if ( dimy > 4 )
  if (derivatives[1] != NODERIVATIVE)
  if (filterCoefs[1] > 0.0) {

    if ( _VERBOSE_ != 0 )
      fprintf( stderr, " %s: processing along Y.\n", proc );

    RFC = InitRecursiveCoefficients( (double)filterCoefs[1], filterType, derivatives[1] );

    if ( RFC == NULL ) {
      if ( _VERBOSE_ != 0 )
	fprintf( stderr, " %s: unable to allocate coefficients\n", proc );
      if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
	free( bufferResult );
      return( EXIT_ON_FAILURE );
    }

    r64firstPoint = (r64*)bufferToBeProcessed;
    r32firstPoint = (r32*)bufferToBeProcessed;

    r64firstPointResult = (r64*)bufferResult;
    r32firstPointResult = (r32*)bufferResult;

    offsetLastPoint = borderYlength + dimy - 1;
    offsetNextFirstPoint = dimx * dimy - dimx;

    theLinePlusBorder = theLine + borderYlength;
    resLinePlusBorder = resLine + borderYlength;

    /*
     * There are dimz*dimx Y lines to be processed.
     */
    for ( z=0; z<dimz; z++ ) {
      for ( x=0; x<dimx; x++ ) {
      /*
       * Acquiring a Y line.
       */ 
	dbl_pt1 = theLinePlusBorder;
	switch ( typeToBeProcessed ) {
	case CGAL_DOUBLE :
	  r64_pt = r64firstPoint;
	  for ( y=0; y<dimy; y++, dbl_pt1++, r64_pt += dimx ) *dbl_pt1 = *r64_pt;
	  /*
	   * Going to the first point of the next Y line
	   */
	  r64firstPoint ++;
	  break;
	case CGAL_FLOAT :
	default :
	  r32_pt = r32firstPoint;
	  for ( y=0; y<dimy; y++, dbl_pt1++, r32_pt += dimx ) *dbl_pt1 = *r32_pt;
	  r32firstPoint ++;
	}
	/*
	 * Adding points at both ends of the line.
	 */
	if ( borderYlength > 0 ) {
	  dbl_pt1 = theLine + borderYlength;   dbl_first = *dbl_pt1;
	  dbl_pt2 = theLine + offsetLastPoint; dbl_last  = *dbl_pt2;
	  for ( y=0; y<borderYlength; y++ ) {
	    *--dbl_pt1 = dbl_first;
	    *++dbl_pt2 = dbl_last;
	  }
	}
	/*
	 * Processing the line.
	 */
	if ( RecursiveFilter1D( RFC, theLine, resLine, tmpLine, resLine, lengthY ) == 0 ) {
	  if ( _VERBOSE_ != 0 ) 
	    fprintf(stderr," Error in %s: unable to process Y line (x=%d,z=%d).\n", proc, x, z);
	  if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
	    free( bufferResult );
	  free( (void*)theLine );
	  return( EXIT_ON_FAILURE );
	}
	/*
	 * Copy the result into the buffer bufferResult.
	 */
	dbl_pt1 = resLinePlusBorder;
	switch ( typeResult ) {
	case CGAL_DOUBLE :
	  r64_pt = r64firstPointResult;
	  for ( y=0; y<dimy; y++, dbl_pt1++, r64_pt += dimx ) *r64_pt = *dbl_pt1;
	  r64firstPointResult ++;
	  break;
	case CGAL_FLOAT :
	default :
	  r32_pt = r32firstPointResult;
	  for ( y=0; y<dimy; y++, dbl_pt1++, r32_pt += dimx ) 
	    *r32_pt = (float)*dbl_pt1;
	  r32firstPointResult ++;
	}
      }
      /*
       * Going to the first point of the next Y line
       * which is the first Y line of the next slice.
       *
       * The pointer r[32,64]firstPoint[Result] has
       * already been increased by dimx. To reach
       * the first point of the next slice, we
       * have to increase it by (dimx*dimy)-dimx.
       */
      switch ( typeToBeProcessed ) {
      case CGAL_DOUBLE :
	r64firstPoint += offsetNextFirstPoint;
	break;
      case CGAL_FLOAT :
      default :
	r32firstPoint += offsetNextFirstPoint;
      }
      switch ( typeResult ) {
      case CGAL_DOUBLE :
	r64firstPointResult += offsetNextFirstPoint;
	break;
      case CGAL_FLOAT :
      default :
	r32firstPointResult += offsetNextFirstPoint;
      }
    }
    
    /*
     * The next buffer to be processed is the buffer
     * bufferResult.
     */
    bufferToBeProcessed = bufferResult;
    typeToBeProcessed = typeResult;
  
    free( RFC );
    RFC = NULL;

  } /* end of Processing along Y. */
  

  /*
   * Processing along Z.
   */
  if ( dimz > 4 )
  if (derivatives[2] != NODERIVATIVE)
  if (filterCoefs[2] > 0.0) {

    if ( _VERBOSE_ != 0 )
      fprintf( stderr, " %s: processing along Z.\n", proc );
    
    RFC = InitRecursiveCoefficients( (double)filterCoefs[2], filterType, derivatives[2] );
    
    if ( RFC == NULL ) {
      if ( _VERBOSE_ != 0 )
	fprintf( stderr, " %s: unable to allocate coefficients\n", proc );
      if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
	free( bufferResult );
      return( EXIT_ON_FAILURE );
    }

    r64firstPoint = (r64*)bufferToBeProcessed;
    r32firstPoint = (r32*)bufferToBeProcessed;

    offsetLastPoint = borderZlength + dimz - 1;

    r64firstPointResult = (r64*)bufferResult;
    r32firstPointResult = (r32*)bufferResult;

    offsetLastPoint = borderZlength + dimz - 1;

    theLinePlusBorder = theLine + borderYlength;
    resLinePlusBorder = resLine + borderYlength;

    /*
     * There are dimy*dimx Z lines to be processed.
     */
    for ( y=0; y<dimy; y++ )
    for ( x=0; x<dimx; x++ ) {
      /*
       * Acquiring a Z line.
       */ 
      dbl_pt1 = theLinePlusBorder;
      switch ( typeToBeProcessed ) {
      case CGAL_DOUBLE :
	r64_pt = r64firstPoint;
	for ( z=0; z<dimz; z++, dbl_pt1++, r64_pt += dimxXdimy ) *dbl_pt1 = *r64_pt;
	/*
	 * Going to the first point of the next Z line
	 */
	r64firstPoint ++;
	break;
      case CGAL_FLOAT :
      default :
	r32_pt = r32firstPoint;
	for ( z=0; z<dimz; z++, dbl_pt1++, r32_pt += dimxXdimy ) *dbl_pt1 = *r32_pt;
	r32firstPoint ++;
      }
      /*
       * Adding points at both ends of the line.
       */
      if ( borderZlength > 0 ) {
	dbl_pt1 = theLine + borderZlength;   dbl_first = *dbl_pt1;
	dbl_pt2 = theLine + offsetLastPoint; dbl_last  = *dbl_pt2;
	for ( z=0; z<borderZlength; z++ ) {
	  *--dbl_pt1 = dbl_first;
	  *++dbl_pt2 = dbl_last;
	}
      }
      /*
       * Processing the line.
       */
      if ( RecursiveFilter1D( RFC, theLine, resLine, tmpLine, resLine, lengthZ ) == 0 ) {
	if ( _VERBOSE_ != 0 ) 
	  fprintf(stderr," Error in %s: unable to process Z line (x=%d,y=%d).\n", proc, x, y);
	if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
	  free( bufferResult );
	free( (void*)theLine );
	return( EXIT_ON_FAILURE );
      }
      
      /*
       * Copy the result into the buffer bufferResult.
       */
      dbl_pt1 = resLinePlusBorder;
      switch ( typeResult ) {
      case CGAL_DOUBLE :
	r64_pt = r64firstPointResult;
	for ( z=0; z<dimz; z++, dbl_pt1++, r64_pt += dimxXdimy ) 
	  *r64_pt = *dbl_pt1;
	r64firstPointResult ++;
	break;
      case CGAL_FLOAT :
      default :
	r32_pt = r32firstPointResult;
	for ( z=0; z<dimz; z++, dbl_pt1++, r32_pt += dimxXdimy ) 
	  *r32_pt = (float)*dbl_pt1;
	r32firstPointResult ++;
      }
    }

    free( RFC );
    RFC = NULL;

  } /* end of Processing along Z. */
  



  /*
   * From bufferResult to bufferOut
   */
  ConvertBuffer( bufferResult, typeResult, bufferOut, typeOut, (dimx*dimy*dimz) );

  /*
   * Releasing the buffers.
   */
  if ( (typeOut != CGAL_FLOAT) && (typeOut != CGAL_DOUBLE) )
    free( bufferResult );
  free( (void*)theLine );
  
  return( EXIT_ON_SUCCESS );
}
Esempio n. 7
0
/*
 *
 * Laplacian
 *
 *
 */
int Laplacian_2D ( void *bufferIn,
		   bufferType typeIn,
		   void *bufferOut,
		   bufferType typeOut,
		   int *bufferDims,
		   int *borderLengths,
		   float *filterCoefs,
		   recursiveFilterType filterType )
{
  const char *proc = "Laplacian_2D";
  float *theXX = NULL;
  float *theYY = NULL;

  derivativeOrder XXderiv[3] = { DERIVATIVE_2, SMOOTHING, NODERIVATIVE };
  derivativeOrder YYderiv[3] = { SMOOTHING, DERIVATIVE_2, NODERIVATIVE };
  int sliceDims[3];
  int z, i, dimxXdimy;

  void *sliceOut = NULL;



  /* 
   * We check the buffers' dimensions.
   */
  if ( (bufferDims[0] <= 0) || (bufferDims[1] <= 0) || (bufferDims[2] <= 0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: improper buffer's dimension.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  
  /*
   * test of the coefficients
   */
  if ( (filterCoefs[0] < 0.0) || (filterCoefs[1] < 0.0) ||
       (filterCoefs[2] < 0.0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Error in %s: negative coefficient's value.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  

  /*
   *
   */
  dimxXdimy = bufferDims[0] * bufferDims[1];
  sliceDims[0] = bufferDims[0];
  sliceDims[1] = bufferDims[1];
  sliceDims[2] = 1;
  

  if ( typeOut == CGAL_FLOAT ) {
    theXX = (float*)malloc( dimxXdimy * sizeof( float ) );
  } else {
    theXX = (float*)malloc( 2 * dimxXdimy * sizeof( float ) );
  }
  
  if ( theXX == NULL ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to allocate auxiliary buffer.\n" );
    }
    return( EXIT_ON_FAILURE );
  }

  if ( typeOut != CGAL_FLOAT ) {
    theYY  = theXX;
    theYY += dimxXdimy;
  }
  
  
  
  for ( z=0; z<bufferDims[2]; z++ ) {

    if ( typeOut == CGAL_FLOAT ) {
      theYY = ((float*)bufferOut) + z * dimxXdimy;
    }
    
    if ( RecursiveFilterOnBuffer( bufferIn, typeIn, theXX, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  XXderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X^2 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }

    if ( RecursiveFilterOnBuffer( bufferIn, typeIn, theYY, CGAL_FLOAT, 
				  sliceDims, borderLengths,
				  YYderiv, filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y^2 derivative.\n" );
      }
      free( theXX );
      return( EXIT_ON_FAILURE );
    }
    
    
    for ( i=0; i<dimxXdimy; i++ ) theYY[i] += theXX[i];
    if ( typeOut != CGAL_FLOAT ) {
      switch ( typeOut ) {
      case CGAL_UCHAR :
	sliceOut = (((u8*)bufferOut) + z * dimxXdimy);
	break;
      case CGAL_SCHAR :
	sliceOut = (((s8*)bufferOut) + z * dimxXdimy);
	break;
      case CGAL_SSHORT :
	sliceOut = (((s16*)bufferOut) + z * dimxXdimy);
	break;
      case CGAL_DOUBLE :
	sliceOut = (((r64*)bufferOut) + z * dimxXdimy);
	break;
      default :
	if ( _VERBOSE_ > 0 )
	  fprintf( stderr, " Error in %s: such output type not handled.\n", proc );
	free( theXX );
	return( EXIT_ON_FAILURE );
      }
      ConvertBuffer( theYY, CGAL_FLOAT, sliceOut, typeOut, dimxXdimy );
    }
  }

  return( EXIT_ON_SUCCESS );
}
Esempio n. 8
0
int CSplineFilterOnBufferWithCoefficients( typeCSplineCoefficients *theCoeff,
                                           void *bufferOut, /* output buffer */
                                           bufferType typeOut, /* type of the output buffer */
                                           int *derivative /* order of derivatives to be computed */
                                           )
{
  char *proc ="CSplineFilterOnBufferWithCoefficients";
  double (*bsplinx)(double);
  double (*bspliny)(double);
  double (*bsplinz)(double) = NULL;

  int dimx = theCoeff->theDim[0]-2;
  int dimy = theCoeff->theDim[1]-2;
  int dimz;

  int    i, j, n;
  int    o[27];
  double r, cx[3], cy[3], cz[3], c[27];
  
  float *tmpBuf = NULL;
  float *coeBuf = theCoeff->theCoeff;

  int x, y, z;



  /* dimensions selon Z
     les bords ont ete dupliques dans l'image des
     coefficients
   */
  if ( theCoeff->theDim[2] == 1 ) dimz = 1;
  else dimz = theCoeff->theDim[2]-2;



  switch( derivative[0] ) {
  default :
    if ( _verbose_ ) 
      fprintf( stderr, "%s: invalid derivation order in x\n", proc );
    return( -1 );
  case 0 :
    bsplinx = &CubicBspline;            break;
  case 1 :
    bsplinx = &CubicBspline_FirstDeriv; break;
  case 2:
    bsplinx = &CubicBspline_SecndDeriv; break;
  }

  switch( derivative[1] ) {
  default :
    if ( _verbose_ ) 
      fprintf( stderr, "%s: invalid derivation order in y\n", proc );
    return( -1 );
  case 0 :
    bspliny = &CubicBspline;            break;
  case 1 :
    bspliny = &CubicBspline_FirstDeriv; break;
  case 2:
    bspliny = &CubicBspline_SecndDeriv; break;
  }

  if ( dimz > 1 ) {
    switch( derivative[2] ) {
    default :
      if ( _verbose_ ) 
        fprintf( stderr, "%s: invalid derivation order in z\n", proc );
      return( -1 );
    case 0 :
      bsplinz = &CubicBspline;            break;
    case 1 :
      bsplinz = &CubicBspline_FirstDeriv; break;
    case 2:
      bsplinz = &CubicBspline_SecndDeriv; break;
    }
  }
  


  /* Pre-calcul des coefficients
     coeff[0] = bspline(  1 );
     coeff[1] = bspline(  0 );
     coeff[2] = bspline( -1 );
     Question: c'est inverse ?
  */
  for ( i = 0; i < 3; i ++ ) {
    cx [i] = (*bsplinx) ( (double)(1-i) );
    cy [i] = (*bspliny) ( (double)(1-i) );
  }
  if ( dimz > 1 ) {
    for ( i = 0; i < 3; i ++ )
      cz [i] = (*bsplinz) ( (double)(1-i) );
  }
  

  /* calcul des coefficients
     et des offsets associes
  */

  if ( dimz > 1 ) {
    for ( i=0, z=0; z<3; z++ )
    for ( y=0; y<3; y++ )
    for ( x=0; x<3; x++, i++ ) {
      c[i] = cx[x] * cy[y] * cz[z];
      o[i] = (z-1)*theCoeff->theDim[0]*theCoeff->theDim[1] +
             (y-1)*theCoeff->theDim[0] + (x-1);
    }
    n = 27;
  } else {
    for ( i=0, y=0; y<3; y++ )
    for ( x=0; x<3; x++, i++ ) {
      c[i] = cx[x] * cy[y];
      o[i] = (y-1)*theCoeff->theDim[0] + (x-1);
    }
    n = 9;
  }



  /*
  if ( 1 ) {
    fprintf( stderr, "\n" );
    for ( i=0; i<n; i++ ) {
      fprintf( stderr, " #[%4d]=%f ", o[i], c[i] );
      if ( (i+1)%3 == 0 ) fprintf( stderr, "\n" );
      if ( (i+1)%9 == 0 ) fprintf( stderr, "\n" );
    }
    fprintf( stderr, "\n" );
  }
  */



  if ( typeOut != FLOAT ) {
    tmpBuf = (float*)malloc( dimx*dimy* sizeof(float) );
    if ( tmpBuf == NULL ) {
      if ( _verbose_ )
        fprintf( stderr, "%s: unable to allocate auxiliary buffer\n", proc );
      return( -1 );
    }
  }


  /* cas 3D, on saute le premier plan 
   */
  if ( dimz > 1 ) coeBuf += theCoeff->theDim[0]*theCoeff->theDim[1];

  for ( z=0; z<dimz; z++ ) {

    if ( typeOut == FLOAT ) tmpBuf = &((float*)bufferOut)[z*dimx*dimy];
    
    coeBuf += theCoeff->theDim[0] + 1;

    for ( j=0, y=0; y<dimy; y++, coeBuf+=2 ) {
      for ( x=0; x<dimx; x++, coeBuf++, j++ ) {
        for (r=0.0, i=0; i<n; i++ )
          r += c[i] * coeBuf[ o[i] ];
        tmpBuf[j] = (float)r;
      }
    }

    coeBuf += dimx+1;

    if ( typeOut != FLOAT ) {
      switch ( typeOut ) {
      default :
        free( tmpBuf );
        if ( _verbose_ )
          fprintf( stderr, "%s: such output type not handled in switch\n", proc );
        return( -1 );
      case UCHAR :
        if ( ConvertBuffer( tmpBuf, FLOAT, &((u8*)bufferOut)[z*dimx*dimy],
                            typeOut, dimx*dimy ) != 1 ) {
          free( tmpBuf );
          if ( _verbose_ )
            fprintf( stderr, "%s: unable to convert such image type\n", proc );
          return( -1 );
        }
        break;
      case SCHAR :
        if ( ConvertBuffer( tmpBuf, FLOAT, &((s8*)bufferOut)[z*dimx*dimy],
                            typeOut, dimx*dimy ) != 1 ) {
          free( tmpBuf );
          if ( _verbose_ )
            fprintf( stderr, "%s: unable to convert such image type\n", proc );
          return( -1 );
        }
        break;
      case USHORT :
        if ( ConvertBuffer( tmpBuf, FLOAT, &((u16*)bufferOut)[z*dimx*dimy],
                            typeOut, dimx*dimy ) != 1 ) {
          free( tmpBuf );
          if ( _verbose_ )
            fprintf( stderr, "%s: unable to convert such image type\n", proc );
          return( -1 );
        }
        break;
      case SSHORT :
        if ( ConvertBuffer( tmpBuf, FLOAT, &((s16*)bufferOut)[z*dimx*dimy],
                            typeOut, dimx*dimy ) != 1 ) {
          free( tmpBuf );
          if ( _verbose_ )
            fprintf( stderr, "%s: unable to convert such image type\n", proc );
          return( -1 );
        }
      }
    }
  }




  if ( typeOut != FLOAT ) free( tmpBuf );
  return( 1 );
}
Esempio n. 9
0
int ReechCSpline4x4( void* theBuf, bufferType theType, int *theDim,
                              void* resBuf, bufferType resType, int *resDim,
                              double *mat,
                              int *derivative )
{
  char *proc = "Reech3DCSpline4x4";
  typeCSplineCoefficients *c;
  r32 *resSlice = NULL;
  int z;

  c = ComputeCSplineCoefficients( theBuf, theType, theDim );
  if ( c == NULL ) {
    if( _verbose_ )
      fprintf( stderr, "%s: unable to compute cubic spline coefficients.\n", proc );
    return( -1 );
  }
  


  if ( resType != FLOAT ) {
    resSlice = (r32*)malloc( resDim[0]*resDim[1]*sizeof( r32 ) );
    if ( resSlice == NULL ) {
      FreeTypeCSplineCoefficients( &c );
      if( _verbose_ )
        fprintf( stderr, "%s: unable to allocate auxiliary slice\n", proc );
      return( -1 );
    }
  }
  
  
  for ( z = 0; z < resDim[2]; z ++ ) {

    if ( resType == FLOAT ) {
      resSlice  = resBuf;
      resSlice += z*resDim[0]*resDim[1];
    }

    if ( theDim[2] > 1 ) {
      if ( Reech3DCSpline4x4WithCoefficients( c, resSlice, resDim, mat,
                                            z, derivative ) != 1 ) {
        FreeTypeCSplineCoefficients( &c );
        if ( resType != FLOAT ) free( resSlice );
        if( _verbose_ )
          fprintf( stderr, "%s: unable to compute 3D slice #%d\n", proc, z );
      }
    } else {
      if ( Reech2DCSpline4x4WithCoefficients( c, resSlice, resDim, mat,
                                              derivative ) != 1 ) {
        FreeTypeCSplineCoefficients( &c );
        if ( resType != FLOAT ) free( resSlice );
        if( _verbose_ )
          fprintf( stderr, "%s: unable to compute 2D slice #%d\n", proc, z );
      }
    }

    if ( resType != FLOAT ) {
      switch( resType ) {
      default :
        FreeTypeCSplineCoefficients( &c );
        if ( resType != FLOAT ) free( resSlice );
        if ( _verbose_ )
          fprintf( stderr, "%s: such output type not handled in switch\n", proc );
        return( -1 );
      case UCHAR :
        if ( ConvertBuffer( resSlice, FLOAT, &((u8*)resBuf)[z*resDim[0]*resDim[1]],
                            resType, resDim[0]*resDim[1] ) != 1 ) {
          if ( resType != FLOAT ) free( resSlice );
          if ( _verbose_ )
            fprintf( stderr, "%s: unable to convert such image type\n", proc );
          return( -1 );
        }
        break;
      case SCHAR :
        if ( ConvertBuffer( resSlice, FLOAT, &((s8*)resBuf)[z*resDim[0]*resDim[1]],
                            resType, resDim[0]*resDim[1] ) != 1 ) {
          if ( resType != FLOAT ) free( resSlice );
          if ( _verbose_ )
            fprintf( stderr, "%s: unable to convert such image type\n", proc );
          return( -1 );
        }
        break;
      case USHORT :
        if ( ConvertBuffer( resSlice, FLOAT, &((u16*)resBuf)[z*resDim[0]*resDim[1]],
                            resType, resDim[0]*resDim[1] ) != 1 ) {
          if ( resType != FLOAT ) free( resSlice );
          if ( _verbose_ )
            fprintf( stderr, "%s: unable to convert such image type\n", proc );
          return( -1 );
        }
        break;
      case SSHORT :
        if ( ConvertBuffer( resSlice, FLOAT, &((s16*)resBuf)[z*resDim[0]*resDim[1]],
                            resType, resDim[0]*resDim[1] ) != 1 ) {
          if ( resType != FLOAT ) free( resSlice );
          if ( _verbose_ )
            fprintf( stderr, "%s: unable to convert such image type\n", proc );
          return( -1 );
        }
        break;
      }
    }
  }

  FreeTypeCSplineCoefficients( &c );
  if ( resType != FLOAT ) free( resSlice );

  return( 1 );
}
Esempio n. 10
0
int Extract_Gradient_Maxima_2D( void *bufferIn,
				bufferType typeIn,
				void *bufferOut,
				bufferType typeOut,
				int *bufferDims,
				int *borderLengths,
				float *filterCoefs,
				recursiveFilterType filterType )
{
  char *proc="Extract_Gradient_Maxima_2D";
  /*
   * auxiliary buffer
   */ 
  float *tmpBuffer = (float*)NULL;
  /*
   * Pointers
   */
  float *gx = (float*)NULL;
  float *gy = (float*)NULL;
  float *norme = (float*)NULL;
  void *sliceIn = (void*)NULL;
  void *sliceOut = (void*)NULL;
  /*
   * additional parameters for recursive filtering
   */
  derivativeOrder Xgradient[3] = { DERIVATIVE_1_EDGES, SMOOTHING, NODERIVATIVE };
  derivativeOrder Ygradient[3] = { SMOOTHING, DERIVATIVE_1_EDGES, NODERIVATIVE };
  int sliceDims[3];
  /*
   *
   */
  int z, dimxXdimy;

  /* 
   * We check the buffers' dimensions.
   */
  if ( (bufferDims[0] <= 0) || (bufferDims[1] <= 0) || (bufferDims[2] <= 0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: improper buffer's dimension.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  dimxXdimy = bufferDims[0] * bufferDims[1];
  sliceDims[0] = bufferDims[0];
  sliceDims[1] = bufferDims[1];
  sliceDims[2] = 1;
  
  /*
   * test of the coefficients
   */
  if ( (filterCoefs[0] < 0.0) || (filterCoefs[1] < 0.0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Error in %s: negative coefficient's value.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  
  /* 
   * Allocation of auxiliary buffer.
   * We need a slice buffer for each gradients' component
   * plus one for the modulus.
   */
  tmpBuffer = (float*)malloc( 3 * dimxXdimy * sizeof( float ) );
  if ( tmpBuffer == (float*)NULL ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: unable to allocate auxiliary buffer.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  norme = tmpBuffer;
  gy = norme + dimxXdimy;
  gx = gy + dimxXdimy;
  
  /* 
   * slice by slice processing.
   *
   * For each slice, we compute both the X and Y
   * components of the gradient, its modulus,
   * and we suppress the non-maxima of the
   * gradient. Finally, we put the result
   * in the buffer bufferOut.
   *
   * An other solution may consist in computing
   * the  X and Y components of the gradient
   * for the whole 3D buffer, and performing 
   * the non-maxima suppression slice 
   * by slice.
   */
  for ( z=0; z<bufferDims[2]; z++ ) {
    if ( (_VERBOSE_ > 0) && (bufferDims[2] > 1) ) {
      fprintf( stderr, " %s: Processing slice #%d.\n", proc, z );
    }
    sliceIn = (void*)NULL;
    /*
     * sliceIn points towards the slice #z of
     * the buffer bufferIn.
     */
    switch( typeIn ) {
    case UCHAR :
      sliceIn = (((u8*)bufferIn) + z * dimxXdimy);
      break;
    case SCHAR :
      sliceIn = (((s8*)bufferIn) + z * dimxXdimy);
      break;
    case USHORT :
      sliceIn = (((u16*)bufferIn) + z * dimxXdimy);
      break;
    case SSHORT :
      sliceIn = (((s16*)bufferIn) + z * dimxXdimy);
      break;
    case INT :
      sliceIn = (((i32*)bufferIn) + z * dimxXdimy);
      break;
    case FLOAT :
      sliceIn = (((r32*)bufferIn) + z * dimxXdimy);
      break;
    case DOUBLE :
      sliceIn = (((r64*)bufferIn) + z * dimxXdimy);
      break;
    default :
      if ( _VERBOSE_ > 0 )
	fprintf( stderr, " Error in %s: such input type not handled.\n", proc );
      free( tmpBuffer );
      return( EXIT_ON_FAILURE );
    }
    /*
     * computing the X and Y component
     * of the gradient.
     */
    if ( RecursiveFilterOnBuffer( sliceIn, typeIn, gx, FLOAT,
				  sliceDims, borderLengths,
				  Xgradient, filterCoefs,
				  filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X gradient for slice #%d.\n", z );
      }
      free( tmpBuffer );
      return( EXIT_ON_FAILURE );
    }
    if ( RecursiveFilterOnBuffer( sliceIn, typeIn, gy, FLOAT,
				  sliceDims, borderLengths,
				  Ygradient, filterCoefs,
				  filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y gradient for slice #%d.\n", z );
      }
      free( tmpBuffer );
      return( EXIT_ON_FAILURE );
    }
    /*
     * Modulus of the gradient
     */ 
    GradientModulus2D( norme, gx, gy, dimxXdimy );

    /*
     * Suppression of the non maxima of the gradient
     * in the direction of the gradient.
     *
     * If the type of the result buffer bufferOut is
     * FLOAT, then we compute directly the result
     * into the slice #z of the result buffer.
     * Else, we compute the suppression of the
     * non maxima into the gx buffer, and we 
     * convert it into the result buffer type.
     */
    if (typeOut == FLOAT ) {
      sliceOut = (((float*)bufferOut) + z * dimxXdimy);
      Remove_Gradient_NonMaxima_Slice_2D( sliceOut, gx ,gy,
					  norme, sliceDims );
    } else {
      Remove_Gradient_NonMaxima_Slice_2D( gx, gx ,gy,
					  norme, sliceDims );
      switch( typeOut ) {
      case UCHAR :
	sliceOut = (((u8*)bufferOut) + z * dimxXdimy);
	break;
      case SCHAR :
	sliceOut = (((s8*)bufferOut) + z * dimxXdimy);
	break;
      case USHORT :
	sliceOut = (((u16*)bufferOut) + z * dimxXdimy);
	break;
      case SSHORT :
	sliceOut = (((s16*)bufferOut) + z * dimxXdimy);
	break;
      case INT :
	sliceOut = (((i32*)bufferOut) + z * dimxXdimy);
	break;
      case DOUBLE :
	sliceOut = (((r64*)bufferOut) + z * dimxXdimy);
	break;
      default :
	if ( _VERBOSE_ > 0 )
	  fprintf( stderr, " Error in %s: such output type not handled.\n", proc );
	free( tmpBuffer );
	return( EXIT_ON_FAILURE );
      }
      ConvertBuffer( gx, FLOAT, sliceOut, typeOut, dimxXdimy);
    }
  }


  free( tmpBuffer );
  return( EXIT_ON_SUCCESS );
}
Esempio n. 11
0
int Extract_Gradient_Maxima_3D( void *bufferIn,
				bufferType typeIn,
				void *bufferOut,
				bufferType typeOut,
				int *bufferDims,
				int *borderLengths,
				float *filterCoefs,
				recursiveFilterType filterType )
{
  char *proc="Extract_Gradient_Maxima_3D";
  /*
   * auxiliary buffer
   */ 
  float *tmpBuffer = (float*)NULL;
  float *bufferZsmoothed = (float*)NULL;
  float *bufferZderivated = (float*)NULL;
  /*
   * Pointers
   */
  /* 
   * gx[0] points toward the X gradient of the current slice
   * gx[0] points toward the X gradient of the next slice
   */
  float *gx[2] = { (float*)NULL, (float*)NULL };
  /*
   * gy: idem gx but for the Y gradient
   */
  float *gy[2] = { (float*)NULL, (float*)NULL };
  float *gz = (float*)NULL;
  /*
   * norme[0] points toward the gradient modulus of the previous slice
   * norme[1] points toward the gradient modulus of the current slice
   * norme[2] points toward the gradient modulus of the next slice
   */
  float *norme[3] = { (float*)NULL, (float*)NULL, (float*)NULL }; 
  float *sliceZsmoothed = (float*)NULL;
  float *pt = (float*)NULL;
  /*
   * additional parameters for recursive filtering
   */
  derivativeOrder Xgradient[3] = { DERIVATIVE_1_EDGES, SMOOTHING, NODERIVATIVE };
  derivativeOrder Ygradient[3] = { SMOOTHING, DERIVATIVE_1_EDGES, NODERIVATIVE };
  derivativeOrder Zgradient[3] = { SMOOTHING, SMOOTHING, DERIVATIVE_1_EDGES };
  derivativeOrder Zsmoothing[3] = { NODERIVATIVE, NODERIVATIVE, SMOOTHING };
  int sliceDims[3];
  /*
   *
   */
  int z, dimxXdimy;

  /* 
   * We check the buffers' dimensions.
   */
  if ( (bufferDims[0] <= 0) || (bufferDims[1] <= 0) || (bufferDims[2] <= 0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Fatal error in %s: improper buffer's dimension.\n", proc );
    return( EXIT_ON_FAILURE );
  }

  /*
   * May we perform a 3D edge detection?
   */
  if ( bufferDims[2] <= 4 ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Warning in %s: switch to 2D edge extraction.\n", proc );
    return( Extract_Gradient_Maxima_2D( bufferIn, typeIn,
					bufferOut, typeOut,
					bufferDims, borderLengths,
					filterCoefs, filterType ) );
  }

  /*
   *
   */
  dimxXdimy = bufferDims[0] * bufferDims[1];
  sliceDims[0] = bufferDims[0];
  sliceDims[1] = bufferDims[1];
  sliceDims[2] = 1;
  
  /*
   * test of the coefficients
   */
  if ( (filterCoefs[0] < 0.0) || (filterCoefs[1] < 0.0) ||
       (filterCoefs[2] < 0.0) ) {
    if ( _VERBOSE_ > 0 )
      fprintf( stderr, " Error in %s: negative coefficient's value.\n", proc );
    return( EXIT_ON_FAILURE );
  }
  
  /* 
   * Allocation of auxiliary buffers.
   *
   * We need a 3D buffer for the Z component of the
   * gradient, plus a 3D buffer for the 3D buffer 
   * smoothed along Z, plus 7 2D buffers for the
   * X component of the gradient in both the current
   * and the next slices, idem for the Y component,
   * idem for the modulus plus one 2D buffer for
   * the modulua in the previous slice.
   *
   * If the buffer bufferOut is of type FLOAT,
   * we use it as the Z component of the gradient.
   *
   * This Z component will be used to stored the
   * extrema of the gradient.
   */
  tmpBuffer = (float*)malloc( 7 * dimxXdimy * sizeof( float ) );
  if ( tmpBuffer == (float*)NULL ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to allocate auxiliary buffer.\n" );      
    }
    return( EXIT_ON_FAILURE );
  }
  gx[0] = tmpBuffer;
  gx[1] = gx[0] + dimxXdimy;
  gy[0] = gx[1] + dimxXdimy;
  gy[1] = gy[0] + dimxXdimy;
  norme[0] = gy[1] + dimxXdimy;
  norme[1] = norme[0] + dimxXdimy;
  norme[2] = norme[1] + dimxXdimy;
  
  bufferZsmoothed = (float*)malloc( bufferDims[2] * dimxXdimy * sizeof( float ) );
  if ( bufferZsmoothed == (float*)NULL ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to allocate auxiliary first 3D buffer.\n" );
    }
    free( tmpBuffer );
    return( EXIT_ON_FAILURE );
  }
  
  if ( typeOut == FLOAT ) {
    bufferZderivated = bufferOut;
  } else {
    bufferZderivated = (float*)malloc( bufferDims[2] * dimxXdimy * sizeof( float ) );
    if ( bufferZderivated == (float*)NULL ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to allocate auxiliary first 3D buffer.\n" );
      }
      free( tmpBuffer );
      free( bufferZsmoothed );
      return( EXIT_ON_FAILURE );
    }
  }
  
  /* 
   * Computation of the Z component of the gradient.
   * Computation of the input buffer smoothed along Z.
   */
  if ( RecursiveFilterOnBuffer( bufferIn, typeIn,
				bufferZderivated, FLOAT,
				bufferDims, borderLengths,
				Zgradient, filterCoefs,
				filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Z gradient.\n" );
    }
    free( tmpBuffer );
    free( bufferZsmoothed );
    if ( typeOut != FLOAT ) free( bufferZderivated );
    return( EXIT_ON_FAILURE );
  }

  if ( RecursiveFilterOnBuffer( bufferIn, typeIn,
				bufferZsmoothed, FLOAT,
				bufferDims, borderLengths,
				Zsmoothing, filterCoefs,
				filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Z gradient.\n" );
    }
    free( tmpBuffer );
    free( bufferZsmoothed );
    if ( typeOut != FLOAT ) free( bufferZderivated );
    return( EXIT_ON_FAILURE );
  }
  
  /*
   * First slice: extraction of 2D edges.
   *
   * - computation of the X component of the gradient
   *   for that slice
   * - idem for the Y component of the gradient
   * - computation of the modulus
   * - suppression of the 2D non maxima of the gradient
   */
  sliceZsmoothed = bufferZsmoothed;
  gz = bufferZderivated;
  if ( RecursiveFilterOnBuffer( sliceZsmoothed, FLOAT,
				gx[0], FLOAT, sliceDims, 
				borderLengths, Xgradient,
				filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute X gradient of the first slice.\n" );
    }
    free( tmpBuffer );
    free( bufferZsmoothed );
    if ( typeOut != FLOAT ) free( bufferZderivated );
    return( EXIT_ON_FAILURE );
  }
  if ( RecursiveFilterOnBuffer( sliceZsmoothed, FLOAT,
				gy[0], FLOAT, sliceDims, 
				borderLengths, Ygradient,
				filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Y gradient of the first slice.\n" );
    }
    free( tmpBuffer );
    free( bufferZsmoothed );
    if ( typeOut != FLOAT ) free( bufferZderivated );
    return( EXIT_ON_FAILURE );
  }
  GradientModulus3D( norme[1], gx[0], gy[0], gz, dimxXdimy );
  Remove_Gradient_NonMaxima_Slice_2D( gz, gx[0], gy[0],
				      norme[1], sliceDims );
   
  /*
   * The first slice is already processed.
   * 
   * We prepare the processing of the next slice.
   * - computation of the X component of the gradient
   *   for that slice
   * - idem for the Y component of the gradient
   * - computation of the modulus
   */
  sliceZsmoothed += dimxXdimy;
  gz += dimxXdimy;
  if ( RecursiveFilterOnBuffer( sliceZsmoothed, FLOAT,
				gx[1], FLOAT, sliceDims, 
				borderLengths, Xgradient,
				filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute X gradient of the second slice.\n" );
    }
    free( tmpBuffer );
    free( bufferZsmoothed );
    if ( typeOut != FLOAT ) free( bufferZderivated );
    return( EXIT_ON_FAILURE );
  }
  if ( RecursiveFilterOnBuffer( sliceZsmoothed, FLOAT,
				gy[1], FLOAT, sliceDims, 
				borderLengths, Ygradient,
				filterCoefs, filterType ) == 0 ) {
    if ( _VERBOSE_ > 0 ) {
      fprintf( stderr, " Fatal error in %s:", proc );
      fprintf( stderr, " unable to compute Y gradient of the second slice.\n" );
    }
    free( tmpBuffer );
    free( bufferZsmoothed );
    if ( typeOut != FLOAT ) free( bufferZderivated );
    return( EXIT_ON_FAILURE );
  }
  GradientModulus3D( norme[2], gx[1], gy[1], gz, dimxXdimy );
 
  /*
   * slice by slice processing 
   */
  for ( z=1; z<bufferDims[2]-1; z++ ) {
    /*
     * slices permutations
     */
    pt = gx[0]; gx[0] = gx[1]; gx[1] = pt;
    pt = gy[0]; gy[0] = gy[1]; gy[1] = pt;
    pt = norme[0]; norme[0] = norme[1]; 
    norme[1] = norme[2]; norme[2] = pt;
    /*
     * gx[0] and gy[0] are the X and Y components
     * of the gradient of the current slice.
     * gx[1] and gy[1] are the X and Y components
     * of the gradient of the next slice.
     * norme[0] is the gradient modulus of the previous slice,
     * norme[1] is the gradient modulus of the current slice,
     * norme[2] is the gradient modulus of the next slice.
     */
    /*
     * Processing of the next slice.
     * - computation of the X component of the gradient
     *   for that slice
     * - idem for the Y component of the gradient
     * - computation of the modulus
     */
    sliceZsmoothed += dimxXdimy;
    gz += dimxXdimy;
    if ( RecursiveFilterOnBuffer( sliceZsmoothed, FLOAT,
				  gx[1], FLOAT, sliceDims, 
				  borderLengths, Xgradient,
				  filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute X gradient of slice #%d.\n", z+1 );
      }
      free( tmpBuffer );
      free( bufferZsmoothed );
      if ( typeOut != FLOAT ) free( bufferZderivated );
      return( EXIT_ON_FAILURE );
    }
    if ( RecursiveFilterOnBuffer( sliceZsmoothed, FLOAT,
				  gy[1], FLOAT, sliceDims, 
				  borderLengths, Ygradient,
				  filterCoefs, filterType ) == 0 ) {
      if ( _VERBOSE_ > 0 ) {
	fprintf( stderr, " Fatal error in %s:", proc );
	fprintf( stderr, " unable to compute Y gradient of slice #%d.\n", z+1 );
      }
      free( tmpBuffer );
      free( bufferZsmoothed );
      if ( typeOut != FLOAT ) free( bufferZderivated );
      return( EXIT_ON_FAILURE );
    }
    GradientModulus3D( norme[2], gx[1], gy[1], gz, dimxXdimy );
    /*
     * suppression of the 3D non maxima of the gradient.
     */
    gz -= dimxXdimy;
    Remove_Gradient_NonMaxima_Slice_3D( gz, gx[0], gy[0], gz, norme, sliceDims );
    gz += dimxXdimy;
  }

  /*
   * last slice 
   * 
   * Components and moduls of the gradient are 
   * already computed.
   *
   * - 2D suppression of the non maxima
   */
  Remove_Gradient_NonMaxima_Slice_2D( gz, gx[1], gy[1],
				      norme[2], sliceDims );
  /*
   * conversion of the buffer bufferZderivated of type FLOAT
   * into the buffer bufferOut.
   */
  
  if (typeOut != FLOAT ) {
    ConvertBuffer( bufferZderivated, FLOAT, 
		   bufferOut, typeOut, bufferDims[2]*dimxXdimy);
  }

  free( tmpBuffer );
  free( bufferZsmoothed );
  if ( typeOut != FLOAT ) free( bufferZderivated );
  return( EXIT_ON_SUCCESS );
}
int gradientHessianGradient2D( void *bufferIn,
                       bufferType typeIn,
                       void *bufferOut,
                       bufferType typeOut,
                       int *bufferDims,
                       int *borderLengths,
                       typeFilteringCoefficients *theFilter )
{
  char *proc = "gradientHessianGradient2D";
  size_t dimx, dimy, dimz;
  size_t sizeAuxBuf = 0;
  typeFilteringCoefficients filter[3];

  float *theXX = NULL;
  float *theYY = NULL;
  float *theXY = NULL;
  float *theX  = NULL;
  float *theY  = NULL;
  float *theH  = NULL;
  double g;
  long int i;

  dimx = bufferDims[0];
  dimy = bufferDims[1];
  dimz = bufferDims[2];


  /* we could spare one buffer,
     but who cares?
  */
  sizeAuxBuf = (size_t)5 * dimx*dimy*dimz;
  if ( typeOut != FLOAT || bufferIn == bufferOut )
    sizeAuxBuf += dimx*dimy*dimz;


  /* allocation des buffers de calcul
   */
  theXX = (float*)malloc( sizeAuxBuf * sizeof(float) );
  if ( theXX == NULL ) {
    if ( _verbose_ > 0 )
      fprintf( stderr, "%s: unable to allocate auxiliary buffer\n", proc );
    return( -1 );
  }

  sizeAuxBuf = dimx*dimy*dimz;
  theYY = theXY = theX = theY = theH = theXX;
  theYY +=   sizeAuxBuf;
  theXY += 2*sizeAuxBuf;
  theX  += 3*sizeAuxBuf;
  theY  += 4*sizeAuxBuf;
  
  if ( typeOut != FLOAT || bufferIn == bufferOut ) {
    theH  += 5*sizeAuxBuf;
  } else {
    theH  = (float*)bufferOut;
  }



  /* filtering
   */
  filter[0] = theFilter[0];
  filter[1] = theFilter[1];
  filter[2] = theFilter[2];
    
  /* smoothing along Y 
   */
  filter[0].derivative = NODERIVATIVE;
  filter[1].derivative = DERIVATIVE_0;
  filter[2].derivative = NODERIVATIVE;
  if ( separableLinearFiltering( bufferIn, typeIn, (void*)theXX, FLOAT,
                                 bufferDims, borderLengths, filter ) != 1 ) {
    if ( _verbose_ ) 
      fprintf( stderr, "%s: unable to compute Y smoothing (2D)\n", proc );
    free( theXX );
    return( -1 );
  }

  /* 1st derivative along X 
   */
  filter[0].derivative = DERIVATIVE_1;
  filter[1].derivative = NODERIVATIVE;
  filter[2].derivative = NODERIVATIVE;
  if ( separableLinearFiltering( (void*)theXX, FLOAT, (void*)theX, FLOAT,
                                 bufferDims, borderLengths, filter ) != 1 ) {
    if ( _verbose_ ) 
      fprintf( stderr, "%s: unable to compute X 1st derivative (2D)\n", proc );
    free( theXX );
    return( -1 );
  }
  
  /* 2nd derivative along X 
   */
  filter[0].derivative = DERIVATIVE_2;
  filter[1].derivative = NODERIVATIVE;
  filter[2].derivative = NODERIVATIVE;
  if ( separableLinearFiltering( (void*)theXX, FLOAT, (void*)theXX, FLOAT,
                                 bufferDims, borderLengths, filter ) != 1 ) {
    if ( _verbose_ ) 
      fprintf( stderr, "%s: unable to compute X 2nd derivative (2D)\n", proc );
    free( theXX );
    return( -1 );
  }


   
  /* smoothing along X 
   */
  filter[0].derivative = DERIVATIVE_0;
  filter[1].derivative = NODERIVATIVE;
  filter[2].derivative = NODERIVATIVE;
  if ( separableLinearFiltering( bufferIn, typeIn, (void*)theYY, FLOAT,
                                 bufferDims, borderLengths, filter ) != 1 ) {
    if ( _verbose_ ) 
      fprintf( stderr, "%s: unable to compute X smoothing (2D)\n", proc );
    free( theXX );
    return( -1 );
  }

  /* 1st derivative along Y 
   */
  filter[0].derivative = NODERIVATIVE;
  filter[1].derivative = DERIVATIVE_1;
  filter[2].derivative = NODERIVATIVE;
  if ( separableLinearFiltering( (void*)theYY, FLOAT, (void*)theY, FLOAT,
                                 bufferDims, borderLengths, filter ) != 1 ) {
    if ( _verbose_ ) 
      fprintf( stderr, "%s: unable to compute Y 1st derivative (2D)\n", proc );
    free( theXX );
    return( -1 );
  }
  
  /* 2nd derivative along Y 
   */
  filter[0].derivative = NODERIVATIVE;
  filter[1].derivative = DERIVATIVE_2;
  filter[2].derivative = NODERIVATIVE;
  if ( separableLinearFiltering( (void*)theYY, FLOAT, (void*)theYY, FLOAT,
                                 bufferDims, borderLengths, filter ) != 1 ) {
    if ( _verbose_ ) 
      fprintf( stderr, "%s: unable to compute Y 2nd derivative (2D)\n", proc );
    free( theXX );
    return( -1 );
  }



  /* 2nd derivative along X and Y 
   */
  filter[0].derivative = DERIVATIVE_1;
  filter[1].derivative = DERIVATIVE_1;
  filter[2].derivative = NODERIVATIVE;
  if ( separableLinearFiltering( bufferIn, typeIn, (void*)theXY, FLOAT,
                                 bufferDims, borderLengths, filter ) != 1 ) {
    if ( _verbose_ ) 
      fprintf( stderr, "%s: unable to compute XY 2nd derivative (2D)\n", proc );
    free( theXX );
    return( -1 );
  }



  sizeAuxBuf = dimx*dimy*dimz;
#ifdef _OPENMP
#pragma omp parallel for private( g )
#endif 
  for ( i = 0; i < (long int)sizeAuxBuf; i++ ) {
    theH[i] = theX[i] * ( theXX[i] * theX[i] + theXY[i] * theY[i] ) 
      + theY[i] * ( theXY[i] * theX[i] + theYY[i] * theY[i] );
    if ( 0 ) {
      g = theX[i] * theX[i] + theY[i] * theY[i];
      if ( g > 1e-10 ) theH[i] /= g;
    }
  }
  
  

  if ( theH != bufferOut ) {
    if ( ConvertBuffer( theH, FLOAT, bufferOut, typeOut, sizeAuxBuf ) != 1 ) {
      if ( _verbose_ ) 
        fprintf( stderr, "%s: unable to convert buffer\n", proc );
      free( theXX );
      return( -1 );
    }
  }

  free( theXX );

  return( 1 );
}