#ifndef __fpa__Image__EndPointsFilter__hxx__ #define __fpa__Image__EndPointsFilter__hxx__ #include #include #include #include // ------------------------------------------------------------------------- template< class _TDistanceMap, class _TCostMap > const typename fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: TIndices& fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: GetBifurcations( ) const { return( this->m_Bifurcations ); } // ------------------------------------------------------------------------- template< class _TDistanceMap, class _TCostMap > const typename fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: TIndices& fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: GetEndPoints( ) const { return( this->m_EndPoints ); } // ------------------------------------------------------------------------- template< class _TDistanceMap, class _TCostMap > void fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: Compute( ) { typedef itk::ImageRegionConstIteratorWithIndex< _TDistanceMap > _TDistMapIt; typedef itk::ImageRegionConstIteratorWithIndex< _TCostMap > _TCostMapIt; typedef std::multimap< double, TIndex, std::greater< double > > _TQueue; typedef typename _TQueue::value_type _TQueueValue; typedef itk::Image< unsigned char, _TCostMap::ImageDimension > _TMarks; // Some values typename _TDistanceMap::RegionType region = this->m_DistanceMap->GetRequestedRegion( ); typename _TMarks::Pointer marks = _TMarks::New( ); marks->SetLargestPossibleRegion( this->m_DistanceMap->GetLargestPossibleRegion( ) ); marks->SetRequestedRegion( this->m_DistanceMap->GetRequestedRegion( ) ); marks->SetBufferedRegion( this->m_DistanceMap->GetBufferedRegion( ) ); marks->SetSpacing( this->m_DistanceMap->GetSpacing( ) ); marks->SetOrigin( this->m_DistanceMap->GetOrigin( ) ); marks->SetDirection( this->m_DistanceMap->GetDirection( ) ); marks->Allocate( ); marks->FillBuffer( 0 ); // Create queue _TQueue queue; _TDistMapIt dIt( this->m_DistanceMap, region ); _TCostMapIt cIt( this->m_CostMap, region ); dIt.GoToBegin( ); cIt.GoToBegin( ); for( ; !dIt.IsAtEnd( ) && !cIt.IsAtEnd( ); ++dIt, ++cIt ) { double d = double( dIt.Get( ) ); if( d > 0 ) { double v = double( cIt.Get( ) ) / ( d * d ); queue.insert( _TQueueValue( v, dIt.GetIndex( ) ) ); } // fi } // rof // BFS from maximum queue while( queue.size( ) > 0 ) { // Get node auto nIt = queue.begin( ); auto n = *nIt; queue.erase( nIt ); unsigned char m = marks->GetPixel( n.second ); if( ( m & 0x01 ) == 0x01 ) continue; // Mark it m |= 0x01; marks->SetPixel( n.second, m ); this->m_EndPoints.insert( n.second ); // Get path typename TMST::TPath::Pointer path; this->m_MST->GetPath( path, n.second ); for( unsigned long i = 0; i < path->GetSize( ); ++i ) { TIndex idx = path->GetVertex( path->GetSize( ) - 1 - i ); typename _TCostMap::PointType cnt; this->m_CostMap->TransformIndexToPhysicalPoint( idx, cnt ); double d = double( this->m_DistanceMap->GetPixel( idx ) ); d *= double( 2 ); // Mark sphere std::queue< TIndex > q; q.push( idx ); while( q.size( ) > 0 ) { TIndex v = q.front( ); q.pop( ); unsigned char m = marks->GetPixel( v ); if( ( m & 0x02 ) == 0x02 ) continue; m |= 0x03; marks->SetPixel( v, m ); for( unsigned int x = 0; x < _TCostMap::ImageDimension; ++x ) { for( int y = -1; y <= 1; y += 2 ) { TIndex w = v; w[ x ] += y; if( region.IsInside( w ) ) { typename _TCostMap::PointType p; this->m_CostMap->TransformIndexToPhysicalPoint( w, p ); if( cnt.EuclideanDistanceTo( p ) <= d ) q.push( w ); } // fi } // rof } // rof } // elihw } // rof } // elihw } // ------------------------------------------------------------------------- template< class _TDistanceMap, class _TCostMap > fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: EndPointsFilter( ) : Superclass( ) { } // ------------------------------------------------------------------------- template< class _TDistanceMap, class _TCostMap > fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: ~EndPointsFilter( ) { } #endif // __fpa__Image__EndPointsFilter__hxx__ // eof - $RCSfile$