// ========================================================================= // @author Leonardo Florez Valencia // @email florez-l@javeriana.edu.co // ========================================================================= #ifndef __CTBronchi__MoriLabelling__h__ #define __CTBronchi__MoriLabelling__h__ #include #include #include #include #include #include namespace CTBronchi { /** */ template< class _TImage, class _TLabels > class MoriLabellingTraits : public fpa::Filters::Image::DefaultTraits< _TImage, _TLabels, typename _TLabels::PixelType > { public: typedef fpa::Filters::Image::DefaultTraits< _TImage, _TLabels, typename _TLabels::PixelType > Superclass; typedef typename Superclass::TInternalTraits TInternalTraits; typedef typename Superclass::TMarksImage TMarksImage; typedef typename Superclass::TFilterInterface TFilterInterface; typedef fpa::Filters::BaseMarksInterface< TInternalTraits > TMarksInterface; typedef fpa::Filters::Image::SeedsFromLabelsInterface< TInternalTraits > TSeedsInterface; }; /** */ template< class _TImage, class _TLabels, class _TScalarImage > class MoriLabelling : public fpa::Filters::Image::RegionGrow< _TImage, _TLabels, typename _TLabels::PixelType, CTBronchi::MoriLabellingTraits< _TImage, _TLabels > > { public: typedef CTBronchi::MoriLabellingTraits< _TImage, _TLabels > TTraits; fpaTraitsMacro( typename TTraits ); typedef fpa::Filters::Image::RegionGrow< _TImage, _TLabels, TMark, TTraits > Superclass; typedef MoriLabelling Self; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; typedef fpa::Functors::RegionGrow::BinaryThreshold< TInputValue > TFunctor; public: itkNewMacro( Self ); itkTypeMacro( MoriLabelling, fpa::Filters::Image::RegionGrow ); itkGetConstMacro( VesselnessThreshold, double ); itkSetMacro( VesselnessThreshold, double ); itkGetConstMacro( UpperThreshold, TInputValue ); itkSetMacro( UpperThreshold, TInputValue ); ivqITKInputMacro( InputLabels, _TLabels ); ivqITKInputMacro( InputVesselness, _TScalarImage ); protected: MoriLabelling( ) : Superclass( ), m_VesselnessThreshold( 5 ), m_UpperThreshold( -650 ) { ivqITKInputConfigureMacro( InputLabels, _TLabels ); ivqITKInputConfigureMacro( InputVesselness, _TScalarImage ); this->m_Functor = TFunctor::New( ); this->SetPredicate( this->m_Functor ); } virtual ~MoriLabelling( ) { } virtual const itk::DataObject* _GetReferenceInput( ) const override { return( this->GetInputLabels( ) ); } virtual void _BeforeGenerateData( ) override { this->Superclass::_BeforeGenerateData( ); this->m_Functor->SetUpperThreshold( this->m_UpperThreshold ); typedef itk::MinimumMaximumImageCalculator< _TScalarImage > _TMinMax; typename _TMinMax::Pointer minMax = _TMinMax::New( ); minMax->SetImage( this->GetInputVesselness( ) ); minMax->Compute( ); this->m_MinVesselness = ( 1.0 - ( this->m_VesselnessThreshold / double( 100 ) ) ) * double( minMax->GetMaximum( ) ); } virtual void _PostComputeOutputValue( TNode& n ) override { this->Superclass::_PostComputeOutputValue( n ); if( n.Value == this->GetInsideValue( ) ) { const _TLabels* labels = this->GetInputLabels( ); const _TScalarImage* vesselness = this->GetInputVesselness( ); if( labels->GetPixel( n.Vertex ) == 0 ) { if( this->m_MinVesselness < vesselness->GetPixel( n.Vertex ) ) n.Value = this->GetInsideValue( ); else n.Value = 0; } // fi } // fi } private: // Purposely not implemented. MoriLabelling( const Self& other ); Self& operator=( const Self& other ); protected: typename TFunctor::Pointer m_Functor; double m_VesselnessThreshold; double m_MinVesselness; TInputValue m_UpperThreshold; }; } // ecapseman #endif // __CTBronchi__Functions__h__ // eof - $RCSfile$