17 #ifndef __itkLevelSetNeighborhoodExtractor_txx
18 #define __itkLevelSetNeighborhoodExtractor_txx
23 #include "itkNumericTraits.h"
24 #include "vnl/vnl_math.h"
34 template <
class TLevelSet>
38 m_LevelSetValue = 0.0;
43 m_LargeValue = NumericTraits<PixelType>::max();
44 m_NodesUsed.resize( SetDimension );
46 m_NarrowBanding =
false;
47 m_NarrowBandwidth = 12.0;
48 m_InputNarrowBand = 0;
49 for (
unsigned int i=0; i < SetDimension; ++i)
58 template <
class TLevelSet>
63 Superclass::PrintSelf(os, indent);
64 os << indent <<
"Input level set: " << m_InputLevelSet.GetPointer();
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;
76 template <
class TLevelSet>
82 if( m_InputNarrowBand != ptr )
84 m_InputNarrowBand = ptr;
93 template <
class TLevelSet>
105 template <
class TLevelSet>
111 m_InsidePoints = NodeContainer::New();
112 m_OutsidePoints = NodeContainer::New();
114 typename TLevelSet::SizeType size =
115 m_InputLevelSet->GetBufferedRegion().GetSize();
117 for(
unsigned int j = 0; j < SetDimension; j++ )
119 m_ImageSize[j] = (
signed long) size[j];
127 template <
class TLevelSet>
132 if( !m_InputLevelSet )
134 itkExceptionMacro( <<
"Input level set is NULL" );
140 if( m_NarrowBanding )
142 this->GenerateDataNarrowBand();
146 this->GenerateDataFull();
149 itkDebugMacro(<<
"No. inside points: " << m_InsidePoints->Size());
150 itkDebugMacro(<<
"No. outside points: " << m_OutsidePoints->Size());
158 template <
class TLevelSet>
166 InputConstIterator inIt ( m_InputLevelSet,
167 m_InputLevelSet->GetBufferedRegion() );
171 unsigned long totalPixels =
172 m_InputLevelSet->GetBufferedRegion().GetNumberOfPixels();
173 unsigned long updateVisits = totalPixels / 10;
174 if ( updateVisits < 1) { updateVisits = 1; }
178 for ( i = 0; !inIt.IsAtEnd(); ++inIt, ++i )
181 if ( !(i % updateVisits) )
183 this->UpdateProgress( (
float) i/ (
float) totalPixels );
186 inputIndex = inIt.GetIndex();
187 this->CalculateDistance( inputIndex );
195 template <
class TLevelSet>
200 if ( !m_InputNarrowBand )
202 itkExceptionMacro( <<
"InputNarrowBand has not been set" );
208 pointsIter = m_InputNarrowBand->Begin();
209 pointsEnd = m_InputNarrowBand->End();
211 double maxValue = m_NarrowBandwidth / 2.0;
214 unsigned long totalPixels = m_InputNarrowBand->Size();
215 unsigned long updateVisits = totalPixels / 10;
216 if ( updateVisits < 1) { updateVisits = 1; }
220 for ( i = 0; pointsIter != pointsEnd; ++pointsIter, ++i )
224 if ( !(i % updateVisits) )
226 this->UpdateProgress( (
float) i/ (
float) totalPixels );
229 node = pointsIter.
Value();
230 if ( vnl_math_abs( node.
GetValue() ) <= maxValue )
232 this->CalculateDistance( node.
GetIndex() );
241 template <
class TLevelSet>
248 m_LastPointIsInside =
false;
250 typename LevelSetImageType::PixelType centerValue;
253 inputPixel = m_InputLevelSet->GetPixel( index );
254 centerValue = (double) inputPixel;
255 centerValue -= m_LevelSetValue;
260 if( centerValue == 0.0 )
263 m_InsidePoints->InsertElement( m_InsidePoints->Size(), centerNode );
264 m_LastPointIsInside =
true;
268 bool inside = ( centerValue <= 0.0 );
271 typename LevelSetImageType::PixelType neighValue;
277 for(
unsigned int j = 0; j < SetDimension; j++ )
281 for(
int s = -1; s < 2; s = s + 2 )
283 neighIndex[j] = index[j] + s;
285 if( neighIndex[j] > m_ImageSize[j] - 1 ||
291 inputPixel = m_InputLevelSet->GetPixel( neighIndex );
292 neighValue = inputPixel;
293 neighValue -= m_LevelSetValue;
295 if( ( neighValue > 0 && inside ) ||
296 ( neighValue < 0 && !inside ) )
298 distance = centerValue / ( centerValue - neighValue );
300 if( neighNode.
GetValue() > distance )
310 m_NodesUsed[j] = neighNode;
313 neighIndex[j] = index[j];
318 std::sort( m_NodesUsed.begin(), m_NodesUsed.end() );
323 for(
unsigned int j = 0; j < SetDimension; j++ )
325 neighNode = m_NodesUsed[j];
327 if( neighNode.
GetValue() >= m_LargeValue )
332 distance += 1.0 / vnl_math_sqr( (
double)neighNode.
GetValue() );
335 if( distance == 0.0 )
340 distance = vcl_sqrt( 1.0 / distance );
345 m_InsidePoints->InsertElement( m_InsidePoints->Size(), centerNode );
346 m_LastPointIsInside =
true;
350 m_OutsidePoints->InsertElement( m_OutsidePoints->Size(), centerNode );
351 m_LastPointIsInside =
false;