Orfeo Toolbox  3.16
itkLevelSetNeighborhoodExtractor.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkLevelSetNeighborhoodExtractor.txx,v $
5  Language: C++
6  Date: $Date: 2009-01-24 20:02:58 $
7  Version: $Revision: 1.31 $
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 __itkLevelSetNeighborhoodExtractor_txx
18 #define __itkLevelSetNeighborhoodExtractor_txx
19 
22 #include "itkImageRegionIterator.h"
23 #include "itkNumericTraits.h"
24 #include "vnl/vnl_math.h"
25 
26 #include <algorithm>
27 
28 namespace itk
29 {
30 
34 template <class TLevelSet>
37 {
38  m_LevelSetValue = 0.0;
39  m_InsidePoints = 0;
40  m_OutsidePoints = 0;
41  m_InputLevelSet = 0;
42 
43  m_LargeValue = NumericTraits<PixelType>::max();
44  m_NodesUsed.resize( SetDimension );
45 
46  m_NarrowBanding = false;
47  m_NarrowBandwidth = 12.0;
48  m_InputNarrowBand = 0;
49  for (unsigned int i=0; i < SetDimension; ++i)
50  {
51  m_ImageSize[i] = 0;
52  }
53 }
54 
55 /*
56  *
57  */
58 template <class TLevelSet>
59 void
61 ::PrintSelf(std::ostream& os, Indent indent) const
62 {
63  Superclass::PrintSelf(os, indent);
64  os << indent << "Input level set: " << m_InputLevelSet.GetPointer();
65  os << std::endl;
66  os << indent << "Level set value: " << m_LevelSetValue << std::endl;
67  os << indent << "Narrow bandwidth: " << m_NarrowBandwidth << std::endl;
68  os << indent << "Narrowbanding: " << m_NarrowBanding << std::endl;
69  os << indent << "Input narrow band: ";
70  os << m_InputNarrowBand.GetPointer() << std::endl;
71 }
72 
73 /*
74  *
75  */
76 template <class TLevelSet>
77 void
80  NodeContainer * ptr )
81 {
82  if( m_InputNarrowBand != ptr )
83  {
84  m_InputNarrowBand = ptr;
85  this->Modified();
86  }
87 }
88 
89 
93 template <class TLevelSet>
94 void
97 {
98  this->GenerateData();
99 }
100 
101 
105 template <class TLevelSet>
106 void
109 {
110  // create new emtpy points containers
111  m_InsidePoints = NodeContainer::New();
112  m_OutsidePoints = NodeContainer::New();
113 
114  typename TLevelSet::SizeType size =
115  m_InputLevelSet->GetBufferedRegion().GetSize();
116 
117  for( unsigned int j = 0; j < SetDimension; j++ )
118  {
119  m_ImageSize[j] = (signed long) size[j];
120  }
121 
122 }
123 
124 /*
125  *
126  */
127 template <class TLevelSet>
128 void
131 {
132  if( !m_InputLevelSet )
133  {
134  itkExceptionMacro( << "Input level set is NULL" );
135  }
136 
137  this->Initialize();
138 
139 
140  if( m_NarrowBanding )
141  {
142  this->GenerateDataNarrowBand();
143  }
144  else
145  {
146  this->GenerateDataFull();
147  }
148 
149  itkDebugMacro(<< "No. inside points: " << m_InsidePoints->Size());
150  itkDebugMacro(<< "No. outside points: " << m_OutsidePoints->Size());
151 
152 }
153 
154 
155 /*
156  *
157  */
158 template <class TLevelSet>
159 void
162 {
163 
164  typedef ImageRegionConstIterator<LevelSetImageType> InputConstIterator;
165 
166  InputConstIterator inIt ( m_InputLevelSet,
167  m_InputLevelSet->GetBufferedRegion() );
168 
169  IndexType inputIndex;
170 
171  unsigned long totalPixels =
172  m_InputLevelSet->GetBufferedRegion().GetNumberOfPixels();
173  unsigned long updateVisits = totalPixels / 10;
174  if ( updateVisits < 1) { updateVisits = 1; }
175 
176 
177  unsigned long i;
178  for ( i = 0; !inIt.IsAtEnd(); ++inIt, ++i )
179  {
180  // update progress
181  if ( !(i % updateVisits) )
182  {
183  this->UpdateProgress( (float) i/ (float) totalPixels );
184  }
185 
186  inputIndex = inIt.GetIndex();
187  this->CalculateDistance( inputIndex );
188  }
189 
190 }
191 
195 template <class TLevelSet>
196 void
199 {
200  if ( !m_InputNarrowBand )
201  {
202  itkExceptionMacro( << "InputNarrowBand has not been set" );
203  }
204 
205  typename NodeContainer::ConstIterator pointsIter;
206  typename NodeContainer::ConstIterator pointsEnd;
207 
208  pointsIter = m_InputNarrowBand->Begin();
209  pointsEnd = m_InputNarrowBand->End();
210  NodeType node;
211  double maxValue = m_NarrowBandwidth / 2.0;
212 
213 
214  unsigned long totalPixels = m_InputNarrowBand->Size();
215  unsigned long updateVisits = totalPixels / 10;
216  if ( updateVisits < 1) { updateVisits = 1; }
217 
218 
219  unsigned int i;
220  for ( i = 0; pointsIter != pointsEnd; ++pointsIter, ++i )
221  {
222 
223  // update progress
224  if ( !(i % updateVisits) )
225  {
226  this->UpdateProgress( (float) i/ (float) totalPixels );
227  }
228 
229  node = pointsIter.Value();
230  if ( vnl_math_abs( node.GetValue() ) <= maxValue )
231  {
232  this->CalculateDistance( node.GetIndex() );
233  }
234  }
235 
236 }
237 
241 template <class TLevelSet>
242 double
245  IndexType& index)
246 {
247 
248  m_LastPointIsInside = false;
249 
250  typename LevelSetImageType::PixelType centerValue;
251  PixelType inputPixel;
252 
253  inputPixel = m_InputLevelSet->GetPixel( index );
254  centerValue = (double) inputPixel;
255  centerValue -= m_LevelSetValue;
256 
257  NodeType centerNode;
258  centerNode.SetIndex( index );
259 
260  if( centerValue == 0.0 )
261  {
262  centerNode.SetValue( 0.0 );
263  m_InsidePoints->InsertElement( m_InsidePoints->Size(), centerNode );
264  m_LastPointIsInside = true;
265  return 0.0;
266  }
267 
268  bool inside = ( centerValue <= 0.0 );
269 
270  IndexType neighIndex = index;
271  typename LevelSetImageType::PixelType neighValue;
272  NodeType neighNode;
273  double distance;
274 
275  // In each dimension, find the distance to the zero set
276  // by linear interpolating along the grid line.
277  for( unsigned int j = 0; j < SetDimension; j++ )
278  {
279  neighNode.SetValue( m_LargeValue );
280 
281  for( int s = -1; s < 2; s = s + 2 )
282  {
283  neighIndex[j] = index[j] + s;
284 
285  if( neighIndex[j] > m_ImageSize[j] - 1 ||
286  neighIndex[j] < 0 )
287  {
288  continue;
289  }
290 
291  inputPixel = m_InputLevelSet->GetPixel( neighIndex );
292  neighValue = inputPixel;
293  neighValue -= m_LevelSetValue;
294 
295  if( ( neighValue > 0 && inside ) ||
296  ( neighValue < 0 && !inside ) )
297  {
298  distance = centerValue / ( centerValue - neighValue );
299 
300  if( neighNode.GetValue() > distance )
301  {
302  neighNode.SetValue( distance );
303  neighNode.SetIndex( neighIndex );
304  }
305  }
306 
307  } // end one dim loop
308 
309  // put the minimum distance neighbor onto the heap
310  m_NodesUsed[j] = neighNode;
311 
312  // reset neighIndex
313  neighIndex[j] = index[j];
314 
315  } // end dimension loop
316 
317  // sort the neighbors according to distance
318  std::sort( m_NodesUsed.begin(), m_NodesUsed.end() );
319 
320  // The final distance is given by the minimum distance to the plane
321  // crossing formed by the zero set crossing points.
322  distance = 0.0;
323  for( unsigned int j = 0; j < SetDimension; j++ )
324  {
325  neighNode = m_NodesUsed[j];
326 
327  if( neighNode.GetValue() >= m_LargeValue )
328  {
329  break;
330  }
331 
332  distance += 1.0 / vnl_math_sqr( (double)neighNode.GetValue() );
333  }
334 
335  if( distance == 0.0 )
336  {
337  return m_LargeValue;
338  }
339 
340  distance = vcl_sqrt( 1.0 / distance );
341  centerNode.SetValue( distance );
342 
343  if( inside )
344  {
345  m_InsidePoints->InsertElement( m_InsidePoints->Size(), centerNode );
346  m_LastPointIsInside = true;
347  }
348  else
349  {
350  m_OutsidePoints->InsertElement( m_OutsidePoints->Size(), centerNode );
351  m_LastPointIsInside = false;
352  }
353 
354  return distance;
355 
356 }
357 
358 } // namespace itk
359 
360 #endif

Generated at Sat Feb 2 2013 23:51:03 for Orfeo Toolbox with doxygen 1.8.1.1