Orfeo Toolbox  3.16
itkWarpImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkWarpImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2009-10-29 11:19:10 $
7  Version: $Revision: 1.34 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkWarpImageFilter_txx
18 #define __itkWarpImageFilter_txx
19 #include "itkWarpImageFilter.h"
20 
21 #include "itkImageRegionIterator.h"
23 #include "itkNumericTraits.h"
24 #include "itkProgressReporter.h"
25 #include "itkContinuousIndex.h"
26 #include "vnl/vnl_math.h"
27 
29 #include "itkPixelBuilder.h"
30 
31 namespace itk
32 {
33 
37 template <class TInputImage,class TOutputImage,class TDeformationField>
40 {
41  // Setup the number of required inputs
42  this->SetNumberOfRequiredInputs( 2 );
43 
44  // Setup default values
45  m_OutputSpacing.Fill( 1.0 );
46  m_OutputOrigin.Fill( 0.0 );
47  m_OutputDirection.SetIdentity();
48  m_OutputSize.Fill(0);
49  PixelBuilder<PixelType>::Zero(m_EdgePaddingValue,1);
50  m_OutputStartIndex.Fill(0);
51  // Setup default interpolator
52  typename DefaultInterpolatorType::Pointer interp =
53  DefaultInterpolatorType::New();
54 
55  m_Interpolator =
56  static_cast<InterpolatorType*>( interp.GetPointer() );
57 }
58 
62 template <class TInputImage,class TOutputImage,class TDeformationField>
63 void
65 ::PrintSelf(std::ostream& os, Indent indent) const
66 {
67 
68  Superclass::PrintSelf(os, indent);
69 
70  os << indent << "OutputSpacing: " << m_OutputSpacing << std::endl;
71  os << indent << "OutputOrigin: " << m_OutputOrigin << std::endl;
72  os << indent << "OutputDirection: " << m_OutputDirection << std::endl;
73  os << indent << "OutputSize: " << m_OutputSize << std::endl;
74  os << indent << "OutputStartIndex: " << m_OutputStartIndex << std::endl;
75  os << indent << "EdgePaddingValue: "
76  << static_cast<typename NumericTraits<PixelType>::PrintType>(m_EdgePaddingValue)
77  << std::endl;
78  os << indent << "Interpolator: " << m_Interpolator.GetPointer() << std::endl;
79 
80 }
81 
82 
87 template <class TInputImage,class TOutputImage,class TDeformationField>
88 void
91  const double* spacing)
92 {
93  SpacingType s(spacing);
94  this->SetOutputSpacing( s );
95 }
96 
97 
102 template <class TInputImage,class TOutputImage,class TDeformationField>
103 void
106  const double* origin)
107 {
108  PointType p(origin);
109  this->SetOutputOrigin(p);
110 }
111 
113 template <class TInputImage,class TOutputImage,class TDeformationField>
114 void
117 {
118  this->SetOutputOrigin ( image->GetOrigin() );
119  this->SetOutputSpacing ( image->GetSpacing() );
120  this->SetOutputDirection ( image->GetDirection() );
121  this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() );
122  this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() );
123 }
124 
129 template <class TInputImage,class TOutputImage,class TDeformationField>
130 void
133  const DeformationFieldType * field )
134 {
135  // const cast is needed because the pipeline is not const-correct.
136  DeformationFieldType * input =
137  const_cast< DeformationFieldType * >( field );
138  this->ProcessObject::SetNthInput( 1, input );
139 }
140 
141 
145 template <class TInputImage,class TOutputImage,class TDeformationField>
147 ::DeformationFieldType *
150 {
151  return static_cast<DeformationFieldType *>
152  ( this->ProcessObject::GetInput( 1 ));
153 }
154 
155 
161 template <class TInputImage,class TOutputImage,class TDeformationField>
162 void
165 {
166 
167  if( !m_Interpolator )
168  {
169  itkExceptionMacro(<< "Interpolator not set");
170  }
171  DeformationFieldPointer fieldPtr = this->GetDeformationField();
172 
173  // Connect input image to interpolator
174  m_Interpolator->SetInputImage( this->GetInput() );
175  typename DeformationFieldType::RegionType defRegion =
176  fieldPtr->GetLargestPossibleRegion();
177  typename OutputImageType::RegionType outRegion =
178  this->GetOutput()->GetLargestPossibleRegion();
179  m_DefFieldSizeSame = outRegion == defRegion;
180  if(!m_DefFieldSizeSame)
181  {
182  m_StartIndex = fieldPtr->GetBufferedRegion().GetIndex();
183  for(unsigned i = 0; i < ImageDimension; i++)
184  {
185  m_EndIndex[i] = m_StartIndex[i] +
186  fieldPtr->GetBufferedRegion().GetSize()[i] - 1;
187  }
188  }
189 }
190 
194 template <class TInputImage,class TOutputImage,class TDeformationField>
195 void
198 {
199  // Disconnect input image from interpolator
200  m_Interpolator->SetInputImage( NULL );
201 }
202 
203 
204 template <class TInputImage,class TOutputImage,class TDeformationField>
205 typename WarpImageFilter<TInputImage,
206  TOutputImage,
207  TDeformationField>::DisplacementType
210 {
211  DeformationFieldPointer fieldPtr = this->GetDeformationField();
213  fieldPtr->TransformPhysicalPointToContinuousIndex(point,index);
214  unsigned int dim; // index over dimension
219  IndexType baseIndex;
220  IndexType neighIndex;
221  double distance[ImageDimension];
222 
223  for( dim = 0; dim < ImageDimension; dim++ )
224  {
225  baseIndex[dim] = Math::Floor< IndexValueType >( index[dim] );
226 
227  if( baseIndex[dim] >= m_StartIndex[dim] )
228  {
229  if( baseIndex[dim] < m_EndIndex[dim] )
230  {
231  distance[dim] = index[dim] - static_cast<double>( baseIndex[dim] );
232  }
233  else
234  {
235  baseIndex[dim] = m_EndIndex[dim];
236  distance[dim] = 0.0;
237  }
238  }
239  else
240  {
241  baseIndex[dim] = m_StartIndex[dim];
242  distance[dim] = 0.0;
243  }
244  }
245 
251  DisplacementType output;
252  output.Fill(0);
253 
254  double totalOverlap = 0.0;
255  unsigned int numNeighbors(1 << TInputImage::ImageDimension);
256 
257  for( unsigned int counter = 0; counter < numNeighbors; counter++ )
258  {
259  double overlap = 1.0; // fraction overlap
260  unsigned int upper = counter; // each bit indicates upper/lower neighbour
261 
262  // get neighbor index and overlap fraction
263  for( dim = 0; dim < ImageDimension; dim++ )
264  {
265 
266  if( upper & 1 )
267  {
268  neighIndex[dim] = baseIndex[dim] + 1;
269  overlap *= distance[dim];
270  }
271  else
272  {
273  neighIndex[dim] = baseIndex[dim];
274  overlap *= 1.0 - distance[dim];
275  }
276 
277  upper >>= 1;
278 
279  }
280 
281  // get neighbor value only if overlap is not zero
282  if( overlap )
283  {
284  const DisplacementType input =
285  fieldPtr->GetPixel( neighIndex );
286  for(unsigned int k = 0; k < PixelSizeFinder(input); k++ )
287  {
288  output[k] += overlap * static_cast<double>( input[k] );
289  }
290  totalOverlap += overlap;
291  }
292 
293  if( totalOverlap == 1.0 )
294  {
295  // finished
296  break;
297  }
298 
299  }
300  return ( output );
301 }
302 
303 template <class PixelType> unsigned int PixelSizeFinder(itk::VariableLengthVector<PixelType> pix)
304 {
305  return pix.Size();
306 }
307 template <class PixelType> unsigned int PixelSizeFinder(PixelType pix)
308 {
309  return PixelType::Dimension;
310 }
311 
315 template <class TInputImage,class TOutputImage,class TDeformationField>
316 void
319  const OutputImageRegionType& outputRegionForThread,
320  int threadId )
321 {
322 
323  InputImageConstPointer inputPtr = this->GetInput();
324  OutputImagePointer outputPtr = this->GetOutput();
325  DeformationFieldPointer fieldPtr = this->GetDeformationField();
326 
327  // support progress methods/callbacks
328  ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
329 
330  // iterator for the output image
332  outputPtr, outputRegionForThread );
333  IndexType index;
334  PointType point;
335  DisplacementType displacement;
336  if(this->m_DefFieldSizeSame)
337  {
338  // iterator for the deformation field
340  fieldIt(fieldPtr, outputRegionForThread );
341 
342  while( !outputIt.IsAtEnd() )
343  {
344  // get the output image index
345  index = outputIt.GetIndex();
346  outputPtr->TransformIndexToPhysicalPoint( index, point );
347 
348  // get the required displacement
349  displacement = fieldIt.Get();
350 
351  // compute the required input image point
352  for(unsigned int j = 0; j < ImageDimension; j++ )
353  {
354  point[j] += displacement[j];
355  }
356 
357  // get the interpolated value
358  if( m_Interpolator->IsInsideBuffer( point ) )
359  {
360  PixelType value =
361  static_cast<PixelType>(m_Interpolator->Evaluate( point ) );
362  outputIt.Set( value );
363  }
364  else
365  {
366  outputIt.Set( m_EdgePaddingValue );
367  }
368  ++outputIt;
369  ++fieldIt;
370  progress.CompletedPixel();
371  }
372  }
373  else
374  {
375  while( !outputIt.IsAtEnd() )
376  {
377  // get the output image index
378  index = outputIt.GetIndex();
379  outputPtr->TransformIndexToPhysicalPoint( index, point );
380 
381  displacement = this->EvaluateDeformationAtPhysicalPoint(point);
382  // compute the required input image point
383  for(unsigned int j = 0; j < ImageDimension; j++ )
384  {
385  point[j] += displacement[j];
386  }
387 
388  // get the interpolated value
389  if( m_Interpolator->IsInsideBuffer( point ) )
390  {
391  PixelType value =
392  static_cast<PixelType>(m_Interpolator->Evaluate( point ) );
393  outputIt.Set( value );
394  }
395  else
396  {
397  outputIt.Set( m_EdgePaddingValue );
398  }
399  ++outputIt;
400  progress.CompletedPixel();
401  }
402  }
403 }
404 
405 
406 template <class TInputImage,class TOutputImage,class TDeformationField>
407 void
410 {
411 
412  // call the superclass's implementation
413  Superclass::GenerateInputRequestedRegion();
414 
415  // request the largest possible region for the input image
416  InputImagePointer inputPtr =
417  const_cast< InputImageType * >( this->GetInput() );
418 
419  if( inputPtr )
420  {
421  inputPtr->SetRequestedRegionToLargestPossibleRegion();
422  }
423 
424  // just propagate up the output requested region for the
425  // deformation field.
426  DeformationFieldPointer fieldPtr = this->GetDeformationField();
427  OutputImagePointer outputPtr = this->GetOutput();
428  if(fieldPtr.IsNotNull() )
429  {
430  fieldPtr->SetRequestedRegion( outputPtr->GetRequestedRegion() );
431  if(!fieldPtr->VerifyRequestedRegion())
432  {
433  fieldPtr->SetRequestedRegion(fieldPtr->GetLargestPossibleRegion());
434  }
435  }
436 }
437 
438 
439 template <class TInputImage,class TOutputImage,class TDeformationField>
440 void
443 {
444  // call the superclass's implementation of this method
445  Superclass::GenerateOutputInformation();
446 
447  OutputImagePointer outputPtr = this->GetOutput();
448 
449  outputPtr->SetSpacing( m_OutputSpacing );
450  outputPtr->SetOrigin( m_OutputOrigin );
451  outputPtr->SetDirection( m_OutputDirection );
452 
453  DeformationFieldPointer fieldPtr = this->GetDeformationField();
454  if( this->m_OutputSize[0] == 0 &&
455  fieldPtr.IsNotNull())
456  {
457  outputPtr->SetLargestPossibleRegion( fieldPtr->
458  GetLargestPossibleRegion() );
459  }
460  else
461  {
462  OutputImageRegionType region;
463  region.SetSize(this->m_OutputSize);
464  region.SetIndex(this->m_OutputStartIndex);
465  outputPtr->SetLargestPossibleRegion(region);
466  }
467 }
468 
469 
470 } // end namespace itk
471 
472 #endif

Generated at Sun May 19 2013 00:14:51 for Orfeo Toolbox with doxygen 1.8.3.1