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 )
96 int width = order + 1;
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++ )
155 normalizedInLocation[2] );
156 foldZ[ k ] =
getFold( z + k, dimz ) *
167 y =
static_cast<int>(floor(normalizedInLocation[1]));
177 for ( j = 0; j < width; j++ )
181 foldY[ j ] =
getFold( y +j, dimy )
189 x =
static_cast<int>(floor(normalizedInLocation[0]));
199 for ( i = 0; i < width; i++ )
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;
237 outValue = outBackground;
248 int t,
bool verbose )
const 258 std::cout <<
"[ updating spline coefficients : " << std::flush;
262 std::vector<int> dims = inVolume.
getSize();
263 int inSizeX = dims[0];
264 int inSizeY = dims[1];
265 int inSizeZ = dims[2];
279 for ( z = 0; z < inSizeZ; z++ )
280 for ( y = 0; y < inSizeY; y++ )
282 q = &inVolume.
at( 0, y, z, t );
283 for ( x = 0; x < inSizeX; ++x, ++p, ++q )
300 std::vector< double > data( inSizeX );
302 for ( z = 0; z < inSizeZ; z++ )
305 for ( y = 0; y < inSizeY; y++ )
308 for ( x = 0; x < inSizeX; x++ )
315 for ( x = 0; x < inSizeX; x++ )
331 std::vector< double > data( inSizeY );
333 for ( z = 0; z < inSizeZ; z++ )
336 for ( x = 0; x < inSizeX; x++ )
339 for ( y = 0; y < inSizeY; y++ )
346 for ( y = 0; y < inSizeY; y++ )
362 std::vector< double > data( inSizeZ );
364 for ( y = 0; y < inSizeY; y++ )
367 for ( x = 0; x < inSizeX; x++ )
370 for ( z = 0; z < inSizeZ; z++ )
377 for ( z = 0; z < inSizeZ; z++ )
396 std::cout <<
"done ]" << std::flush;
410 double tolerance = log10(
EPSILON );
412 std::vector< double >::iterator d = data.begin(), de = data.end();
424 int size = ( int )data.size();
432 int size2 = 2 * ( size - 1 );
434 std::vector< double >::const_reverse_iterator p =
_poles.rbegin(),
436 double* dataBegin = &data[ 0 ];
437 double* dataEnd = dataBegin + data.size();
446 j = ( int )ceil( tolerance / log10( std::fabs( *p ) ) );
447 k = j - size2 * ( j / size2 );
452 ptrD1 = dataBegin + k;
460 ptrD1 = dataBegin + k;
462 while ( ++ptrD1 < dataEnd )
465 x0 = *p * x0 + *ptrD1;
471 while ( --ptrD1 >= dataBegin )
474 x0 = *p * x0 + *ptrD1;
481 while ( ++ptrD1 < dataEnd )
484 x0 = *p * x0 + *ptrD1;
488 while ( --ptrD1 >= dataBegin )
491 x0 = *p * x0 + *ptrD1;
499 x0 = *( ptrD2++ + size );
500 while ( ptrD1 < dataEnd )
503 *ptrD1++ += *ptrD2++ * *p;
506 *ptrD2 = ( 2.0 * *ptrD2 - x0 ) / ( 1.0 - *p * *p );
508 while ( --ptrD2 >= dataBegin )
511 *ptrD2 += *ptrD1-- * *p;
532 template <
typename T>
536 inverse_transform_to_vox,
543 int outSizeX = outVolume.
getSizeX();
544 int outSizeY = outVolume.
getSizeY();
545 int outSizeZ = outVolume.
getSizeZ();
546 int outSizeT = outVolume.
getSizeT();
547 if( outSizeT > inVolume.
getSizeT() )
553 * outSizeY * outSizeZ * outSizeT);
556 for ( t = 0; t < outSizeT; t++ )
561 for ( z = 0; z < outSizeZ; z++ )
564 for ( y = 0; y < outSizeY; y++ )
566 o = &outVolume.
at( 0, y, z, t );
568 for ( x = 0; x < outSizeX; x++ )
572 inVolume, inverse_transform_to_vox, outBackground,
576 outLoc[0] += outResolution[0];
579 outLoc[1] += outResolution[1];
586 outLoc[2] += outResolution[2];
618 inverse_transform_to_vox,
621 bool verbose =
false )
624 spline_resampler->Resampler<T>::resample_inv_to_vox(
625 input_data, inverse_transform_to_vox,
626 background, output_data,
verbose);
631 int t,
bool verbose )
657 for (
unsigned int channel = 0;
658 channel < carto::DataTypeTraits<T>::channelcount;
664 input_channel = selector.select( inref, channel );
673 output_value[channel],
681 inverse_transform_to_vox,
684 bool verbose =
false )
695 for (
unsigned int channel = 0;
696 channel < carto::DataTypeTraits<T>::channelcount;
702 output_channel.
header().setProperty(
"voxel_size", vs );
710 input_channel = selector.select( inref, channel );
714 *input_channel, inverse_transform_to_vox, background[ channel ],
719 outref.
reset( &output_data );
720 selector.set( outref, channel, output_channel );
740 int t,
bool verbose )
const 745 Switch::updateParameters(
this,
746 inVolume, t, verbose);
760 Switch::resample_inv_to_vox(
this,
761 input_data, inverse_transform_to_vox,
762 background, output_data, verbose);
778 Switch::doResample(
this, input_data, inverse_transform, background,
779 output_location, output_value, timestep);
784 #endif // !defined( AIMS_RESAMPLING_SPLINERESAMPLER_D_H ) 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
carto::VolumeRef< double > getSplineCoef(const carto::Volume< T > &inVolume, int t=0, bool verbose=false)
Computes spline coefficients corresponding to an input volume.
const T & at(long x, long y=0, long z=0, long t=0) const
carto::VolumeRef< double > _splineCoefficients
virtual void doResampleChannel(const carto::Volume< ChannelType > &inVolume, const soma::Transformation3d &transform3d, const ChannelType &outBackground, const Point3df &outLocation, ChannelType &outValue, int t) const
virtual void print(const bool force=false)
carto::DataTypeTraits< T >::ChannelType ChannelType
int mirrorCoeff(int i, int size)
This method returns a mirror index when needed.
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)
virtual void updateParametersChannel(const carto::Volume< ChannelType > &inVolume, int t, bool verbose) const
std::vector< double > _poles
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.
std::vector< int > getSize() const
virtual void convert(const INP &in, OUTP &out) const
static void updateParameters(const SplineResampler< T > *, const carto::Volume< T > &, int, bool)
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)
void iirConvolveMirror(std::vector< double > &data) const
int getFold(int i, int size) const
This method returns a mirror index when needed.
const PropertySet & header() const
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 setProperty(const std::string &, const T &)
void updateParameters(const carto::Volume< T > &inVolume, int t, bool verbose) const CARTO_OVERRIDE
Update the cache of spline coefficients if needed.
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)
void reset()
Clear the cache.
Resampling of data from a volume, applying a transformation.
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)
virtual int getOrder() const =0
Spline order (1 to 7)
virtual double getBSplineWeight(int i, double x) const =0
Returns .
static void updateParameters(const SplineResampler< T > *spline_resampler, const carto::Volume< T > &inVolume, int t, bool verbose)
const carto::Volume< ChannelType > * _lastvolume
virtual void copyHeaderFrom(const PropertySet &other)
std::vector< float > getVoxelSize() const
B-Spline-based resampling.