X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2Ffpa%2FImage%2FAlgorithm.hxx;h=a5b1f8548e5e4dd481a93eb1fbb3e3f6561d4ff4;hb=781520794cb7530b882effe7222dde78f1039eb3;hp=7800a549576e7f378b1454ed39013d5996c72cff;hpb=9622bd5b833a8845881003228207e0caca59b081;p=FrontAlgorithms.git diff --git a/lib/fpa/Image/Algorithm.hxx b/lib/fpa/Image/Algorithm.hxx index 7800a54..a5b1f85 100644 --- a/lib/fpa/Image/Algorithm.hxx +++ b/lib/fpa/Image/Algorithm.hxx @@ -2,67 +2,102 @@ #define __FPA__IMAGE__ALGORITHM__HXX__ #include -#include #include // ------------------------------------------------------------------------- -template< class I, class A > -fpa::Image::Algorithm< I, A >:: +template< class I, class O, class A > +typename fpa::Image::Algorithm< I, O, A >:: +TMinimumSpanningTree* fpa::Image::Algorithm< I, O, A >:: +GetMinimumSpanningTree( ) +{ + return( + dynamic_cast< TMinimumSpanningTree* >( + this->itk::ProcessObject::GetOutput( 1 ) + ) + ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class A > +const typename fpa::Image::Algorithm< I, O, A >:: +TMinimumSpanningTree* fpa::Image::Algorithm< I, O, A >:: +GetMinimumSpanningTree( ) const +{ + return( + dynamic_cast< const TMinimumSpanningTree* >( + this->itk::ProcessObject::GetOutput( 1 ) + ) + ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class A > +void fpa::Image::Algorithm< I, O, A >:: +GraftMinimumSpanningTree( itk::DataObject* obj ) +{ + TMinimumSpanningTree* mst = dynamic_cast< TMinimumSpanningTree* >( obj ); + if( mst != NULL ) + this->GraftNthOutput( 1, mst ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class A > +fpa::Image::Algorithm< I, O, A >:: Algorithm( ) : Superclass( ), m_NeighborhoodOrder( 1 ) { + this->itk::ProcessObject::SetNumberOfRequiredOutputs( 2 ); + this->itk::ProcessObject::SetNthOutput( 0, O::New( ) ); + this->itk::ProcessObject::SetNthOutput( 1, TMinimumSpanningTree::New( ) ); } // ------------------------------------------------------------------------- -template< class I, class A > -fpa::Image::Algorithm< I, A >:: +template< class I, class O, class A > +fpa::Image::Algorithm< I, O, A >:: ~Algorithm( ) { } // ------------------------------------------------------------------------- -template< class I, class A > -bool fpa::Image::Algorithm< I, A >:: -_UpdateResult( _TNode& n ) +template< class I, class O, class A > +void fpa::Image::Algorithm< I, O, A >:: +_BeforeGenerateData( ) { - bool ret = this->Superclass::_UpdateResult( n ); - this->GetOutput( )->SetPixel( n.Vertex, n.Result ); - return( ret ); + this->Superclass::_BeforeGenerateData( ); + this->AllocateOutputs( ); } // ------------------------------------------------------------------------- -template< class I, class A > -unsigned long fpa::Image::Algorithm< I, A >:: -_NumberOfVertices( ) const +template< class I, class O, class A > +void fpa::Image::Algorithm< I, O, A >:: +_AfterGenerateData( ) { - return( - this->GetInput( )->GetLargestPossibleRegion( ).GetNumberOfPixels( ) - ); + this->Superclass::_AfterGenerateData( ); + this->GetMinimumSpanningTree( )->SetCollisions( this->m_Collisions ); } // ------------------------------------------------------------------------- -template< class I, class A > -typename fpa::Image::Algorithm< I, A >:: -TVertexValue fpa::Image::Algorithm< I, A >:: -_Value( const TVertex& v ) const +template< class I, class O, class A > +unsigned long fpa::Image::Algorithm< I, O, A >:: +_NumberOfVertices( ) const { - return( this->GetInput( )->GetPixel( v ) ); + return( this->GetInput( )->GetRequestedRegion( ).GetNumberOfPixels( ) ); } // ------------------------------------------------------------------------- -template< class I, class A > -typename fpa::Image::Algorithm< I, A >:: -TResult fpa::Image::Algorithm< I, A >:: -_Result( const TVertex& v ) const +template< class I, class O, class A > +const typename fpa::Image::Algorithm< I, O, A >:: +TValue& fpa::Image::Algorithm< I, O, A >:: +_VertexValue( const TVertex& v ) const { - return( this->GetOutput( )->GetPixel( v ) ); + return( this->GetInput( )->GetPixel( v ) ); } // ------------------------------------------------------------------------- -template< class I, class A > -double fpa::Image::Algorithm< I, A >:: -_Norm( const TVertex& a, const TVertex& b ) const +template< class I, class O, class A > +double fpa::Image::Algorithm< I, O, A >:: +_Distance( const TVertex& a, const TVertex& b ) const { typename I::PointType pa, pb; this->GetInput( )->TransformIndexToPhysicalPoint( a, pa ); @@ -71,58 +106,37 @@ _Norm( const TVertex& a, const TVertex& b ) const } // ------------------------------------------------------------------------- -template< class I, class A > -bool fpa::Image::Algorithm< I, A >:: -_Edge( const TVertex& a, const TVertex& b ) const +template< class I, class O, class A > +bool fpa::Image::Algorithm< I, O, A >:: +_HasEdge( const TVertex& a, const TVertex& b ) const { unsigned long dist = 0; for( unsigned int d = 0; d < I::ImageDimension; d++ ) dist += std::abs( long( a[ d ] ) - long( b[ d ] ) ); if( this->m_NeighborhoodOrder == 1 ) - return( dist == 0 || dist == 1 ); - else - return( dist == 0 || dist == 1 || dist == 2 ); -} - -// ------------------------------------------------------------------------- -template< class I, class A > -typename fpa::Image::Algorithm< I, A >:: -TCost fpa::Image::Algorithm< I, A >:: -_Cost( const TVertex& a, const TVertex& b ) const -{ - static const TCost INF_COST = std::numeric_limits< TCost >::max( ); - if( this->_Edge( a, b ) ) - { - TCost c = TCost( this->GetInput( )->GetPixel( b ) ); - if( this->m_CostConversion.IsNotNull( ) ) - return( this->m_CostConversion->Evaluate( c ) ); - else - return( c ); - } + return( dist <= 1 ); else - return( INF_COST ); + return( dist <= I::ImageDimension ); } // ------------------------------------------------------------------------- -template< class I, class A > -void fpa::Image::Algorithm< I, A >:: -_Neighs( const _TNode& n, _TNodes& N ) const +template< class I, class O, class A > +void fpa::Image::Algorithm< I, O, A >:: +_Neighborhood( _TVertices& neighborhood, const TVertex& v ) const { typename I::RegionType reg = this->GetInput( )->GetRequestedRegion( ); - N.clear( ); + neighborhood.clear( ); if( this->m_NeighborhoodOrder == 1 ) { for( unsigned int d = 0; d < I::ImageDimension; d++ ) { for( int i = -1; i <= 1; i += 2 ) { - TVertex v = n.Vertex; - v[ d ] += i; - if( reg.IsInside( v ) ) - N.push_back( _TNode( v, n.FrontId ) ); - else - N.push_back( n ); + TVertex n = v; + n[ d ] += i; + if( reg.IsInside( n ) ) + neighborhood.push_back( n ); } // rof @@ -135,15 +149,14 @@ _Neighs( const _TNode& n, _TNodes& N ) const nSize.Fill( 1 ); TNeighIt nIt( nSize, this->GetInput( ), reg ); - nIt.SetLocation( n.Vertex ); + nIt.SetLocation( v ); for( unsigned int i = 0; i < nIt.Size( ); i++ ) { - TVertex idxN = nIt.GetIndex( i ); - if( idxN == n.Vertex ) - continue; - if( !reg.IsInside( idxN ) ) + TVertex n = nIt.GetIndex( i ); + if( n == v ) continue; - N.push_back( _TNode( idxN, n.FrontId ) ); + if( reg.IsInside( n ) ) + neighborhood.push_back( n ); } // rof @@ -151,28 +164,54 @@ _Neighs( const _TNode& n, _TNodes& N ) const } // ------------------------------------------------------------------------- -template< class I, class A > -void fpa::Image::Algorithm< I, A >:: -_NeighsInDim( const _TNode& n, const unsigned int& d, _TNodes& N ) +template< class I, class O, class A > +void fpa::Image::Algorithm< I, O, A >:: +_InitResults( ) { - typename I::RegionType reg = this->GetInput( )->GetRequestedRegion( ); +} - N.clear( ); - for( int i = -1; i <= 1; i += 2 ) - { - TVertex v = n.Vertex; - v[ d ] += i; - if( reg.IsInside( v ) ) - N.push_back( _TNode( v, n.FrontId ) ); +// ------------------------------------------------------------------------- +template< class I, class O, class A > +const typename fpa::Image::Algorithm< I, O, A >:: +TResult& fpa::Image::Algorithm< I, O, A >:: +_Result( const TVertex& v ) const +{ + return( this->GetOutput( )->GetPixel( v ) ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class A > +void fpa::Image::Algorithm< I, O, A >:: +_SetResult( const TVertex& v, const TResult& r ) +{ + this->GetOutput( )->SetPixel( v, r ); +} - } // rof +// ------------------------------------------------------------------------- +template< class I, class O, class A > +const typename fpa::Image::Algorithm< I, O, A >:: +_TNode& fpa::Image::Algorithm< I, O, A >:: +_Node( const TVertex& v ) const +{ + return( this->GetMinimumSpanningTree( )->GetPixel( v ) ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class A > +void fpa::Image::Algorithm< I, O, A >:: +_InitMarks( ) +{ + _TNode far_node; + far_node.Label = Self::FarLabel; + this->GetMinimumSpanningTree( )->FillBuffer( far_node ); } // ------------------------------------------------------------------------- -template< class I, class A > -void fpa::Image::Algorithm< I, A >:: -_InitializeResults( ) +template< class I, class O, class A > +void fpa::Image::Algorithm< I, O, A >:: +_Mark( const _TNode& node ) { + this->GetMinimumSpanningTree( )->SetPixel( node.Vertex, node ); } #endif // __FPA__IMAGE__ALGORITHM__HXX__