Skip to content
Snippets Groups Projects
Commit 58f865fc authored by Emmanuel Christophe's avatar Emmanuel Christophe
Browse files

ENH: makes resample filters more generics (non-optimized filter)

parent e7655fdc
No related branches found
No related tags found
No related merge requests found
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
Copyright (c) Insight Software Consortium. All rights reserved. Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information. PURPOSE. See the above copyright notices for more information.
=========================================================================*/ =========================================================================*/
...@@ -69,7 +69,7 @@ namespace itk ...@@ -69,7 +69,7 @@ namespace itk
* ProcessObject::GenerateInputRequestedRegion() and * ProcessObject::GenerateInputRequestedRegion() and
* ProcessObject::GenerateOutputInformation(). * ProcessObject::GenerateOutputInformation().
* *
* This filter is implemented as a multithreaded filter. It provides a * This filter is implemented as a multithreaded filter. It provides a
* ThreadedGenerateData() method for its implementation. * ThreadedGenerateData() method for its implementation.
* *
* \ingroup GeometricTransforms * \ingroup GeometricTransforms
...@@ -94,7 +94,7 @@ public: ...@@ -94,7 +94,7 @@ public:
typedef typename InputImageType::RegionType InputImageRegionType; typedef typename InputImageType::RegionType InputImageRegionType;
/** Method for creation through the object factory. */ /** Method for creation through the object factory. */
itkNewMacro(Self); itkNewMacro(Self);
/** Run-time type information (and related methods). */ /** Run-time type information (and related methods). */
itkTypeMacro(ResampleImageFilter, ImageToImageFilter); itkTypeMacro(ResampleImageFilter, ImageToImageFilter);
...@@ -107,13 +107,14 @@ public: ...@@ -107,13 +107,14 @@ public:
/** Transform typedef. */ /** Transform typedef. */
typedef Transform<TInterpolatorPrecisionType, typedef double CoordRepType;
itkGetStaticConstMacro(ImageDimension), typedef Transform<CoordRepType,
itkGetStaticConstMacro(ImageDimension),
itkGetStaticConstMacro(ImageDimension)> TransformType; itkGetStaticConstMacro(ImageDimension)> TransformType;
typedef typename TransformType::ConstPointer TransformPointerType; typedef typename TransformType::ConstPointer TransformPointerType;
/** Interpolator typedef. */ /** Interpolator typedef. */
typedef InterpolateImageFunction<InputImageType, TInterpolatorPrecisionType> InterpolatorType; typedef InterpolateImageFunction<InputImageType,CoordRepType > InterpolatorType;
typedef typename InterpolatorType::Pointer InterpolatorPointerType; typedef typename InterpolatorType::Pointer InterpolatorPointerType;
/** Image size typedef. */ /** Image size typedef. */
...@@ -129,7 +130,7 @@ public: ...@@ -129,7 +130,7 @@ public:
/** Image pixel value typedef. */ /** Image pixel value typedef. */
typedef typename TOutputImage::PixelType PixelType; typedef typename TOutputImage::PixelType PixelType;
typedef typename TInputImage::PixelType InputPixelType; typedef typename TInputImage::PixelType InputPixelType;
/** Typedef to describe the output image region type. */ /** Typedef to describe the output image region type. */
typedef typename TOutputImage::RegionType OutputImageRegionType; typedef typename TOutputImage::RegionType OutputImageRegionType;
...@@ -137,7 +138,7 @@ public: ...@@ -137,7 +138,7 @@ public:
typedef typename TOutputImage::SpacingType SpacingType; typedef typename TOutputImage::SpacingType SpacingType;
typedef typename TOutputImage::PointType OriginPointType; typedef typename TOutputImage::PointType OriginPointType;
typedef typename TOutputImage::DirectionType DirectionType; typedef typename TOutputImage::DirectionType DirectionType;
/** Set the coordinate transformation. /** Set the coordinate transformation.
* Set the coordinate transform to use for resampling. Note that this must * Set the coordinate transform to use for resampling. Note that this must
* be in physical coordinates and it is the output-to-input transform, NOT * be in physical coordinates and it is the output-to-input transform, NOT
...@@ -145,7 +146,7 @@ public: ...@@ -145,7 +146,7 @@ public:
* the filter uses an Identity transform. You must provide a different * the filter uses an Identity transform. You must provide a different
* transform here, before attempting to run the filter, if you do not want to * transform here, before attempting to run the filter, if you do not want to
* use the default Identity transform. */ * use the default Identity transform. */
itkSetConstObjectMacro( Transform, TransformType ); itkSetConstObjectMacro( Transform, TransformType );
/** Get a pointer to the coordinate transform. */ /** Get a pointer to the coordinate transform. */
itkGetConstObjectMacro( Transform, TransformType ); itkGetConstObjectMacro( Transform, TransformType );
...@@ -166,7 +167,7 @@ public: ...@@ -166,7 +167,7 @@ public:
/** Get the size of the output image. */ /** Get the size of the output image. */
itkGetConstReferenceMacro( Size, SizeType ); itkGetConstReferenceMacro( Size, SizeType );
/** Set the pixel value when a transformed pixel is outside of the /** Set the pixel value when a transformed pixel is outside of the
* image. The default default pixel value is 0. */ * image. The default default pixel value is 0. */
itkSetMacro( DefaultPixelValue, PixelType ); itkSetMacro( DefaultPixelValue, PixelType );
...@@ -211,7 +212,7 @@ public: ...@@ -211,7 +212,7 @@ public:
this->SetOutputStartIndex ( Image->GetLargestPossibleRegion().GetIndex() ); this->SetSize ( Image->GetLargestPossibleRegion().GetSize() ); this->SetOutputStartIndex ( Image->GetLargestPossibleRegion().GetIndex() ); this->SetSize ( Image->GetLargestPossibleRegion().GetSize() );
} }
/** Set the start index of the output largest possible region. /** Set the start index of the output largest possible region.
* The default is an index of all zeros. */ * The default is an index of all zeros. */
itkSetMacro( OutputStartIndex, IndexType ); itkSetMacro( OutputStartIndex, IndexType );
...@@ -222,7 +223,7 @@ public: ...@@ -222,7 +223,7 @@ public:
* the information is specified with the SetOutputSpacing, Origin, * the information is specified with the SetOutputSpacing, Origin,
* and Direction methods. UseReferenceImage must be On and a * and Direction methods. UseReferenceImage must be On and a
* Reference image must be present to override the defaul behavior. * Reference image must be present to override the defaul behavior.
* NOTE: This function seems redundant with the * NOTE: This function seems redundant with the
* SetOutputParametersFromImage( image ) function */ * SetOutputParametersFromImage( image ) function */
void SetReferenceImage ( const TOutputImage *image ); void SetReferenceImage ( const TOutputImage *image );
const TOutputImage * GetReferenceImage( void ) const; const TOutputImage * GetReferenceImage( void ) const;
...@@ -245,11 +246,11 @@ public: ...@@ -245,11 +246,11 @@ public:
* \sa ProcessObject::GenerateInputRequestedRegion() */ * \sa ProcessObject::GenerateInputRequestedRegion() */
virtual void GenerateInputRequestedRegion( void ); virtual void GenerateInputRequestedRegion( void );
/** This method is used to set the state of the filter before /** This method is used to set the state of the filter before
* multi-threading. */ * multi-threading. */
virtual void BeforeThreadedGenerateData( void ); virtual void BeforeThreadedGenerateData( void );
/** This method is used to set the state of the filter after /** This method is used to set the state of the filter after
* multi-threading. */ * multi-threading. */
virtual void AfterThreadedGenerateData( void ); virtual void AfterThreadedGenerateData( void );
...@@ -286,12 +287,12 @@ protected: ...@@ -286,12 +287,12 @@ protected:
int threadId ); int threadId );
/** Implementation for resampling that works for with linear /** Implementation for resampling that works for with linear
* transformation types. * transformation types.
*/ */
void LinearThreadedGenerateData( const OutputImageRegionType& void LinearThreadedGenerateData( const OutputImageRegionType&
outputRegionForThread, outputRegionForThread,
int threadId ); int threadId );
private: private:
ResampleImageFilter( const Self& ); //purposely not implemented ResampleImageFilter( const Self& ); //purposely not implemented
...@@ -312,13 +313,13 @@ private: ...@@ -312,13 +313,13 @@ private:
}; };
} // end namespace itk } // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION #ifndef ITK_MANUAL_INSTANTIATION
#include "itkResampleImageFilter.txx" #include "itkResampleImageFilter.txx"
#endif #endif
#endif #endif
#endif #endif
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
Copyright (c) Insight Software Consortium. All rights reserved. Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information. PURPOSE. See the above copyright notices for more information.
=========================================================================*/ =========================================================================*/
...@@ -54,9 +54,10 @@ ResampleImageFilter<TInputImage, TOutputImage,TInterpolatorPrecisionType> ...@@ -54,9 +54,10 @@ ResampleImageFilter<TInputImage, TOutputImage,TInterpolatorPrecisionType>
m_Size.Fill( 0 ); m_Size.Fill( 0 );
m_OutputStartIndex.Fill( 0 ); m_OutputStartIndex.Fill( 0 );
m_Transform = IdentityTransform<TInterpolatorPrecisionType, ImageDimension>::New(); typedef double CoordRepType;
m_Interpolator = LinearInterpolateImageFunction<InputImageType, TInterpolatorPrecisionType>::New(); m_Transform = IdentityTransform<CoordRepType, ImageDimension>::New();
m_Interpolator = LinearInterpolateImageFunction<InputImageType, CoordRepType>::New();
m_DefaultPixelValue = 0; m_DefaultPixelValue = 0;
} }
...@@ -67,12 +68,12 @@ ResampleImageFilter<TInputImage, TOutputImage,TInterpolatorPrecisionType> ...@@ -67,12 +68,12 @@ ResampleImageFilter<TInputImage, TOutputImage,TInterpolatorPrecisionType>
* \todo Add details about this class * \todo Add details about this class
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage, TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage, TOutputImage,TInterpolatorPrecisionType>
::PrintSelf(std::ostream& os, Indent indent) const ::PrintSelf(std::ostream& os, Indent indent) const
{ {
Superclass::PrintSelf(os,indent); Superclass::PrintSelf(os,indent);
os << indent << "DefaultPixelValue: " os << indent << "DefaultPixelValue: "
<< static_cast<typename NumericTraits<PixelType>::PrintType>(m_DefaultPixelValue) << static_cast<typename NumericTraits<PixelType>::PrintType>(m_DefaultPixelValue)
<< std::endl; << std::endl;
...@@ -91,7 +92,7 @@ ResampleImageFilter<TInputImage, TOutputImage,TInterpolatorPrecisionType> ...@@ -91,7 +92,7 @@ ResampleImageFilter<TInputImage, TOutputImage,TInterpolatorPrecisionType>
* Set the output image spacing. * Set the output image spacing.
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::SetOutputSpacing( ::SetOutputSpacing(
const double* spacing) const double* spacing)
...@@ -105,7 +106,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -105,7 +106,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
* Set the output image origin. * Set the output image origin.
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::SetOutputOrigin( ::SetOutputOrigin(
const double* origin) const double* origin)
...@@ -121,7 +122,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -121,7 +122,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
* has to be set up before ThreadedGenerateData * has to be set up before ThreadedGenerateData
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::BeforeThreadedGenerateData() ::BeforeThreadedGenerateData()
{ {
...@@ -144,7 +145,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -144,7 +145,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
* Set up state of filter after multi-threading. * Set up state of filter after multi-threading.
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::AfterThreadedGenerateData() ::AfterThreadedGenerateData()
{ {
...@@ -157,7 +158,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -157,7 +158,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
* ThreadedGenerateData * ThreadedGenerateData
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::ThreadedGenerateData( ::ThreadedGenerateData(
const OutputImageRegionType& outputRegionForThread, const OutputImageRegionType& outputRegionForThread,
...@@ -183,7 +184,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -183,7 +184,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
this->NonlinearThreadedGenerateData(outputRegionForThread, threadId); this->NonlinearThreadedGenerateData(outputRegionForThread, threadId);
return; return;
} }
// Check whether we can use a fast path for resampling. Fast path // Check whether we can use a fast path for resampling. Fast path
// can be used if the transformation is linear. Transform respond // can be used if the transformation is linear. Transform respond
// to the IsLinear() call. // to the IsLinear() call.
...@@ -196,12 +197,12 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -196,12 +197,12 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
// Otherwise, we use the normal method where the transform is called // Otherwise, we use the normal method where the transform is called
// for computing the transformation of every point. // for computing the transformation of every point.
this->NonlinearThreadedGenerateData(outputRegionForThread, threadId); this->NonlinearThreadedGenerateData(outputRegionForThread, threadId);
} }
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::NonlinearThreadedGenerateData( ::NonlinearThreadedGenerateData(
const OutputImageRegionType& outputRegionForThread, const OutputImageRegionType& outputRegionForThread,
...@@ -223,12 +224,13 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -223,12 +224,13 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
PointType outputPoint; // Coordinates of current output pixel PointType outputPoint; // Coordinates of current output pixel
PointType inputPoint; // Coordinates of current input pixel PointType inputPoint; // Coordinates of current input pixel
typedef ContinuousIndex<TInterpolatorPrecisionType, ImageDimension> ContinuousIndexType; typedef double CoordRepType;
typedef ContinuousIndex<CoordRepType, ImageDimension> ContinuousIndexType;
ContinuousIndexType inputIndex; ContinuousIndexType inputIndex;
// Support for progress methods/callbacks // Support for progress methods/callbacks
ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
typedef typename InterpolatorType::OutputType OutputType; typedef typename InterpolatorType::OutputType OutputType;
// Min/max values of the output pixel type AND these values // Min/max values of the output pixel type AND these values
...@@ -238,7 +240,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -238,7 +240,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
const OutputType minOutputValue = static_cast<OutputType>(minValue); const OutputType minOutputValue = static_cast<OutputType>(minValue);
const OutputType maxOutputValue = static_cast<OutputType>(maxValue); const OutputType maxOutputValue = static_cast<OutputType>(maxValue);
// Walk the output region // Walk the output region
outIt.GoToBegin(); outIt.GoToBegin();
...@@ -258,7 +260,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -258,7 +260,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, inputIndex); inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, inputIndex);
// The inputIndex is precise to many decimal points, but this precision // The inputIndex is precise to many decimal points, but this precision
// involves some error in the last bits. // involves some error in the last bits.
// Sometimes, when an index should be inside of the image, the // Sometimes, when an index should be inside of the image, the
// index will be slightly // index will be slightly
// greater than the largest index in the image, like 255.00000000002 // greater than the largest index in the image, like 255.00000000002
...@@ -274,25 +276,16 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -274,25 +276,16 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
double newInputIndexFrac = vcl_floor(precisionConstant * inputIndexFrac)/precisionConstant; double newInputIndexFrac = vcl_floor(precisionConstant * inputIndexFrac)/precisionConstant;
inputIndex[i] = roundedInputIndex + newInputIndexFrac; inputIndex[i] = roundedInputIndex + newInputIndexFrac;
} }
// Evaluate input at right position and copy to the output // Evaluate input at right position and copy to the output
if( m_Interpolator->IsInsideBuffer(inputIndex) ) if( m_Interpolator->IsInsideBuffer(inputIndex) )
{ {
PixelType pixval; PixelType pixval;
const OutputType value const OutputType value
= m_Interpolator->EvaluateAtContinuousIndex(inputIndex); = m_Interpolator->EvaluateAtContinuousIndex(inputIndex);
if( value < minOutputValue ) pixval = static_cast<PixelType>(
{ NumericTraits<OutputType>::Clamp(value,minOutputValue,maxOutputValue)
pixval = minValue; );
}
else if( value > maxOutputValue )
{
pixval = maxValue;
}
else
{
pixval = static_cast<PixelType>( value );
}
outIt.Set( pixval ); outIt.Set( pixval );
} }
else else
...@@ -308,7 +301,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -308,7 +301,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
} }
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::LinearThreadedGenerateData( ::LinearThreadedGenerateData(
const OutputImageRegionType& outputRegionForThread, const OutputImageRegionType& outputRegionForThread,
...@@ -333,17 +326,18 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -333,17 +326,18 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
PointType tmpOutputPoint; PointType tmpOutputPoint;
PointType tmpInputPoint; PointType tmpInputPoint;
typedef ContinuousIndex<TInterpolatorPrecisionType, ImageDimension> ContinuousIndexType; typedef double CoordRepType;
typedef ContinuousIndex<CoordRepType, ImageDimension> ContinuousIndexType;
ContinuousIndexType inputIndex; ContinuousIndexType inputIndex;
ContinuousIndexType tmpInputIndex; ContinuousIndexType tmpInputIndex;
typedef typename PointType::VectorType VectorType; typedef typename PointType::VectorType VectorType;
VectorType delta; // delta in input continuous index coordinate frame VectorType delta; // delta in input continuous index coordinate frame
IndexType index; IndexType index;
// Support for progress methods/callbacks // Support for progress methods/callbacks
ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
typedef typename InterpolatorType::OutputType OutputType; typedef typename InterpolatorType::OutputType OutputType;
// Cache information from the superclass // Cache information from the superclass
...@@ -356,34 +350,34 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -356,34 +350,34 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
const OutputType minOutputValue = static_cast<OutputType>(minValue); const OutputType minOutputValue = static_cast<OutputType>(minValue);
const OutputType maxOutputValue = static_cast<OutputType>(maxValue); const OutputType maxOutputValue = static_cast<OutputType>(maxValue);
// Determine the position of the first pixel in the scanline // Determine the position of the first pixel in the scanline
index = outIt.GetIndex(); index = outIt.GetIndex();
outputPtr->TransformIndexToPhysicalPoint( index, outputPoint ); outputPtr->TransformIndexToPhysicalPoint( index, outputPoint );
// Compute corresponding input pixel position // Compute corresponding input pixel position
inputPoint = m_Transform->TransformPoint(outputPoint); inputPoint = m_Transform->TransformPoint(outputPoint);
inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, inputIndex); inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, inputIndex);
// As we walk across a scan line in the output image, we trace // As we walk across a scan line in the output image, we trace
// an oriented/scaled/translated line in the input image. Cache // an oriented/scaled/translated line in the input image. Cache
// the delta along this line in continuous index space of the input // the delta along this line in continuous index space of the input
// image. This allows us to use vector addition to model the // image. This allows us to use vector addition to model the
// transformation. // transformation.
// //
// To find delta, we take two pixels adjacent in a scanline // To find delta, we take two pixels adjacent in a scanline
// and determine the continuous indices of these pixels when // and determine the continuous indices of these pixels when
// mapped to the input coordinate frame. We use the difference // mapped to the input coordinate frame. We use the difference
// between these two continuous indices as the delta to apply // between these two continuous indices as the delta to apply
// to an index to trace line in the input image as we move // to an index to trace line in the input image as we move
// across the scanline of the output image. // across the scanline of the output image.
// //
// We determine delta in this manner so that Images and // We determine delta in this manner so that Images and
// OrientedImages are both handled properly (with the delta for // OrientedImages are both handled properly (with the delta for
// OrientedImages taking into account the direction cosines). // OrientedImages taking into account the direction cosines).
// //
++index[0]; ++index[0];
outputPtr->TransformIndexToPhysicalPoint( index, tmpOutputPoint ); outputPtr->TransformIndexToPhysicalPoint( index, tmpOutputPoint );
tmpInputPoint = m_Transform->TransformPoint( tmpOutputPoint ); tmpInputPoint = m_Transform->TransformPoint( tmpOutputPoint );
...@@ -432,7 +426,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -432,7 +426,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
// will incremented in the scanline loop // will incremented in the scanline loop
inputPoint = m_Transform->TransformPoint(outputPoint); inputPoint = m_Transform->TransformPoint(outputPoint);
inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, inputIndex); inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, inputIndex);
// The inputIndex is precise to many decimal points, but this precision // The inputIndex is precise to many decimal points, but this precision
// involves some error in the last bits. // involves some error in the last bits.
// Sometimes, when an index should be inside of the image, the // Sometimes, when an index should be inside of the image, the
...@@ -460,25 +454,17 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -460,25 +454,17 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
PixelType pixval; PixelType pixval;
const OutputType value const OutputType value
= m_Interpolator->EvaluateAtContinuousIndex(inputIndex); = m_Interpolator->EvaluateAtContinuousIndex(inputIndex);
if( value < minOutputValue )
{ pixval = static_cast<PixelType>(
pixval = minValue; NumericTraits<OutputType>::Clamp(value,minOutputValue,maxOutputValue)
} );
else if( value > maxOutputValue )
{
pixval = maxValue;
}
else
{
pixval = static_cast<PixelType>( value );
}
outIt.Set( pixval ); outIt.Set( pixval );
} }
else else
{ {
outIt.Set(defaultValue); // default background value outIt.Set(defaultValue); // default background value
} }
progress.CompletedPixel(); progress.CompletedPixel();
++outIt; ++outIt;
inputIndex += delta; inputIndex += delta;
...@@ -490,7 +476,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -490,7 +476,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
} }
/** /**
* Inform pipeline of necessary input image region * Inform pipeline of necessary input image region
* *
* Determining the actual input region is non-trivial, especially * Determining the actual input region is non-trivial, especially
...@@ -498,7 +484,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -498,7 +484,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
* So we do the easy thing and request the entire input image. * So we do the easy thing and request the entire input image.
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::GenerateInputRequestedRegion() ::GenerateInputRequestedRegion()
{ {
...@@ -511,7 +497,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -511,7 +497,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
} }
// get pointers to the input and output // get pointers to the input and output
InputImagePointer inputPtr = InputImagePointer inputPtr =
const_cast< TInputImage *>( this->GetInput() ); const_cast< TInputImage *>( this->GetInput() );
// Request the entire input image // Request the entire input image
...@@ -523,7 +509,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -523,7 +509,7 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
} }
/** /**
* Set the smart pointer to the reference image that will provide * Set the smart pointer to the reference image that will provide
* the grid parameters for the output image. * the grid parameters for the output image.
*/ */
...@@ -533,18 +519,18 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -533,18 +519,18 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::GetReferenceImage() const ::GetReferenceImage() const
{ {
Self * surrogate = const_cast< Self * >( this ); Self * surrogate = const_cast< Self * >( this );
const OutputImageType * referenceImage = const OutputImageType * referenceImage =
static_cast<const OutputImageType *>(surrogate->ProcessObject::GetInput(1)); static_cast<const OutputImageType *>(surrogate->ProcessObject::GetInput(1));
return referenceImage; return referenceImage;
} }
/** /**
* Set the smart pointer to the reference image that will provide * Set the smart pointer to the reference image that will provide
* the grid parameters for the output image. * the grid parameters for the output image.
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::SetReferenceImage( const TOutputImage *image ) ::SetReferenceImage( const TOutputImage *image )
{ {
...@@ -556,11 +542,11 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -556,11 +542,11 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
} }
} }
/** /**
* Inform pipeline of required output region * Inform pipeline of required output region
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
void void
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::GenerateOutputInformation() ::GenerateOutputInformation()
{ {
...@@ -605,15 +591,15 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ...@@ -605,15 +591,15 @@ ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
return; return;
} }
/** /**
* Verify if any of the components has been modified. * Verify if any of the components has been modified.
*/ */
template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType> template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
unsigned long unsigned long
ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType> ResampleImageFilter<TInputImage,TOutputImage,TInterpolatorPrecisionType>
::GetMTime( void ) const ::GetMTime( void ) const
{ {
unsigned long latestTime = Object::GetMTime(); unsigned long latestTime = Object::GetMTime();
if( m_Transform ) if( m_Transform )
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment