Orfeo Toolbox  3.16
itkFastMarchingUpwindGradientImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkFastMarchingUpwindGradientImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2009-07-29 10:31:53 $
7  Version: $Revision: 1.11 $
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 
18 #ifndef __itkFastMarchingUpwindGradientImageFilter_txx
19 #define __itkFastMarchingUpwindGradientImageFilter_txx
20 
22 #include "itkImageRegionIterator.h"
23 #include "itkNumericTraits.h"
24 #include "vnl/vnl_math.h"
25 #include <algorithm>
26 
27 
28 namespace itk
29 {
30 
34 template <class TLevelSet, class TSpeedImage>
37 {
38  m_TargetPoints = NULL;
39  m_ReachedTargetPoints = NULL;
40  m_GradientImage = GradientImageType::New();
41  m_GenerateGradientImage = false;
42  m_TargetOffset = 1.0;
43  m_TargetReachedMode = NoTargets;
44  m_TargetValue = 0.0;
45  m_NumberOfTargets = 0;
46 }
47 
48 
52 template <class TLevelSet, class TSpeedImage>
53 void
55 ::PrintSelf(std::ostream& os, Indent indent) const
56 {
57  Superclass::PrintSelf(os,indent);
58  os << indent << "Target points: " << m_TargetPoints.GetPointer() << std::endl;
59  os << indent << "Reached points: " << m_ReachedTargetPoints.GetPointer() << std::endl;
60  os << indent << "Gradient image: " << m_GradientImage.GetPointer() << std::endl;
61  os << indent << "Generate gradient image: " << m_GenerateGradientImage << std::endl;
62  os << indent << "Number of targets: " << m_NumberOfTargets << std::endl;
63  os << indent << "Target offset: " << m_TargetOffset << std::endl;
64  os << indent << "Target reach mode: " << m_TargetReachedMode << std::endl;
65  os << indent << "Target value: " << m_TargetValue << std::endl;
66 }
67 
71 template <class TLevelSet, class TSpeedImage>
72 void
75 {
76  Superclass::Initialize(output);
77 
78  // allocate memory for the GradientImage if requested
79  if (m_GenerateGradientImage)
80  {
81  m_GradientImage->CopyInformation( this->GetInput() );
82  m_GradientImage->SetBufferedRegion( output->GetBufferedRegion() );
83  m_GradientImage->Allocate();
84  }
85 
86  // set all gradient vectors to zero
87  if (m_GenerateGradientImage)
88  {
89  typedef ImageRegionIterator< GradientImageType > GradientIterator;
90 
91  GradientIterator gradientIt( m_GradientImage,
92  m_GradientImage->GetBufferedRegion() );
93 
94  GradientPixelType zeroGradient;
95  typedef typename GradientPixelType::ValueType GradientPixelValueType;
97  for ( gradientIt.GoToBegin(); !gradientIt.IsAtEnd(); ++gradientIt )
98  {
99  gradientIt.Set( zeroGradient );
100  }
101  }
102 
103 
104  // Need to reset the target value.
105  m_TargetValue = 0.0;
106 
107  if ( m_TargetReachedMode == SomeTargets || m_TargetReachedMode == AllTargets)
108  {
109  m_ReachedTargetPoints = NodeContainer::New();
110  }
111 
112 }
113 
114 
115 template <class TLevelSet, class TSpeedImage>
116 void
119 {
120  // cache the original stopping value that was set by the user
121  // because this subclass may change it once a target point is
122  // reached in order to control the execution of the superclass.
123  double stoppingValue = this->GetStoppingValue();
124 
125  // run the GenerateData() method of the superclass
126  try
127  {
128  Superclass::GenerateData();
129  }
130  catch (ProcessAborted &exc)
131  {
132  // process was aborted, clean up the state of the filter
133  // (most of the cleanup will have already been done by the
134  // superclass)
135 
136  // restore the original stopping value
137  this->SetStoppingValue( stoppingValue );
138  throw exc;
139  }
140 
141  // restore the original stopping value
142  this->SetStoppingValue( stoppingValue );
143 }
144 
145 
146 template <class TLevelSet, class TSpeedImage>
147 void
150  const IndexType& index,
151  const SpeedImageType * speedImage,
152  LevelSetImageType * output )
153 {
154  Superclass::UpdateNeighbors(index,speedImage,output);
155 
156  if (m_GenerateGradientImage)
157  {
158  this->ComputeGradient(index, output, this->GetLabelImage(), m_GradientImage);
159  }
160 
161  AxisNodeType node;
162 
163  // Only check for reached targets if the mode is not NoTargets and
164  // there is at least one TargetPoint.
165  if( m_TargetReachedMode != NoTargets && m_TargetPoints )
166  {
167  bool targetReached = false;
168 
169  if (m_TargetReachedMode == OneTarget)
170  {
171  typename NodeContainer::ConstIterator pointsIter = m_TargetPoints->Begin();
172  typename NodeContainer::ConstIterator pointsEnd = m_TargetPoints->End();
173  for (; pointsIter != pointsEnd; ++pointsIter )
174  {
175  node = pointsIter.Value();
176  if (node.GetIndex() == index)
177  {
178  targetReached = true;
179  break;
180  }
181  }
182  }
183  else if (m_TargetReachedMode == SomeTargets)
184  {
185  typename NodeContainer::ConstIterator pointsIter = m_TargetPoints->Begin();
186  typename NodeContainer::ConstIterator pointsEnd = m_TargetPoints->End();
187  for (; pointsIter != pointsEnd; ++pointsIter )
188  {
189  node = pointsIter.Value();
190 
191  if (node.GetIndex() == index)
192  {
193  m_ReachedTargetPoints->InsertElement(m_ReachedTargetPoints->Size(),node);
194  break;
195  }
196  }
197 
198  if (static_cast<long>(m_ReachedTargetPoints->Size()) == m_NumberOfTargets)
199  {
200  targetReached = true;
201  }
202  }
203  else if (m_TargetReachedMode == AllTargets)
204  {
205  typename NodeContainer::ConstIterator pointsIter = m_TargetPoints->Begin();
206  typename NodeContainer::ConstIterator pointsEnd = m_TargetPoints->End();
207  for (; pointsIter != pointsEnd; ++pointsIter )
208  {
209  node = pointsIter.Value();
210 
211  if (node.GetIndex() == index)
212  {
213  m_ReachedTargetPoints->InsertElement(m_ReachedTargetPoints->Size(),node);
214  break;
215  }
216  }
217 
218  if (m_ReachedTargetPoints->Size() == m_TargetPoints->Size())
219  {
220  targetReached = true;
221  }
222  }
223 
224  if (targetReached)
225  {
226  m_TargetValue = static_cast<double>(output->GetPixel(index));
227  double newStoppingValue = m_TargetValue + m_TargetOffset;
228  if (newStoppingValue < this->GetStoppingValue())
229  {
230  // This changes the stopping value that may have been set by
231  // the user. Therefore, the value set by the user needs to be
232  // cached in GenerateUpdate() so that it will be correct for
233  // future Update() commands.
234  this->SetStoppingValue(newStoppingValue);
235  }
236  }
237  }
238  else
239  {
240  m_TargetValue = static_cast<double>(output->GetPixel(index));
241  }
242 }
243 
247 template <class TLevelSet, class TSpeedImage>
248 void
251  const LevelSetImageType * output,
252  const LabelImageType * itkNotUsed(labelImage),
253  GradientImageType * gradientImage)
254 {
255  IndexType neighIndex = index;
256  typedef typename TLevelSet::PixelType LevelSetPixelType;
257  LevelSetPixelType centerPixel;
258  LevelSetPixelType dx_forward;
259  LevelSetPixelType dx_backward;
260  GradientPixelType gradientPixel;
261 
262  const LevelSetIndexType & lastIndex = this->GetLastIndex();
263  const LevelSetIndexType & startIndex = this->GetStartIndex();
264 
265  const LevelSetPixelType ZERO =
267 
268  OutputSpacingType spacing = this->GetOutput()->GetSpacing();
269 
270  unsigned int xStride[itkGetStaticConstMacro(SetDimension)];
271 
272  for ( unsigned int j = 0; j < SetDimension; j++ )
273  {
274  centerPixel = output->GetPixel(index);
275 
276  neighIndex = index;
277 
278  // Set stride of one in each direction
279  xStride[j] = 1;
280 
281  // Compute one-sided finite differences with alive neighbors
282  // (the front can only come from there)
283  dx_backward = 0.0;
284  neighIndex[j] = index[j] - xStride[j];
285 
286  if(! (neighIndex[j] > lastIndex[j] ||
287  neighIndex[j] < startIndex[j]) )
288  {
289  if ( this->GetLabelImage()->GetPixel( neighIndex ) == Superclass::AlivePoint )
290  {
291  dx_backward = centerPixel - output->GetPixel( neighIndex );
292  }
293  }
294 
295  dx_forward = 0.0;
296  neighIndex[j] = index[j] + xStride[j];
297 
298  if(! (neighIndex[j] > lastIndex[j] ||
299  neighIndex[j] < startIndex[j]) )
300  {
301  if ( this->GetLabelImage()->GetPixel( neighIndex ) == Superclass::AlivePoint )
302  {
303  dx_forward = output->GetPixel( neighIndex ) - centerPixel;
304  }
305  }
306 
307  // Compute upwind finite differences
308  if (vnl_math_max(dx_backward,-dx_forward) < ZERO)
309  {
310  gradientPixel[j] = ZERO;
311  }
312  else if (dx_backward > -dx_forward)
313  {
314  gradientPixel[j] = dx_backward;
315  }
316  else
317  {
318  gradientPixel[j] = dx_forward;
319  }
320 
321  gradientPixel[j] /= spacing[j];
322  }
323 
324  gradientImage->SetPixel( index, gradientPixel );
325 }
326 
327 } // namespace itk
328 
329 #endif

Generated at Sat Jun 15 2013 23:37:38 for Orfeo Toolbox with doxygen 1.8.3.1