-typedef fpa::VTK::Image3DObserver< TBaseDijkstra, vtkRenderWindow > TDijkstraObs;
-
-// -------------------------------------------------------------------------
-class TDijkstra
- : public TBaseDijkstra
-{
-public:
- typedef TDijkstra Self;
- typedef TBaseDijkstra Superclass;
- typedef itk::SmartPointer< Self > Pointer;
- typedef itk::SmartPointer< const Self > ConstPointer;
-
- typedef Superclass::TCost TCost;
- typedef Superclass::TVertex TVertex;
- 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;
- typedef Superclass::_TNode _TNode;
-
-public:
- itkNewMacro( Self );
- itkTypeMacro( TDijkstra, TBaseDijkstra );
-
-protected:
- TDijkstra( )
- : Superclass( )
- { }
- virtual ~TDijkstra( )
- { }
-
- virtual void _BeforeMainLoop( )
- {
- const TImage* img = this->GetInput( );
-
- // Correct seeds
- TImage::SizeType radius;
- radius.Fill( 3 );
- itk::ConstNeighborhoodIterator< TImage > it(
- radius, img, img->GetRequestedRegion( )
- );
- for( unsigned int s = 0; s < this->m_Seeds.size( ); ++s )
- {
- _TNode seed = this->m_Seeds[ s ];
- it.SetLocation( seed.Vertex );
-
- TImage::SizeType size = it.GetSize( );
- unsigned int nN = 1;
- for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
- nN *= size[ d ];
- TImage::PixelType max_value = img->GetPixel( seed.Vertex );
- for( unsigned int i = 0; i < nN; ++i )
- {
- if( it.GetPixel( i ) > max_value )
- {
- seed.Vertex = it.GetIndex( i );
- seed.Parent = seed.Vertex;
- max_value = it.GetPixel( i );
-
- } // fi
-
- } // rof
- this->m_Seeds[ s ] = seed;
-
- } // rof
-
- // End initialization
- this->Superclass::_BeforeMainLoop( );
- this->m_Candidates.clear( );
- }
-
- virtual void _AfterMainLoop( )
- {
- 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->SetBufferedRegion( input->GetBufferedRegion( ) );
- marks->SetOrigin( input->GetOrigin( ) );
- marks->SetSpacing( spacing );
- marks->SetDirection( input->GetDirection( ) );
- marks->Allocate( );
- 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( int backId = 0; backId < 100 && cIt != this->m_Candidates.rend( ); ++cIt )
- {
- // 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;
-
- bool start = true;
- do
- {
- 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.SetLocation( max_vertex );
- nN = 1;
- for( unsigned int d = 0; d < TImage::ImageDimension; ++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;
- }
-
- /*
- TImage::SizeType radius;
- 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 in current path
- this->InvokeEvent( TBacktrackingEvent( max_vertex, backId ) );
- max_vertex = this->_Parent( max_vertex );
-
- } while( max_vertex != this->_Parent( max_vertex ) );
-
- } // rof
- /*
- else
- marks->SetPixel( v, _TMark( 1 ) );
- } // rof
- */
-
- /*
- itk::ImageFileWriter< _TMarkImage >::Pointer w =
- itk::ImageFileWriter< _TMarkImage >::New( );
- 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 )
- {
- TCost nc = this->_Cost( nn.Vertex, n.Vertex );
- if( TCost( 0 ) < nc )
- {
- nn.Cost = n.Cost + ( TCost( 1 ) / nc );
- nn.Result = nn.Cost;
- return( true );
- }
- else
- return( false );
- }
-
- virtual bool _UpdateResult( _TNode& n )
- {
- bool ret = this->Superclass::_UpdateResult( n );
- if( ret )
- {
- TCost nc = this->_Cost( n.Vertex, n.Parent );
- if( TCost( 0 ) < nc )
- {
- TCost cc = n.Cost / nc;
- this->m_Candidates.insert( _TCandidate( cc, n.Vertex ) );
- /* TODO: debug code
- this->GetOutput( )->SetPixel( n.Vertex, cc );
- */
- } // fi
-
- } // fi
- return( ret );
- }
-
-private:
- TDijkstra( const Self& other );
- Self& operator=( const Self& other );
-
-protected:
- _TCandidates m_Candidates;
-public:
- vtkSmartPointer< vtkPolyData > m_Axes;
-};