// ------------------------------------------------------------------------- // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) // ------------------------------------------------------------------------- #ifndef __cpExtensions__Algorithms__MultiScaleGaussianImageFilter__hxx__ #define __cpExtensions__Algorithms__MultiScaleGaussianImageFilter__hxx__ #include #include #include #include #include #include #include #include // ------------------------------------------------------------------------- template< class I, class O > cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >::_Greater:: _Greater( ) { } // ------------------------------------------------------------------------- template< class I, class O > cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >::_Greater:: ~_Greater( ) { } // ------------------------------------------------------------------------- template< class I, class O > bool cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >::_Greater:: operator!=( const _Greater& b ) const { return( false ); } // ------------------------------------------------------------------------- template< class I, class O > bool cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >::_Greater:: operator==( const _Greater& b ) const { return !( *this != b ); } // ------------------------------------------------------------------------- template< class I, class O > typename cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >::_Greater:: _T cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >::_Greater:: operator()( const _T& a ) const { return( a ); } // ------------------------------------------------------------------------- template< class I, class O > typename cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >::_Greater:: _T cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >::_Greater:: operator()( const _T& a, const _T& b ) const { typedef itk::NumericTraits< _T > _TTraits; typedef typename _TTraits::ValueType _TValue; typedef vnl_vector< _TValue > _TVector; _TVector va( _TTraits::GetLength( ) ); _TVector vb( _TTraits::GetLength( ) ); _TTraits::AssignToArray( a, va ); _TTraits::AssignToArray( b, vb ); return( ( vb.magnitude( ) < va.magnitude( ) )? a: b ); } // ------------------------------------------------------------------------- template< class I, class O > void cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >:: AddScale( const double& s ) { if( this->m_Scales.insert( s ).second ) this->Modified( ); } // ------------------------------------------------------------------------- template< class I, class O > unsigned long cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >:: GetNumberOfScales( ) const { return( this->m_Scales.size( ) ); } // ------------------------------------------------------------------------- template< class I, class O > cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >:: MultiScaleGaussianImageFilter( ) : Superclass( ) { } // ------------------------------------------------------------------------- template< class I, class O > cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >:: ~MultiScaleGaussianImageFilter( ) { } // ------------------------------------------------------------------------- template< class I, class O > void cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >:: GenerateData( ) { typedef itk::GradientRecursiveGaussianImageFilter< I, O > _TGF; this->_GenerateData< _TGF >( ); } // ------------------------------------------------------------------------- template< class I, class O > template< class F > void cpExtensions::Algorithms:: MultiScaleGaussianImageFilter< I, O >:: _GenerateData( ) { // Some types typedef itk::BinaryFunctorImageFilter< O, O, O, _Greater > _TMaxFilter; typedef itk::UnaryFunctorImageFilter< O, O, _Greater > _TCopyFilter; typedef itk::ImageRegionConstIterator< O > _TConstIt; typedef itk::ImageRegionIterator< O > _TIt; typedef itk::ProgressAccumulator _TProgress; // Some values typename I::ConstPointer input = this->GetInput( ); typename O::Pointer output = this->GetOutput( ); unsigned int nThreads = this->GetNumberOfThreads( ); float fw = float( 1 ) / float( this->m_Scales.size( ) << 1 ); // Progress accumulator _TProgress::Pointer pg = _TProgress::New( ); pg->SetMiniPipelineFilter( this ); // Copy image information output->SetLargestPossibleRegion( input->GetLargestPossibleRegion( ) ); output->SetRequestedRegion( input->GetRequestedRegion( ) ); output->SetBufferedRegion( input->GetBufferedRegion( ) ); output->SetSpacing( input->GetSpacing( ) ); output->SetOrigin( input->GetOrigin( ) ); output->SetDirection( input->GetDirection( ) ); output->Allocate( ); // Intermediary buffer typename O::Pointer buffer = O::New( ); buffer->SetLargestPossibleRegion( input->GetLargestPossibleRegion( ) ); buffer->SetRequestedRegion( input->GetRequestedRegion( ) ); buffer->SetBufferedRegion( input->GetBufferedRegion( ) ); buffer->SetSpacing( input->GetSpacing( ) ); buffer->SetOrigin( input->GetOrigin( ) ); buffer->SetDirection( input->GetDirection( ) ); buffer->Allocate( ); // Perform all scales _TIt gIt( output, output->GetRequestedRegion( ) ); TScalesContainer::const_iterator sIt = this->m_Scales.begin( ); for( ; sIt != this->m_Scales.end( ); sIt++ ) { // Single scale filter typename F::Pointer filter = F::New( ); filter->SetInput( input ); filter->SetNormalizeAcrossScale( true ); filter->SetNumberOfThreads( nThreads ); filter->SetSigma( *sIt ); pg->RegisterInternalFilter( filter, fw ); filter->GraftOutput( buffer ); filter->Update( ); buffer->Graft( filter->GetOutput( ) ); // Get maximum response if( sIt == this->m_Scales.begin( ) ) { // Copy first result typename _TCopyFilter::Pointer copy = _TCopyFilter::New( ); copy->SetInput( buffer ); copy->InPlaceOff( ); copy->SetNumberOfThreads( nThreads ); pg->RegisterInternalFilter( copy, fw ); copy->GraftOutput( output ); copy->Update( ); output->Graft( copy->GetOutput( ) ); } else { // Maximize results typename _TMaxFilter::Pointer max = _TMaxFilter::New( ); max->SetInput1( output ); max->SetInput2( buffer ); max->InPlaceOn( ); max->SetNumberOfThreads( nThreads ); pg->RegisterInternalFilter( max, fw ); max->GraftOutput( output ); max->Update( ); output->Graft( max->GetOutput( ) ); } // fi } // rof } #endif // __cpExtensions__Algorithms__MultiScaleGaussianImageFilter__hxx__ // eof - $RCSfile$