1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
18 #ifndef __clitkTransformToDeformationFieldSource_txx
19 #define __clitkTransformToDeformationFieldSource_txx
20 #include "clitkTransformToDeformationFieldSource.h"
22 #include "itkIdentityTransform.h"
23 #include "itkProgressReporter.h"
24 #include "itkImageRegionIteratorWithIndex.h"
25 #include "itkImageLinearIteratorWithIndex.h"
32 template <class TOutputImage, class TTransformPrecisionType>
33 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>::TransformToDeformationFieldSource()
35 this->m_OutputSpacing.Fill(1.0);
36 this->m_OutputOrigin.Fill(0.0);
37 this->m_OutputDirection.SetIdentity();
41 this->m_OutputRegion.SetSize( size );
45 this->m_OutputRegion.SetIndex( index );
48 = itk::IdentityTransform<TTransformPrecisionType, ImageDimension>::New();
52 * Print out a description of self
54 * \todo Add details about this class
56 template <class TOutputImage, class TTransformPrecisionType>
58 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
59 ::PrintSelf( std::ostream & os, itk::Indent indent ) const
61 Superclass::PrintSelf( os, indent );
63 os << indent << "OutputRegion: " << this->m_OutputRegion << std::endl;
64 os << indent << "OutputSpacing: " << this->m_OutputSpacing << std::endl;
65 os << indent << "OutputOrigin: " << this->m_OutputOrigin << std::endl;
66 os << indent << "OutputDirection: " << this->m_OutputDirection << std::endl;
67 os << indent << "Transform: " << this->m_Transform.GetPointer() << std::endl;
71 * Set the output image size.
73 template <class TOutputImage, class TTransformPrecisionType>
75 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
76 ::SetOutputSize( const SizeType & size )
78 this->m_OutputRegion.SetSize( size );
82 * Get the output image size.
84 template <class TOutputImage, class TTransformPrecisionType>
85 const typename TransformToDeformationFieldSource<TOutputImage,
86 TTransformPrecisionType>
88 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
91 return this->m_OutputRegion.GetSize();
95 * Set the output image index.
97 template <class TOutputImage, class TTransformPrecisionType>
99 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
100 ::SetOutputIndex( const IndexType & index )
102 this->m_OutputRegion.SetIndex( index );
106 * Get the output image index.
108 template <class TOutputImage, class TTransformPrecisionType>
109 const typename TransformToDeformationFieldSource<TOutputImage,
110 TTransformPrecisionType>
112 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
115 return this->m_OutputRegion.GetIndex();
119 * Set the output image spacing.
121 template <class TOutputImage, class TTransformPrecisionType>
123 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
124 ::SetOutputSpacing( const double *spacing )
126 SpacingType s( spacing );
128 this->SetOutputSpacing( s );
129 } // end SetOutputSpacing()
132 * Set the output image origin.
134 template <class TOutputImage, class TTransformPrecisionType>
136 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
137 ::SetOutputOrigin( const double *origin )
139 OriginType p( origin );
141 this->SetOutputOrigin( p );
144 /** Helper method to set the output parameters based on this image */
145 template <class TOutputImage, class TTransformPrecisionType>
147 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
148 ::SetOutputParametersFromImage ( const ImageBaseType *image )
152 itkExceptionMacro(<< "Cannot use a null image reference");
155 this->SetOutputOrigin( image->GetOrigin() );
156 this->SetOutputSpacing( image->GetSpacing() );
157 this->SetOutputDirection( image->GetDirection() );
158 this->SetOutputRegion( image->GetLargestPossibleRegion() );
159 } // end SetOutputParametersFromImage()
162 * Set up state of filter before multi-threading.
163 * InterpolatorType::SetInputImage is not thread-safe and hence
164 * has to be set up before ThreadedGenerateData
166 template <class TOutputImage, class TTransformPrecisionType>
168 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
169 ::BeforeThreadedGenerateData( void )
171 if ( !this->m_Transform )
173 itkExceptionMacro(<< "Transform not set");
175 } // end BeforeThreadedGenerateData()
178 * ThreadedGenerateData
180 template <class TOutputImage, class TTransformPrecisionType>
182 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
183 ::ThreadedGenerateData(
184 const OutputImageRegionType & outputRegionForThread,
187 // Check whether we can use a fast path for resampling. Fast path
188 // can be used if the transformation is linear. Transform respond
189 // to the IsLinear() call.
190 if ( this->m_Transform->IsLinear() )
192 this->LinearThreadedGenerateData( outputRegionForThread, threadId );
196 // Otherwise, we use the normal method where the transform is called
197 // for computing the transformation of every point.
198 this->NonlinearThreadedGenerateData( outputRegionForThread, threadId );
199 } // end ThreadedGenerateData()
201 template <class TOutputImage, class TTransformPrecisionType>
203 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
204 ::NonlinearThreadedGenerateData(
205 const OutputImageRegionType & outputRegionForThread,
208 // Get the output pointer
209 OutputImagePointer outputPtr = this->GetOutput();
211 // Create an iterator that will walk the output region for this thread.
212 typedef itk::ImageRegionIteratorWithIndex<TOutputImage> OutputIteratorType;
213 OutputIteratorType outIt( outputPtr, outputRegionForThread );
215 // Define a few variables that will be used to translate from an input pixel
216 // to an output pixel
217 PointType outputPoint; // Coordinates of output pixel
218 PointType transformedPoint; // Coordinates of transformed pixel
219 PixelType deformation; // the difference
221 // Support for progress methods/callbacks
222 itk::ProgressReporter progress( this, threadId,
223 outputRegionForThread.GetNumberOfPixels() );
225 // Walk the output region
227 while ( !outIt.IsAtEnd() )
229 // Determine the index of the current output pixel
230 outputPtr->TransformIndexToPhysicalPoint( outIt.GetIndex(), outputPoint );
232 // Compute corresponding input pixel position
233 transformedPoint = this->m_Transform->TransformPoint( outputPoint );
235 // Compute the deformation
236 for ( unsigned int i = 0; i < SpaceDimension; ++i )
238 deformation[i] = static_cast<PixelValueType>(
239 transformedPoint[i] - outputPoint[i] );
243 outIt.Set( deformation );
245 // Update progress and iterator
246 progress.CompletedPixel();
249 } // end NonlinearThreadedGenerateData()
251 template <class TOutputImage, class TTransformPrecisionType>
253 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
254 ::LinearThreadedGenerateData(
255 const OutputImageRegionType & outputRegionForThread,
258 // Get the output pointer
259 OutputImagePointer outputPtr = this->GetOutput();
261 // Create an iterator that will walk the output region for this thread.
262 typedef itk::ImageLinearIteratorWithIndex<TOutputImage> OutputIteratorType;
263 OutputIteratorType outIt( outputPtr, outputRegionForThread );
265 outIt.SetDirection( 0 );
267 // Define a few indices that will be used to translate from an input pixel
268 // to an output pixel
269 PointType outputPoint; // Coordinates of current output pixel
270 PointType transformedPoint; // Coordinates of transformed pixel
271 PixelType deformation; // the difference
275 // Support for progress methods/callbacks
276 itk::ProgressReporter progress( this, threadId,
277 outputRegionForThread.GetNumberOfPixels() );
279 // Determine the position of the first pixel in the scanline
281 index = outIt.GetIndex();
282 outputPtr->TransformIndexToPhysicalPoint( index, outputPoint );
284 // Compute corresponding transformed pixel position
285 transformedPoint = this->m_Transform->TransformPoint( outputPoint );
287 // Compare with the ResampleImageFilter
290 PointType outputPointNeighbour;
291 PointType transformedPointNeighbour;
292 typedef typename PointType::VectorType VectorType;
295 outputPtr->TransformIndexToPhysicalPoint( index, outputPointNeighbour );
296 transformedPointNeighbour = this->m_Transform->TransformPoint(
297 outputPointNeighbour );
298 delta = transformedPointNeighbour - transformedPoint
299 - ( outputPointNeighbour - outputPoint );
301 // loop over the vector image
302 while ( !outIt.IsAtEnd() )
305 index = outIt.GetIndex();
306 outputPtr->TransformIndexToPhysicalPoint( index, outputPoint );
308 // Compute transformed point
309 transformedPoint = this->m_Transform->TransformPoint( outputPoint );
311 while ( !outIt.IsAtEndOfLine() )
313 // Compute the deformation
314 for ( unsigned int i = 0; i < SpaceDimension; ++i )
316 deformation[i] = static_cast<PixelValueType>(
317 transformedPoint[i] - outputPoint[i] );
321 outIt.Set( deformation );
324 progress.CompletedPixel();
326 transformedPoint += delta;
331 } // end LinearThreadedGenerateData()
334 * Inform pipeline of required output region
336 template <class TOutputImage, class TTransformPrecisionType>
338 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
339 ::GenerateOutputInformation( void )
341 // call the superclass' implementation of this method
342 Superclass::GenerateOutputInformation();
344 // get pointer to the output
345 OutputImagePointer outputPtr = this->GetOutput();
351 outputPtr->SetLargestPossibleRegion( m_OutputRegion );
353 outputPtr->SetSpacing( m_OutputSpacing );
354 outputPtr->SetOrigin( m_OutputOrigin );
355 outputPtr->SetDirection( m_OutputDirection );
356 } // end GenerateOutputInformation()
359 * Verify if any of the components has been modified.
361 template <class TOutputImage, class TTransformPrecisionType>
363 TransformToDeformationFieldSource<TOutputImage, TTransformPrecisionType>
364 ::GetMTime( void ) const
366 unsigned long latestTime = itk::Object::GetMTime();
368 if ( this->m_Transform )
370 if ( latestTime < this->m_Transform->GetMTime() )
372 latestTime = this->m_Transform->GetMTime();
378 } // end namespace clitk
380 #endif // end #ifndef _clitkTransformToDeformationFieldSource_txx