typedef Superclass::InputImageType TImage;
typedef std::deque< TVertex > TVertices;
+ typedef Superclass::TEndEvent TEndEvent;
+ typedef Superclass::TBacktrackingEvent TBacktrackingEvent;
+
protected:
typedef std::pair< TCost, TVertex > _TCandidate;
typedef std::multimap< TCost, TVertex > _TCandidates;
virtual void _AfterMainLoop( )
{
- typedef itk::Image< unsigned char, TImage::ImageDimension > _TMarkImage;
+ typedef unsigned char _TMark;
+ typedef itk::Image< _TMark, TImage::ImageDimension > _TMarkImage;
this->Superclass::_AfterMainLoop( );
if( this->m_Candidates.size( ) == 0 )
return;
+ this->InvokeEvent( TEndEvent( ) );
+
const TImage* input = this->GetInput( );
TImage::SpacingType spacing = input->GetSpacing( );
+ // Prepare an object to hold marks
_TMarkImage::Pointer marks = _TMarkImage::New( );
marks->SetLargestPossibleRegion( input->GetLargestPossibleRegion( ) );
marks->SetRequestedRegion( input->GetRequestedRegion( ) );
marks->SetSpacing( spacing );
marks->SetDirection( input->GetDirection( ) );
marks->Allocate( );
- marks->FillBuffer( 0 );
-
- this->m_Axes = vtkSmartPointer< vtkPolyData >::New( );
- vtkSmartPointer< vtkPoints > points =
- vtkSmartPointer< vtkPoints >::New( );
- vtkSmartPointer< vtkCellArray > lines =
- vtkSmartPointer< vtkCellArray >::New( );
+ marks->FillBuffer( _TMark( 0 ) );
+ // Iterate over the candidates, starting from the candidates that
+ // are near thin branches
_TCandidates::const_reverse_iterator cIt =
this->m_Candidates.rbegin( );
-
- for( unsigned long leo = 0; leo < 50 && cIt != this->m_Candidates.rend( ); ++cIt )
+ for( int backId = 0; backId < 100 && cIt != this->m_Candidates.rend( ); ++cIt )
{
- TVertex vIt = cIt->second;
- if( marks->GetPixel( vIt ) != 0 )
+ // If pixel hasn't been visited, continue
+ TVertex v = cIt->second;
+ if( marks->GetPixel( v ) != _TMark( 0 ) )
+ continue;
+
+ // Compute nearest start candidate
+ TImage::SizeType radius;
+ radius.Fill( 3 );
+ itk::ConstNeighborhoodIterator< TImage > iIt(
+ radius, input, input->GetRequestedRegion( )
+ );
+ iIt.SetLocation( v );
+ unsigned int nN = 1;
+ for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+ nN *= iIt.GetSize( )[ d ];
+ TVertex max_vertex = iIt.GetIndex( 0 );
+ TImage::PixelType max_value = iIt.GetPixel( 0 );
+ for( unsigned int i = 1; i < nN; ++i )
+ {
+ TImage::PixelType value = iIt.GetPixel( i );
+ if( value > max_value )
+ {
+ max_value = value;
+ max_vertex = iIt.GetIndex( i );
+
+ } // fi
+
+ } // rof
+
+ if( marks->GetPixel( max_vertex ) != _TMark( 0 ) )
continue;
+ backId++;
+ std::cout << "Leaf: " << backId << " " << max_value << " " << max_vertex << std::endl;
- leo++;
- std::cout << "Leaf: " << leo << " " << cIt->first << " " << vIt << std::endl;
bool start = true;
do
{
- double dist = double( input->GetPixel( vIt ) );
- TImage::SizeType radius;
+ double dist = double( 1.5 ) * std::sqrt( double( input->GetPixel( max_vertex ) ) );
for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
radius[ d ] =
( unsigned long )( dist / spacing[ d ] ) + 1;
itk::NeighborhoodIterator< _TMarkImage > mIt(
radius, marks, marks->GetRequestedRegion( )
);
- mIt.GoToBegin( );
- mIt.SetLocation( vIt );
-
- TImage::SizeType size = mIt.GetSize( );
- unsigned int nN = 1;
+ mIt.SetLocation( max_vertex );
+ nN = 1;
for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
- nN *= size[ d ];
+ nN *= mIt.GetSize( )[ d ];
for( unsigned int i = 0; i < nN; ++i )
if( marks->GetRequestedRegion( ).IsInside( mIt.GetIndex( i ) ) )
+ {
mIt.SetPixel( i, ( start )? 255: 100 );
+ start = false;
+ }
- start = false;
+ /*
+ TImage::SizeType radius;
+ mIt.GoToBegin( );
+ mIt.SetLocation( vIt );
- // Next vertex
- vIt = this->_Parent( vIt );
-
- } while( vIt != this->_Parent( vIt ) );
+ TImage::SizeType size = mIt.GetSize( );
+ unsigned int nN = 1;
+ for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+ nN *= size[ d ];
+ for( unsigned int i = 0; i < nN; ++i )
+ if( marks->GetRequestedRegion( ).IsInside( mIt.GetIndex( i ) ) )
+ mIt.SetPixel( i, ( start )? 255: 100 );
- // Last vertex
- // std::cout << vIt << " " << this->GetSeed( 0 ) << std::endl;
+ start = false;
+ */
+ // Next vertex in current path
+ this->InvokeEvent( TBacktrackingEvent( max_vertex, backId ) );
+ max_vertex = this->_Parent( max_vertex );
- /* TODO
- TVertices pS;
- TVertex parent = this->_Parent( vIt );
- while( parent != vIt )
- {
- pS.push_front( vIt );
- vIt = parent;
- parent = this->_Parent( vIt );
-
- TImage::PointType pnt;
- this->GetInput( )->TransformIndexToPhysicalPoint( vIt, pnt );
- points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
- if( points->GetNumberOfPoints( ) > 1 )
- {
- lines->InsertNextCell( 2 );
- lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
- lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
-
- } // fi
-
- } // elihw
- pS.push_front( vIt );
- TImage::PointType pnt;
- this->GetInput( )->TransformIndexToPhysicalPoint( vIt, pnt );
- points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
- if( points->GetNumberOfPoints( ) > 1 )
- {
- lines->InsertNextCell( 2 );
- lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
- lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
-
- } // fi
-
- this->m_Axes->SetPoints( points );
- this->m_Axes->SetLines( lines );
- */
+ } while( max_vertex != this->_Parent( max_vertex ) );
} // rof
+ /*
+ else
+ marks->SetPixel( v, _TMark( 1 ) );
+ } // rof
+ */
- itk::ImageFileWriter< _TMarkImage >::Pointer w =
+ /*
+ itk::ImageFileWriter< _TMarkImage >::Pointer w =
itk::ImageFileWriter< _TMarkImage >::New( );
- w->SetInput( marks );
- w->SetFileName( "marks.mhd" );
- w->Update( );
+ w->SetInput( marks );
+ w->SetFileName( "marks.mhd" );
+ w->Update( );
+
+
+ this->m_Axes = vtkSmartPointer< vtkPolyData >::New( );
+ vtkSmartPointer< vtkPoints > points =
+ vtkSmartPointer< vtkPoints >::New( );
+ vtkSmartPointer< vtkCellArray > lines =
+ vtkSmartPointer< vtkCellArray >::New( );
+
+ {
+
+ backId++;
+ std::cout << "Leaf: " << backId << " " << cIt->first << " " << vIt << std::endl;
+ bool start = true;
+ do
+ {
+ double dist = double( input->GetPixel( vIt ) );
+ TImage::SizeType radius;
+ for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+ radius[ d ] =
+ ( unsigned long )( dist / spacing[ d ] ) + 1;
+ itk::NeighborhoodIterator< _TMarkImage > mIt(
+ radius, marks, marks->GetRequestedRegion( )
+ );
+ mIt.GoToBegin( );
+ mIt.SetLocation( vIt );
+ TImage::SizeType size = mIt.GetSize( );
+ unsigned int nN = 1;
+ for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+ nN *= size[ d ];
+ for( unsigned int i = 0; i < nN; ++i )
+ if( marks->GetRequestedRegion( ).IsInside( mIt.GetIndex( i ) ) )
+ mIt.SetPixel( i, ( start )? 255: 100 );
+
+ start = false;
+
+ // Next vertex
+ vIt = this->_Parent( vIt );
+
+ } while( vIt != this->_Parent( vIt ) );
+
+ // Last vertex
+ // std::cout << vIt << " " << this->GetSeed( 0 ) << std::endl;
+ */
+ /* TODO
+ TVertices pS;
+ TVertex parent = this->_Parent( vIt );
+ while( parent != vIt )
+ {
+ pS.push_front( vIt );
+ vIt = parent;
+ parent = this->_Parent( vIt );
+
+ TImage::PointType pnt;
+ this->GetInput( )->TransformIndexToPhysicalPoint( vIt, pnt );
+ points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+ if( points->GetNumberOfPoints( ) > 1 )
+ {
+ lines->InsertNextCell( 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
+
+ } // fi
+
+ } // elihw
+ pS.push_front( vIt );
+ TImage::PointType pnt;
+ this->GetInput( )->TransformIndexToPhysicalPoint( vIt, pnt );
+ points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+ if( points->GetNumberOfPoints( ) > 1 )
+ {
+ lines->InsertNextCell( 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
+
+ } // fi
+
+ this->m_Axes->SetPoints( points );
+ this->m_Axes->SetLines( lines );
+ */
+
+ /*
+ } // rof
+ */
}
virtual bool _UpdateNeigh( _TNode& nn, const _TNode& n )
if( ret )
{
TCost nc = this->_Cost( n.Vertex, n.Parent );
- TCost nc2 = nc * nc * nc * nc;
- if( TCost( 0 ) < nc2 )
+ if( TCost( 0 ) < nc )
{
- n.Result = n.Cost / nc2;
- this->GetOutput( )->SetPixel( n.Vertex, n.Result );
- this->m_Candidates.insert( _TCandidate( n.Result, n.Vertex ) );
-
+ TCost cc = n.Cost / nc;
+ this->m_Candidates.insert( _TCandidate( cc, n.Vertex ) );
+ /* TODO: debug code
+ this->GetOutput( )->SetPixel( n.Vertex, cc );
+ */
} // fi
} // fi
{
// Configure observer
TDijkstraObs::Pointer obs = TDijkstraObs::New( );
- obs->SetImage( input_image, view.GetWindow( ) );
+ obs->SetRenderWindow( view.GetWindow( ) );
paths->AddObserver( itk::AnyEvent( ), obs );
paths->ThrowEventsOn( );
}