Orfeo Toolbox  3.16
itkFastMarchingExtensionImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkFastMarchingExtensionImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2008-12-21 19:13:11 $
7  Version: $Revision: 1.37 $
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 __itkFastMarchingExtensionImageFilter_txx
18 #define __itkFastMarchingExtensionImageFilter_txx
19 
21 
22 namespace itk
23 {
24 
25 template <class TLevelSet, class TAuxValue, unsigned int VAuxDimension,
26  class TSpeedImage>
29 {
30 
31  m_AuxAliveValues = NULL;
32  m_AuxTrialValues = NULL;
33 
34  this->ProcessObject::SetNumberOfRequiredOutputs( 1 + AuxDimension );
35 
36  AuxImagePointer ptr;
37  for ( unsigned int k = 0; k < VAuxDimension; k++ )
38  {
39  ptr = AuxImageType::New();
40  this->ProcessObject::SetNthOutput( k+1, ptr.GetPointer() );
41  }
42 }
43 
44 
45 template <class TLevelSet, class TAuxValue, unsigned int VAuxDimension,
46  class TSpeedImage>
47 void
49 ::PrintSelf(std::ostream& os, Indent indent) const
50 {
51  Superclass::PrintSelf(os,indent);
52  os << indent << "Aux alive values: ";
53  os << m_AuxAliveValues.GetPointer() << std::endl;
54  os << indent << "Aux trail values: ";
55  os << m_AuxTrialValues.GetPointer() << std::endl;
56 }
57 
58 
59 /*
60  *
61  */
62 template <class TLevelSet, class TAuxValue, unsigned int VAuxDimension,
63  class TSpeedImage>
65 ::AuxImageType *
67 ::GetAuxiliaryImage( unsigned int idx )
68 {
69 
70  if ( idx >= AuxDimension || this->GetNumberOfOutputs() < idx + 2 )
71  {
72  return NULL;
73  }
74 
75  return static_cast<AuxImageType *>( this->ProcessObject::GetOutput(idx + 1) );
76 
77 }
78 
79 
80 /*
81  *
82  */
83 template <class TLevelSet, class TAuxValue, unsigned int VAuxDimension,
84  class TSpeedImage>
85 void
88 {
89 
90  // call the superclass implementation of this function
91  this->Superclass::GenerateOutputInformation();
92 
93  // set the size of all the auxiliary outputs
94  // to be the same as the primary output
95  typename Superclass::LevelSetPointer primaryOutput = this->GetOutput();
96  for ( unsigned int k = 0; k < VAuxDimension; k++ )
97  {
98  AuxImageType * ptr = this->GetAuxiliaryImage(k);
99  ptr->CopyInformation( primaryOutput );
100  }
101 
102 }
103 
104 
105 /*
106  *
107  */
108 template <class TLevelSet, class TAuxValue, unsigned int VAuxDimension,
109  class TSpeedImage>
110 void
113  DataObject * itkNotUsed(output) )
114 {
115 
116  // This filter requires all of the output images in the buffer.
117  for ( unsigned int j = 0; j < this->GetNumberOfOutputs(); j++ )
118  {
119  if ( this->ProcessObject::GetOutput(j) )
120  {
122  }
123  }
124 }
125 
126 
127 /*
128  *
129  */
130 template <class TLevelSet, class TAuxValue, unsigned int VAuxDimension,
131  class TSpeedImage>
132 void
135 {
136 
137  this->Superclass::Initialize( output );
138 
139  if ( this->GetAlivePoints() && !m_AuxAliveValues )
140  {
141  itkExceptionMacro(<<"in Initialize(): Null pointer for AuxAliveValues" );
142  }
143 
144  if ( m_AuxAliveValues &&
145  m_AuxAliveValues->Size() != (this->GetAlivePoints())->Size() )
146  {
147  itkExceptionMacro(<<"in Initialize(): AuxAliveValues is the wrong size" );
148  }
149 
150  if ( this->GetTrialPoints() && !m_AuxTrialValues )
151  {
152  itkExceptionMacro(<<"in Initialize(): Null pointer for AuxTrialValues" );
153  }
154 
155  if ( m_AuxTrialValues &&
156  m_AuxTrialValues->Size() != (this->GetTrialPoints())->Size() )
157  {
158  itkExceptionMacro(<<"in Initialize(): AuxTrialValues is the wrong size" );
159  }
160 
161  AuxImagePointer auxImages[AuxDimension];
162 
163  // allocate memory for the auxiliary outputs
164  for ( unsigned int k = 0; k < VAuxDimension; k++ )
165  {
166  AuxImageType * ptr = this->GetAuxiliaryImage( k );
167  ptr->SetBufferedRegion( ptr->GetRequestedRegion() );
168  ptr->Allocate();
169  auxImages[k] = ptr;
170  }
171 
172  // set all alive points to alive
173  typename Superclass::NodeType node;
174 
175  AuxValueVectorType auxVec;
176 
177  if ( m_AuxAliveValues )
178  {
179  typename AuxValueContainer::ConstIterator auxIter = m_AuxAliveValues->Begin();
180  typename Superclass::NodeContainer::ConstIterator pointsIter = (this->GetAlivePoints())->Begin();
181  typename Superclass::NodeContainer::ConstIterator pointsEnd = (this->GetAlivePoints())->End();
182 
183  for (; pointsIter != pointsEnd; ++pointsIter, ++auxIter )
184  {
185  node = pointsIter.Value();
186  auxVec = auxIter.Value();
187 
188  // check if node index is within the output level set
189  if ( !this->GetOutput()->GetBufferedRegion().IsInside( node.GetIndex() ) )
190  {
191  continue;
192  }
193 
194  for ( unsigned int k = 0; k < VAuxDimension; k++ )
195  {
196  auxImages[k]->SetPixel( node.GetIndex(), auxVec[k] );
197  }
198 
199  } // end container loop
200  } // if AuxAliveValues set
201 
202  if ( m_AuxTrialValues )
203  {
204  typename AuxValueContainer::ConstIterator auxIter = m_AuxTrialValues->Begin();
205  typename Superclass::NodeContainer::ConstIterator pointsIter = (this->GetTrialPoints())->Begin();
206  typename Superclass::NodeContainer::ConstIterator pointsEnd = (this->GetTrialPoints())->End();
207 
208  for (; pointsIter != pointsEnd; ++pointsIter, ++auxIter )
209  {
210  node = pointsIter.Value();
211  auxVec = auxIter.Value();
212 
213  // check if node index is within the output level set
214  if ( !this->GetOutput()->GetBufferedRegion().IsInside( node.GetIndex() ) )
215  {
216  continue;
217  }
218 
219  for ( unsigned int k = 0; k < VAuxDimension; k++ )
220  {
221  auxImages[k]->SetPixel( node.GetIndex(), auxVec[k] );
222  }
223 
224  } // end container loop
225 
226  } // if AuxTrialValues set
227 
228 }
229 
230 
231 template <class TLevelSet, class TAuxValue, unsigned int VAuxDimension,
232  class TSpeedImage>
233 double
236  const IndexType& index,
237  const SpeedImageType * speed,
238  LevelSetImageType * output )
239 {
240 
241  // A extension value at node is choosen such that
242  // grad(F) dot_product grad(Phi) = 0
243  // where F is the extended speed function and Phi is
244  // the level set function.
245  //
246  // The extension value can approximated as a weighted
247  // sum of the values from nodes used in the calculation
248  // of the distance by the superclass.
249  //
250  // For more detail see Chapter 11 of
251  // "Level Set Methods and Fast Marching Methods", J.A. Sethian,
252  // Cambridge Press, Second edition, 1999.
253 
254  double solution = this->Superclass::UpdateValue( index, speed, output );
255 
256  typename Superclass::NodeType node;
257 
258  if ( solution < this->GetLargeValue() )
259  {
260  // update auxiliary values
261  for ( unsigned int k = 0; k < VAuxDimension; k++ )
262  {
263  double numer = 0.0;
264  double denom = 0.;
265  AuxValueType auxVal;
266 
267  for( unsigned int j = 0; j < SetDimension; j++ )
268  {
269  node = this->GetNodeUsedInCalculation(j);
270 
271  if( solution < node.GetValue() )
272  {
273  break;
274  }
275 
276  auxVal = this->GetAuxiliaryImage(k)->GetPixel( node.GetIndex() );
277  numer += auxVal * ( solution - node.GetValue() );
278  denom += solution - node.GetValue();
279 
280  }
281 
282  if( denom > 0 )
283  {
284  auxVal = static_cast<AuxValueType>( numer / denom );
285  }
286  else
287  {
288  auxVal = NumericTraits<AuxValueType>::Zero;
289  }
290 
291  this->GetAuxiliaryImage(k)->SetPixel( index, auxVal );
292  }
293  }
294 
295  return solution;
296 
297 }
298 
299 } // namespace itk
300 
301 
302 #endif

Generated at Sat Feb 2 2013 23:36:32 for Orfeo Toolbox with doxygen 1.8.1.1