35 #ifndef AIMS_RESAMPLING_SPLINERESAMPLER_D_H
36 #define AIMS_RESAMPLING_SPLINERESAMPLER_D_H
49 #define EPSILON 1.192092896e-7
57 :
Resampler<T>(), _lastvolume( 0 ), _lasttime( -1 )
77 updateParameters( inVolume, t,
verbose);
78 return _splineCoefficients;
91 assert(t == _lasttime);
94 int order = this->getOrder();
96 int width = order + 1;
98 double *s = &_splineCoefficients( 0, 0, 0 );
102 normalizedInLocation = invTransform3d.
transform( outLocation );
104 float xf = round(normalizedInLocation[0]);
105 float yf = round(normalizedInLocation[1]);
106 float zf = round(normalizedInLocation[2]);
114 if ( ( xf >= 0 ) && ( xf < dimx ) &&
115 ( yf >= 0 ) && ( yf < dimy ) &&
116 ( zf >= 0 ) && ( zf < dimz ) )
118 int x =
static_cast<int>(xf);
119 int y =
static_cast<int>(yf);
120 int z =
static_cast<int>(zf);
122 std::vector< double > weightX( width ), weightY( width ), weightZ( width);
123 std::vector< int > foldX( width ), foldY( width ), foldZ( width );
125 double intensity, qi, qj;
141 z =
static_cast<int>(floor(normalizedInLocation[2]));
151 for ( k = 0; k < width; k++ )
154 weightZ[ k ] = getBSplineWeight( z + k,
155 normalizedInLocation[2] );
156 foldZ[ k ] = getFold( z + k, dimz ) *
157 ( &_splineCoefficients( 0, 0, 1 )
158 - &_splineCoefficients( 0 ) );
167 y =
static_cast<int>(floor(normalizedInLocation[1]));
177 for ( j = 0; j < width; j++ )
180 weightY[ j ] = getBSplineWeight( y + j, normalizedInLocation[1] );
181 foldY[ j ] = getFold( y +j, dimy )
182 * ( &_splineCoefficients( 0, 1 ) - &_splineCoefficients( 0 ) );
189 x =
static_cast<int>(floor(normalizedInLocation[0]));
199 for ( i = 0; i < width; i++ )
202 weightX[ i ] = getBSplineWeight( x + i, normalizedInLocation[0] );
203 foldX[ i ] = getFold( x + i, dimx );
208 for ( k = 0; k < ( ( dimz == 1 ) ? 1 : width ); k++ )
213 for ( j = 0; j < width; j++ )
216 pi = pj + foldY[ j ];
218 for ( i = 0; i < width; i++ )
221 qi += weightX[ i ] * ( double )*( pi + foldX[ i ] );
224 qj += weightY[ j ] * qi;
227 intensity += weightZ[ k ] * qj;
251 outValue = outBackground;
262 int t,
bool verbose )
const
265 if ( ( &inVolume != _lastvolume || t != _lasttime )
266 && this->getOrder() > 1 )
272 std::cout <<
"[ updating spline coefficients : " << std::flush;
276 std::vector<int> dims = inVolume.
getSize();
277 int inSizeX = dims[0];
278 int inSizeY = dims[1];
279 int inSizeZ = dims[2];
285 _splineCoefficients->header().setProperty(
"voxel_size",
293 for ( z = 0; z < inSizeZ; z++ )
294 for ( y = 0; y < inSizeY; y++ )
296 q = &inVolume.
at( 0, y, z, t );
297 for ( x = 0; x < inSizeX; ++x, ++p, ++q )
300 converter.
convert( tmpvol, _splineCoefficients );
307 converter.
convert( inref, _splineCoefficients );
314 std::vector< double > data( inSizeX );
316 for ( z = 0; z < inSizeZ; z++ )
319 for ( y = 0; y < inSizeY; y++ )
322 for ( x = 0; x < inSizeX; x++ )
325 data[ x ] = ( double )_splineCoefficients( x, y, z );
328 iirConvolveMirror( data );
329 for ( x = 0; x < inSizeX; x++ )
332 _splineCoefficients( x, y, z ) = data[ x ];
345 std::vector< double > data( inSizeY );
347 for ( z = 0; z < inSizeZ; z++ )
350 for ( x = 0; x < inSizeX; x++ )
353 for ( y = 0; y < inSizeY; y++ )
356 data[ y ] = ( double )_splineCoefficients( x, y, z );
359 iirConvolveMirror( data );
360 for ( y = 0; y < inSizeY; y++ )
363 _splineCoefficients( x, y, z ) = data[ y ];
376 std::vector< double > data( inSizeZ );
378 for ( y = 0; y < inSizeY; y++ )
381 for ( x = 0; x < inSizeX; x++ )
384 for ( z = 0; z < inSizeZ; z++ )
387 data[ z ] = ( double )_splineCoefficients( x, y, z );
390 iirConvolveMirror( data );
391 for ( z = 0; z < inSizeZ; z++ )
394 _splineCoefficients( x, y, z ) = data[ z ];
404 _lastvolume = &inVolume;
410 std::cout <<
"done ]" << std::flush;
424 double tolerance = log10(
EPSILON );
426 std::vector< double >::iterator d = data.begin(), de = data.end();
438 int size = ( int )data.size();
446 int size2 = 2 * ( size - 1 );
448 std::vector< double >::const_reverse_iterator p = _poles.rbegin(),
450 double* dataBegin = &data[ 0 ];
451 double* dataEnd = dataBegin + data.size();
460 j = ( int )ceil( tolerance / log10( std::fabs( *p ) ) );
461 k = j - size2 * ( j / size2 );
466 ptrD1 = dataBegin + k;
474 ptrD1 = dataBegin + k;
476 while ( ++ptrD1 < dataEnd )
479 x0 = *p * x0 + *ptrD1;
485 while ( --ptrD1 >= dataBegin )
488 x0 = *p * x0 + *ptrD1;
495 while ( ++ptrD1 < dataEnd )
498 x0 = *p * x0 + *ptrD1;
502 while ( --ptrD1 >= dataBegin )
505 x0 = *p * x0 + *ptrD1;
513 x0 = *( ptrD2++ + size );
514 while ( ptrD1 < dataEnd )
517 *ptrD1++ += *ptrD2++ * *p;
520 *ptrD2 = ( 2.0 * *ptrD2 - x0 ) / ( 1.0 - *p * *p );
522 while ( --ptrD2 >= dataBegin )
525 *ptrD2 += *ptrD1-- * *p;
546 template <
typename T>
550 inverse_transform_to_vox,
557 int outSizeX = outVolume.
getSizeX();
558 int outSizeY = outVolume.
getSizeY();
559 int outSizeZ = outVolume.
getSizeZ();
560 int outSizeT = outVolume.
getSizeT();
561 if( outSizeT > inVolume.
getSizeT() )
567 * outSizeY * outSizeZ * outSizeT);
570 for ( t = 0; t < outSizeT; t++ )
572 updateParametersChannel( inVolume, t,
verbose );
575 for ( z = 0; z < outSizeZ; z++ )
578 for ( y = 0; y < outSizeY; y++ )
580 o = &outVolume.
at( 0, y, z, t );
582 for ( x = 0; x < outSizeX; x++ )
586 inVolume, inverse_transform_to_vox, outBackground,
590 outLoc[0] += outResolution[0];
593 outLoc[1] += outResolution[1];
600 outLoc[2] += outResolution[2];
632 inverse_transform_to_vox,
635 bool verbose =
false )
638 spline_resampler->Resampler<T>::resample_inv_to_vox(
639 input_data, inverse_transform_to_vox,
640 background, output_data,
verbose);
645 int t,
bool verbose )
671 for (
unsigned int channel = 0;
672 channel < carto::DataTypeTraits<T>::channelcount;
678 input_channel = selector.select( inref, channel );
687 output_value[channel],
695 inverse_transform_to_vox,
698 bool verbose =
false )
709 for (
unsigned int channel = 0;
710 channel < carto::DataTypeTraits<T>::channelcount;
724 input_channel = selector.select( inref, channel );
728 *input_channel, inverse_transform_to_vox, background[ channel ],
733 outref.
reset( &output_data );
734 selector.set( outref, channel, output_channel );
754 int t,
bool verbose )
const
759 Switch::updateParameters(
this,
774 Switch::resample_inv_to_vox(
this,
775 input_data, inverse_transform_to_vox,
776 background, output_data,
verbose);
792 Switch::doResample(
this, input_data, inverse_transform, background,
793 output_location, output_value, timestep);
virtual void print(const bool force=false)
Resampling of data from a volume, applying a transformation.
B-Spline-based resampling.
void doResample(const carto::Volume< T > &inVolume, const soma::Transformation3d &transform3d, const T &outBackground, const Point3df &outLocation, T &outValue, int t) const CARTO_OVERRIDE
Resample a volume at a single location.
void reset()
Clear the cache.
carto::VolumeRef< double > getSplineCoef(const carto::Volume< T > &inVolume, int t=0, bool verbose=false)
Computes spline coefficients corresponding to an input volume.
void resample_inv_to_vox(const carto::Volume< T > &input_data, const soma::Transformation3d &inverse_transform_to_vox, const T &background, carto::Volume< T > &output_data, bool verbose=false) const CARTO_OVERRIDE
Resample a volume into an existing output volume.
int getFold(int i, int size) const
This method returns a mirror index when needed.
virtual void updateParametersChannel(const carto::Volume< ChannelType > &inVolume, int t, bool verbose) const
virtual void doResampleChannel(const carto::Volume< ChannelType > &inVolume, const soma::Transformation3d &transform3d, const ChannelType &outBackground, const Point3df &outLocation, ChannelType &outValue, int t) const
void resample_channel_inv_to_vox(const carto::Volume< ChannelType > &inVolume, const soma::Transformation3d &inverse_transform_to_vox, const ChannelType &outBackground, carto::Volume< ChannelType > &outVolume, bool verbose) const
void iirConvolveMirror(std::vector< double > &data) const
void updateParameters(const carto::Volume< T > &inVolume, int t, bool verbose) const CARTO_OVERRIDE
Update the cache of spline coefficients if needed.
virtual void convert(const INP &in, OUTP &out) const
void setProperty(const std::string &, const T &)
void convert(const INP &in, OUTP &out) const
std::vector< float > getVoxelSize() const
std::vector< int > getSize() const
virtual void copyHeaderFrom(const PropertySet &other)
const PropertySet & header() const
const T & at(long x, long y=0, long z=0, long t=0) const
int mirrorCoeff(int i, int size)
This method returns a mirror index when needed.
static void updateParameters(const SplineResampler< T > *spline_resampler, const carto::Volume< T > &inVolume, int t, bool verbose)
static void doResample(const SplineResampler< T > *spline_resampler, const carto::Volume< T > &input_data, const soma::Transformation3d &inverse_transform, const T &background, const Point3df &output_location, T &output_value, int timestep)
static void resample_inv_to_vox(const SplineResampler< T > *spline_resampler, const carto::Volume< T > &input_data, const soma::Transformation3d &inverse_transform_to_vox, const T &background, carto::Volume< T > &output_data, bool verbose=false)
carto::DataTypeTraits< T >::ChannelType ChannelType
static void updateParameters(const SplineResampler< T > *, const carto::Volume< T > &, int, bool)
static void resample_inv_to_vox(const SplineResampler< T > *spline_resampler, const carto::Volume< T > &input_data, const soma::Transformation3d &inverse_transform_to_vox, const T &background, carto::Volume< T > &output_data, bool verbose=false)
static void doResample(const SplineResampler< T > *spline_resampler, const carto::Volume< T > &input_data, const soma::Transformation3d &inverse_transform, const T &background, const Point3df &output_location, T &output_value, int timestep)