4 #include <itkObjectFactory.h> 5 #include <itkIdentityTransform.h> 6 #include <itkLinearInterpolateImageFunction.h> 7 #include <itkProgressReporter.h> 8 #include <itkImageRegionIteratorWithIndex.h> 9 #include <itkImageLinearIteratorWithIndex.h> 10 #include <itkSpecialCoordinatesImage.h> 12 #include <vnl/vnl_det.h> 20 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
24 m_OutputSpacing.Fill(1.0);
25 m_OutputOrigin.Fill(0.0);
26 m_OutputDirection.SetIdentity();
28 m_UseReferenceImage =
false;
31 m_OutputStartIndex.Fill( 0 );
33 m_Transform = itk::IdentityTransform<TInterpolatorPrecisionType, ImageDimension>::New();
34 m_Interpolator =
nullptr;
35 m_DefaultPixelValue = 0;
37 m_ScaleIntensitiesWithJacobian =
false;
38 m_LinearTransform =
false;
45 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
50 Superclass::PrintSelf(os,indent);
52 os << indent <<
"DefaultPixelValue: " 53 <<
static_cast<typename itk::NumericTraits<PixelType>::PrintType
>(m_DefaultPixelValue)
55 os << indent <<
"Size: " << m_Size << std::endl;
56 os << indent <<
"OutputStartIndex: " << m_OutputStartIndex << std::endl;
57 os << indent <<
"OutputOrigin: " << m_OutputOrigin << std::endl;
58 os << indent <<
"OutputSpacing: " << m_OutputSpacing << std::endl;
59 os << indent <<
"OutputDirection: " << m_OutputDirection << std::endl;
60 os << indent <<
"Transform: " << m_Transform.GetPointer() << std::endl;
61 os << indent <<
"Interpolator: " << m_Interpolator.GetPointer() << std::endl;
62 os << indent <<
"UseReferenceImage: " << (m_UseReferenceImage ?
"On" :
"Off") << std::endl;
63 os << indent <<
"Scale intensities with Jacobian : " << (m_ScaleIntensitiesWithJacobian ?
"On" :
"Off") << std::endl;
71 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
72 itk::LightObject::Pointer
76 itk::LightObject::Pointer outputPointer = Superclass::InternalClone();
78 Self *castPointer = dynamic_cast <
Self *> (outputPointer.GetPointer());
87 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
93 this->SetOutputSpacing( s );
100 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
106 this->SetOutputOrigin( p );
109 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
114 if (m_Transform != transform)
116 m_Transform = transform;
119 m_LinearTransform = (tmpTrsf != 0);
130 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
137 itkExceptionMacro(<<
"Transform not set");
141 m_Interpolator = itk::LinearInterpolateImageFunction<InputImageType, TInterpolatorPrecisionType>::New();
144 m_Interpolator->SetInputImage(this->GetInput());
150 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
156 m_Interpolator->SetInputImage(
nullptr);
162 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
174 typedef itk::ImageRegionIteratorWithIndex<TOutputImage> OutputIterator;
176 OutputIterator outIt(outputPtr, outputRegionForThread);
183 typedef itk::ContinuousIndex<TInterpolatorPrecisionType, ImageDimension> ContinuousIndexType;
184 ContinuousIndexType inputIndex;
186 typedef typename InterpolatorType::OutputType OutputType;
190 const PixelType minValue = itk::NumericTraits<PixelType >::NonpositiveMin();
191 const PixelType maxValue = itk::NumericTraits<PixelType >::max();
193 const OutputType minOutputValue =
static_cast<OutputType
>(minValue);
194 const OutputType maxOutputValue =
static_cast<OutputType
>(maxValue);
199 while ( !outIt.IsAtEnd() )
202 outputPtr->TransformIndexToPhysicalPoint( outIt.GetIndex(), outputPoint );
205 inputPoint = m_Transform->TransformPoint(outputPoint);
206 inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, inputIndex);
209 if( m_Interpolator->IsInsideBuffer(inputIndex) )
212 OutputType value = m_Interpolator->EvaluateAtContinuousIndex(inputIndex);
214 if (m_ScaleIntensitiesWithJacobian)
216 double jacobianValue = 1;
217 if (m_LinearTransform)
218 jacobianValue = this->ComputeLinearJacobianValue();
220 jacobianValue = this->ComputeLocalJacobianValue(outIt.GetIndex());
222 value *= jacobianValue;
225 if( value < minOutputValue )
229 else if( value > maxOutputValue )
235 pixval =
static_cast<PixelType>( value );
241 outIt.Set(m_DefaultPixelValue);
255 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
261 Superclass::GenerateInputRequestedRegion();
263 if ( !this->GetInput() )
270 const_cast< TInputImage *
>( this->GetInput() );
274 inputRegion = inputPtr->GetLargestPossibleRegion();
275 inputPtr->SetRequestedRegion(inputRegion);
284 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
289 Self * surrogate =
const_cast< Self *
>( this );
291 static_cast<const OutputImageType *
>(surrogate->itk::ProcessObject::GetInput(1));
292 return referenceImage;
300 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
305 itkDebugMacro(
"setting input ReferenceImage to " << image);
306 if( image != static_cast<const TOutputImage *>(this->itk::ProcessObject::GetInput( 1 )) )
308 this->itk::ProcessObject::SetNthInput(1, const_cast< TOutputImage *>( image ) );
314 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
319 this->SetOutputOrigin ( image->GetOrigin() );
320 this->SetOutputSpacing ( image->GetSpacing() );
321 this->SetOutputDirection ( image->GetDirection() );
322 this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() );
323 this->SetSize ( image->GetLargestPossibleRegion().GetSize() );
329 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
335 Superclass::GenerateOutputInformation();
347 if( m_UseReferenceImage && referenceImage )
349 outputPtr->SetLargestPossibleRegion( referenceImage->GetLargestPossibleRegion() );
353 typename TOutputImage::RegionType outputLargestPossibleRegion;
354 outputLargestPossibleRegion.SetSize( m_Size );
355 outputLargestPossibleRegion.SetIndex( m_OutputStartIndex );
356 outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion );
360 if (m_UseReferenceImage && referenceImage)
362 outputPtr->SetOrigin( referenceImage->GetOrigin() );
363 outputPtr->SetSpacing( referenceImage->GetSpacing() );
364 outputPtr->SetDirection( referenceImage->GetDirection() );
368 outputPtr->SetOrigin( m_OutputOrigin );
369 outputPtr->SetSpacing( m_OutputSpacing );
370 outputPtr->SetDirection( m_OutputDirection );
378 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
379 itk::ModifiedTimeType
383 itk::ModifiedTimeType latestTime = itk::Object::GetMTime();
387 if( latestTime < m_Transform->GetMTime() )
389 latestTime = m_Transform->GetMTime();
395 if( latestTime < m_Interpolator->GetMTime() )
397 latestTime = m_Interpolator->GetMTime();
404 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
409 vnl_matrix_fixed <double,ImageDimension,ImageDimension> jacMatrix;
412 for (
unsigned int i = 0;i < ImageDimension;++i)
413 for (
unsigned int j = 0;j < ImageDimension;++j)
414 jacMatrix(i,j) = matrixTrsf->GetMatrix()(i,j);
416 double jacValue = vnl_det(jacMatrix);
423 template <
class TInputImage,
class TOutputImage,
class TInterpolatorPrecisionType>
429 startIndDef = this->GetOutput()->GetLargestPossibleRegion().GetIndex();
430 endIndDef = startIndDef + this->GetOutput()->GetLargestPossibleRegion().GetSize();
432 vnl_matrix_fixed <double,ImageDimension,ImageDimension> jacMatrix;
434 vnl_matrix_fixed <double,ImageDimension,ImageDimension> deltaMatrix;
439 vnl_matrix_fixed <double,ImageDimension,ImageDimension> resDiff;
445 for (
unsigned int i = 0;i < ImageDimension;++i)
450 if (posBef[i] < startIndDef[i])
451 posBef[i] = startIndDef[i];
453 outputPtr->TransformIndexToPhysicalPoint(posBef,tmpPosBef);
458 if (posAfter[i] >= endIndDef[i])
459 posAfter[i] = endIndDef[i] - 1;
461 outputPtr->TransformIndexToPhysicalPoint(posAfter,tmpPosAfter);
463 if (posAfter[i] == posBef[i])
465 deltaMatrix(i,i) = 1;
469 for (
unsigned int j = 0;j < ImageDimension;++j)
470 deltaMatrix(i,j) = tmpPosAfter[j] - tmpPosBef[j];
472 tmpPos = m_Transform->TransformPoint(tmpPosAfter);
473 for (
unsigned int j = 0;j < ImageDimension;++j)
474 resDiff(i,j) = tmpPos[j];
476 tmpPos = m_Transform->TransformPoint(tmpPosBef);
477 for (
unsigned int j = 0;j < ImageDimension;++j)
478 resDiff(i,j) -= tmpPos[j];
481 vnl_matrix_inverse <double> invDeltaMatrix(deltaMatrix.as_matrix());
482 deltaMatrix = invDeltaMatrix.inverse();
484 for (
unsigned int i = 0;i < ImageDimension;++i)
486 for (
unsigned int j = 0;j < ImageDimension;++j)
489 for (
unsigned int k = 0;k < ImageDimension;++k)
490 jacMatrix(j,i) += deltaMatrix(i,k)*resDiff(k,j);
494 if (startIndDef[2] == (endIndDef[2]-1))
497 double jacValue = vnl_det(jacMatrix);
InputImageType::ConstPointer InputImageConstPointer
InterpolatorType::PointType PointType
virtual void AfterThreadedGenerateData() ITK_OVERRIDE
InputImageType::Pointer InputImagePointer
TOutputImage OutputImageType
TOutputImage::PointType OriginPointType
itk::ImageBase< itkGetStaticConstMacro(ImageDimension)> ImageBaseType
double ComputeLinearJacobianValue()
const TOutputImage * GetReferenceImage() const
InputImageType::RegionType InputImageRegionType
virtual void BeforeThreadedGenerateData() ITK_OVERRIDE
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) ITK_OVERRIDE
OutputImageType::Pointer OutputImagePointer
virtual void SetOutputSpacing(SpacingType _arg)
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
virtual itk::LightObject::Pointer InternalClone() const ITK_OVERRIDE
TOutputImage::PixelType PixelType
TOutputImage::SpacingType SpacingType
TOutputImage::RegionType OutputImageRegionType
void SetScaleIntensitiesWithJacobian(bool scale)
void SetReferenceImage(const TOutputImage *image)
itk::MatrixOffsetTransformBase< TInterpolatorPrecisionType, itkGetStaticConstMacro(ImageDimension), itkGetStaticConstMacro(ImageDimension)> MatrixTransformType
itk::Transform< TInterpolatorPrecisionType, itkGetStaticConstMacro(ImageDimension), itkGetStaticConstMacro(ImageDimension)> TransformType
virtual void GenerateOutputInformation() ITK_OVERRIDE
virtual void GenerateInputRequestedRegion() ITK_OVERRIDE
void SetTransform(TransformType *transform)
itk::ModifiedTimeType GetMTime() const ITK_OVERRIDE
double ComputeLocalJacobianValue(const InputIndexType &index)
InputImageType::IndexType InputIndexType
void SetOutputParametersFromImage(const ImageBaseType *image)
virtual void SetOutputOrigin(OriginPointType _arg)