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; }
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 ); }
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 ); }
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 ); }
/* * * 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 ); }
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 ); }
/* * * 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 ); }
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 ); }
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 ); }
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 ); }
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 ); }