Orfeo Toolbox  3.16
itkFiniteDifferenceImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkFiniteDifferenceImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2009-10-19 15:32:55 $
7  Version: $Revision: 1.51 $
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 __itkFiniteDifferenceImageFilter_txx
18 #define __itkFiniteDifferenceImageFilter_txx
19 
20 #include "itkImageRegionIterator.h"
22 #include "itkExceptionObject.h"
23 #include "itkEventObject.h"
25 
26 namespace itk {
27 
28 template <class TInputImage, class TOutputImage>
31 {
32  m_UseImageSpacing = false;
33  m_ElapsedIterations = 0;
34  m_DifferenceFunction = 0;
35  m_NumberOfIterations = NumericTraits<unsigned int>::max();
36  m_MaximumRMSError = 0.0;
37  m_RMSChange = 0.0;
38  m_State = UNINITIALIZED;
39  m_ManualReinitialization = false;
40  this->InPlaceOff();
41 }
42 
43 template <class TInputImage, class TOutputImage>
46 {
47 }
48 
49 template <class TInputImage, class TOutputImage>
50 void
53 {
54  // Test whether the output pixel type (or its components) are not of type
55  // float or double:
57  {
58  itkWarningMacro("Output pixel type MUST be float or double to prevent computational errors");
59  }
60 
61  if (this->GetState() == UNINITIALIZED)
62  {
63  // Allocate the output image
64  this->AllocateOutputs();
65 
66  // Copy the input image to the output image. Algorithms will operate
67  // directly on the output image and the update buffer.
68  this->CopyInputToOutput();
69 
70  // Set the coefficients of the Function and consider the use of images spacing.
71  this->InitializeFunctionCoefficients();
72 
73  // Perform any other necessary pre-iteration initialization.
74  this->Initialize();
75 
76  // Allocate the internal update buffer. This takes place entirely within
77  // the subclass, since this class cannot define an update buffer type.
78  this->AllocateUpdateBuffer();
79 
80  this->SetStateToInitialized();
81  m_ElapsedIterations = 0;
82  }
83 
84  // Iterative algorithm
85  TimeStepType dt;
86 
87  while ( ! this->Halt() )
88  {
89  this->InitializeIteration(); // An optional method for precalculating
90  // global values, or otherwise setting up
91  // for the next iteration
92  dt = this->CalculateChange();
93  this->ApplyUpdate(dt);
94  ++m_ElapsedIterations;
95 
96  // Invoke the iteration event.
97  this->InvokeEvent( IterationEvent() );
98  if( this->GetAbortGenerateData() )
99  {
100  this->InvokeEvent( IterationEvent() );
101  this->ResetPipeline();
102  throw ProcessAborted(__FILE__,__LINE__);
103  }
104  }
105 
106  if (m_ManualReinitialization == false)
107  {
108  this->SetStateToUninitialized(); // Reset the state once execution is
109  // completed
110  }
111  // Any further processing of the solution can be done here.
112  this->PostProcessOutput();
113 }
114 
118 template <class TInputImage, class TOutputImage>
119 void
122 {
123  // call the superclass' implementation of this method
124  // copy the output requested region to the input requested region
125  Superclass::GenerateInputRequestedRegion();
126 
127  // get pointers to the input
128  typename Superclass::InputImagePointer inputPtr =
129  const_cast< TInputImage * >( this->GetInput());
130 
131  if ( !inputPtr )
132  {
133  return;
134  }
135 
136  // Get the size of the neighborhood on which we are going to operate. This
137  // radius is supplied by the difference function we are using.
138  RadiusType radius = this->GetDifferenceFunction()->GetRadius();
139 
140  // Try to set up a buffered region that will accommodate our
141  // neighborhood operations. This may not be possible and we
142  // need to be careful not to request a region outside the largest
143  // possible region, because the pipeline will give us whatever we
144  // ask for.
145 
146  // get a copy of the input requested region (should equal the output
147  // requested region)
148  typename TInputImage::RegionType inputRequestedRegion;
149  inputRequestedRegion = inputPtr->GetRequestedRegion();
150 
151  // pad the input requested region by the operator radius
152  inputRequestedRegion.PadByRadius( radius );
153 
154 // std::cout << "inputRequestedRegion: " << inputRequestedRegion << std::endl;
155 // std::cout << "largestPossibleRegion: " << inputPtr->GetLargestPossibleRegion() << std::endl;
156 
157  // crop the input requested region at the input's largest possible region
158  if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
159  {
160  inputPtr->SetRequestedRegion( inputRequestedRegion );
161  return;
162  }
163  else
164  {
165  // Couldn't crop the region (requested region is outside the largest
166  // possible region). Throw an exception.
167 
168  // store what we tried to request (prior to trying to crop)
169  inputPtr->SetRequestedRegion( inputRequestedRegion );
170 
171  // build an exception
172  InvalidRequestedRegionError e(__FILE__, __LINE__);
173  e.SetLocation(ITK_LOCATION);
174  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
175  e.SetDataObject(inputPtr);
176  throw e;
177  }
178 
179 }
180 
181 template <class TInputImage, class TOutputImage>
184 ::ResolveTimeStep(const TimeStepType *timeStepList, const bool *valid, int size)
185 {
186  TimeStepType min;
187  bool flag;
189 
190  // grab first valid value
191  flag = false;
192  for (int i = 0; i < size; ++i)
193  {
194  if (valid[i])
195  {
196  min = timeStepList[i];
197  flag = true;
198  break;
199  }
200  }
201 
202  if (!flag)
203  { // no values!
204  throw ExceptionObject(__FILE__, __LINE__);
205  }
206 
207  // find minimum value
208  for (int i = 0; i < size; ++i)
209  { if ( valid[i] && (timeStepList[i] < min) ) min = timeStepList[i]; }
210 
211  return min;
212 }
213 
214 template <class TInputImage, class TOutputImage>
215 bool
218 {
219  if (m_NumberOfIterations != 0)
220  {
221  this->UpdateProgress( static_cast<float>( this->GetElapsedIterations() ) /
222  static_cast<float>( m_NumberOfIterations ) );
223  }
224 
225  if (this->GetElapsedIterations() >= m_NumberOfIterations)
226  {
227  return true;
228  }
229  else if ( this->GetElapsedIterations() == 0)
230  {
231  return false;
232  }
233  else if ( this->GetMaximumRMSError() > m_RMSChange )
234  {
235  return true;
236  }
237  else
238  {
239  return false;
240  }
241 }
242 
243 
244 template <class TInputImage, class TOutputImage>
245 void
248 {
249  // Set the coefficients for the derivatives
250  double coeffs[TOutputImage::ImageDimension];
251 
252  if ( this->m_UseImageSpacing )
253  {
254  const TOutputImage * outputImage = this->GetOutput();
255  if( outputImage == NULL )
256  {
257  itkExceptionMacro("Output image is NULL");
258  }
259 
260  typedef typename TOutputImage::SpacingType SpacingType;
261  const SpacingType spacing = outputImage->GetSpacing();
262 
263  for (unsigned int i = 0; i < TOutputImage::ImageDimension; i++)
264  {
265  coeffs[i] = 1.0 / spacing[i];
266  }
267  }
268  else
269  {
270  for (unsigned int i = 0; i < TOutputImage::ImageDimension; i++)
271  {
272  coeffs[i] = 1.0;
273  }
274  }
275  m_DifferenceFunction->SetScaleCoefficients(coeffs);
276 }
277 
278 template <class TInputImage, class TOutputImage>
279 void
281 ::PrintSelf(std::ostream& os, Indent indent) const
282 {
283  Superclass::PrintSelf(os, indent);
284 
285  os << indent << "ElapsedIterations: " << m_ElapsedIterations << std::endl;
286  os << indent << "UseImageSpacing: " << (m_UseImageSpacing ? "On" : "Off") << std::endl;
287  os << indent << "State: " << m_State << std::endl;
288  os << indent << "MaximumRMSError: " << m_MaximumRMSError << std::endl;
289  os << indent << "NumberOfIterations: " << m_NumberOfIterations << std::endl;
290  os << indent << "ManualReinitialization: " << m_ManualReinitialization << std::endl;
291  os << indent << "RMSChange: " << m_RMSChange << std::endl;
292  os << std::endl;
293  if (m_DifferenceFunction)
294  {
295  os << indent << "DifferenceFunction: " << std::endl;
296  m_DifferenceFunction->Print(os,indent.GetNextIndent());
297  }
298  else
299  {
300  os << indent << "DifferenceFunction: " << "(None)" << std::endl;
301  }
302  os << std::endl;
303 }
304 
305 
306 }// end namespace itk
307 
308 #endif

Generated at Sat May 18 2013 23:39:08 for Orfeo Toolbox with doxygen 1.8.3.1