// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
// -------------------------------------------------------------------------
-#ifndef __CPEXTENSIONS__ALGORITHMS__IMAGEFUNCTORFILTER__H__
-#define __CPEXTENSIONS__ALGORITHMS__IMAGEFUNCTORFILTER__H__
+#ifndef __cpExtensions__Algorithms__ImageFunctorFilter__h__
+#define __cpExtensions__Algorithms__ImageFunctorFilter__h__
+#include <itkFunctionBase.h>
#include <itkImageToImageFilter.h>
-#include <itkImageScanlineConstIterator.h>
-#include <itkImageScanlineIterator.h>
-#include <itkProgressReporter.h>
namespace cpExtensions
{
{
/**
*/
- template< class I, class O, class F >
+ template< class _TInputImage, class _TOutputImage >
class ImageFunctorFilter
: public itk::ImageToImageFilter< I, O >
{
public:
- typedef ImageFunctorFilter Self;
+ typedef ImageFunctorFilter Self;
typedef itk::ImageToImageFilter< I, O > Superclass;
typedef itk::SmartPointer< Self > Pointer;
typedef itk::SmartPointer< const Self > ConstPointer;
- typedef I TInputImage;
- typedef O TOutputImage;
- typedef F TFunctor;
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ typedef typename TInputImage::PixelType TInputPixel;
+ typedef typename TOutputImage::PixelType TOutputPixel;
+ typedef typename TOutputImage::RegionType TRegion;
- typedef typename O::RegionType TRegion;
+ typedef itk::FunctionBase< TInputPixel, TOutputPixel > TFunctor;
public:
itkNewMacro( Self );
itkTypeMacro( ImageFunctorFilter, itkImageToImageFilter );
- itkGetMacro( Functor, F );
- itkGetConstMacro( Functor, F );
+ itkGetObjectMacro( Functor, TFunctor );
+ itkGetConstObjectMacro( Functor, TFunctor );
+ itkSetObjectMacro( Functor, TFunctor );
protected:
- ImageFunctorFilter( )
- : Superclass( )
- {
- }
- virtual ~ImageFunctorFilter( )
- {
- }
-
- virtual void ThreadedGenerateData(
- const TRegion& region,
- itk::ThreadIdType threadId
- )
- {
- const typename TRegion::SizeType& regionSize = region.GetSize( );
- if( regionSize[ 0 ] == 0 )
- return;
- const I* in = this->GetInput( );
- O* out = this->GetOutput( 0 );
-
- const size_t nLines = region.GetNumberOfPixels( ) / regionSize[ 0 ];
- itk::ProgressReporter progress( this, threadId, nLines );
-
- // Define the iterators
- itk::ImageScanlineConstIterator< I > inIt( in, region );
- itk::ImageScanlineIterator< O > outIt( out, region );
-
- inIt.GoToBegin( );
- outIt.GoToBegin( );
- while( !inIt.IsAtEnd( ) )
- {
- while( !inIt.IsAtEndOfLine( ) )
- {
- outIt.Set( this->m_Functor( inIt.Get( ) ) );
- ++inIt;
- ++outIt;
-
- } // elihw
- inIt.NextLine( );
- outIt.NextLine( );
- progress.CompletedPixel( );
-
- } // elihw
- }
+ ImageFunctorFilter( );
+ virtual ~ImageFunctorFilter( );
+
+ virtual void ThreadedGenerateData( const TRegion& region, itk::ThreadIdType threadId ) override;
private:
// Purposely not implemented.
void operator=( const Self& );
protected:
- F m_Functor;
+ typename TFunctor::Pointer m_Functor;
};
} // ecapseman
} // ecapseman
-#endif // __CPEXTENSIONS__ALGORITHMS__IMAGEFUNCTORFILTER__H__
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <cpExtensions/Algorithms/ImageFunctorFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __cpExtensions__Algorithms__ImageFunctorFilter__h__
// eof - $RCSfile$
--- /dev/null
+// -------------------------------------------------------------------------
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// -------------------------------------------------------------------------
+
+#ifndef __cpExtensions__Algorithms__ImageFunctorFilter__hxx__
+#define __cpExtensions__Algorithms__ImageFunctorFilter__hxx__
+
+#include <itkImageScanlineConstIterator.h>
+#include <itkImageScanlineIterator.h>
+#include <itkProgressReporter.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+cpExtensions::Algorithms::ImageFunctorFilter< _TInputImage, _TOutputImage >::
+ImageFunctorFilter( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+cpExtensions::Algorithms::ImageFunctorFilter< _TInputImage, _TOutputImage >::
+~ImageFunctorFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void
+cpExtensions::Algorithms::ImageFunctorFilter< _TInputImage, _TOutputImage >::
+ThreadedGenerateData( const TRegion& region, itk::ThreadIdType threadId )
+{
+ // Configure data for this thread
+ const typename TRegion::SizeType& regionSize = region.GetSize( );
+ if( regionSize[ 0 ] == 0 )
+ return;
+ const TInputImage* in = this->GetInput( );
+ TOutputImage* out = this->GetOutput( 0 );
+ const size_t nLines = region.GetNumberOfPixels( ) / regionSize[ 0 ];
+ itk::ProgressReporter progress( this, threadId, nLines );
+
+ // Iterate over this region
+ itk::ImageScanlineConstIterator< TInputImage > iIt( in, region );
+ itk::ImageScanlineIterator< TOutputImage > oIt( out, region );
+ iIt.GoToBegin( );
+ oIt.GoToBegin( );
+ while( !iIt.IsAtEnd( ) )
+ {
+ while( !iIt.IsAtEndOfLine( ) )
+ {
+ oIt.Set( this->m_Functor->Evaluate( iIt.Get( ) ) );
+ ++iIt;
+ ++oIt;
+
+ } // elihw
+ iIt.NextLine( );
+ oIt.NextLine( );
+ progress.CompletedPixel( );
+
+ } // elihw
+}
+
+#endif // __cpExtensions__Algorithms__ImageFunctorFilter__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// -------------------------------------------------------------------------
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// -------------------------------------------------------------------------
+
+#ifndef __cpExtensions__Algorithms__RGBToSingleChannelFunctor__h__
+#define __cpExtensions__Algorithms__RGBToSingleChannelFunctor__h__
+
+#include <itkFunctionBase.h>
+#include <itkRGBPixel.h>
+
+namespace cpExtensions
+{
+ namespace Algorithms
+ {
+ /**
+ */
+ template< class _TScalar >
+ class RGBToSingleChannelFunctor
+ : public itk::FunctionBase< itk::RGBPixel< _TScalar >, _TScalar >
+ {
+ public:
+ typedef _TScalar TScalar;
+ typedef itk::RGBPixel< _TScalar > TPixel;
+ typedef RGBToSingleChannelFunctor Self;
+ typedef itk::FunctionBase< TPixel, TScalar > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ enum ChannelType
+ {
+ Red = 0,
+ Green,
+ Blue,
+ Hue,
+ Saturation,
+ Value
+ };
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( RGBToSingleChannelFunctor, itkFunctionBase );
+
+ itkGetConstMacro( Channel, ChannelType );
+ itkSetMacro( Channel, ChannelType );
+
+ public:
+ bool IsChannelRed( ) const;
+ bool IsChannelGreen( ) const;
+ bool IsChannelBlue( ) const;
+ bool IsChannelHue( ) const;
+ bool IsChannelSaturation( ) const;
+ bool IsChannelValue( ) const;
+
+ void SetChannelToRed( );
+ void SetChannelToGreen( );
+ void SetChannelToBlue( );
+ void SetChannelToHue( );
+ void SetChannelToSaturation( );
+ void SetChannelToValue( );
+
+ virtual TScalar Evaluate( const TPixel& pixel ) const override;
+
+ protected:
+ RGBToSingleChannelFunctor( );
+ virtual ~RGBToSingleChannelFunctor( );
+
+ private:
+ // Purposely not implemented.
+ RGBToSingleChannelFunctor( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ ChannelType m_Channel;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <cpExtensions/Algorithms/RGBToSingleChannelFunctor.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __cpExtensions__Algorithms__RGBToSingleChannelFunctor__h__
+
+// eof - $RCSfile$
--- /dev/null
+// -------------------------------------------------------------------------
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// -------------------------------------------------------------------------
+
+#ifndef __cpExtensions__Algorithms__RGBToSingleChannelFunctor__hxx__
+#define __cpExtensions__Algorithms__RGBToSingleChannelFunctor__hxx__
+
+#include <cmath>
+#include <limits>
+#include <vnl/vnl_math.h>
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+bool cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+IsChannelRed( ) const
+{
+ return( this->m_Channel == Self::Red );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+bool cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+IsChannelGreen( ) const
+{
+ return( this->m_Channel == Self::Green );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+bool cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+IsChannelBlue( ) const
+{
+ return( this->m_Channel == Self::Blue );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+bool cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+IsChannelHue( ) const
+{
+ return( this->m_Channel == Self::Hue );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+bool cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+IsChannelSaturation( ) const
+{
+ return( this->m_Channel == Self::Saturation );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+bool cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+IsChannelValue( ) const
+{
+ return( this->m_Channel == Self::Value );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+SetChannelToRed( )
+{
+ this->SetChannel( Self::Red );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+SetChannelToGreen( )
+{
+ this->SetChannel( Self::Green );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+SetChannelToBlue( )
+{
+ this->SetChannel( Self::Blue );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+SetChannelToHue( )
+{
+ this->SetChannel( Self::Hue );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+SetChannelToSaturation( )
+{
+ this->SetChannel( Self::Saturation );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+SetChannelToValue( )
+{
+ this->SetChannel( Self::Value );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+_TScalar cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+Evaluate( const TPixel& pixel ) const
+{
+ _TScalar res;
+ switch( this->m_Channel )
+ {
+ case Self::Hue:
+ {
+ double R = double( pixel.GetRed( ) );
+ double G = double( pixel.GetRed( ) );
+ double B = double( pixel.GetBlue( ) );
+ double RG = R - G;
+ double RB = R - B;
+ double GB = G - B;
+ double A = std::sqrt( ( RG * RG ) + ( RB * GB ) );
+ if( A != _0 )
+ A = std::acos( ( RG + RB ) / ( double( 2 ) * A ) );
+ A /= double( 2 ) * double( vnl_math::pi );
+ res =
+ _TScalar(
+ double( std::numeric_limits< _TScalar >::max( ) ) *
+ ( ( G >= B )? A: double( 1 ) - A )
+ );
+ }
+ break;
+ case Self::Saturation:
+ {
+ double R = double( r );
+ double G = double( g );
+ double B = double( b );
+ double sRGB = R + G + B;
+ double RG = R - G;
+ double RB = R - B;
+ double GB = G - B;
+ if( sRGB != double( 0 ) )
+ {
+ double C = ( G < R )? G: R;
+ C = ( B < C )? B: C;
+ res =
+ _TScalar(
+ double( std::numeric_limits< _TScalar >::max( ) ) *
+ ( double( 1 ) - ( ( double( 3 ) * C ) / sRGB ) )
+ );
+ }
+ else
+ res = _TScalar( 0 );
+ }
+ break;
+ case Self::Value:
+ {
+ res = ( pixel.GetRed( ) + pixel.GetGreen( ) + pixel.GetBlue( ) ) / 3;
+ }
+ break;
+ case Self::Green: { res = pixel.GetGreen( ); } break;
+ case Self::Blue: { res = pixel.GetBlue( ); } break;
+ case Self::Red: default: { res = pixel.GetRed( ); } break;
+ } // hctiws
+ return( res );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+RGBToSingleChannelFunctor( )
+ : Superclass( )
+{
+ this->SetChannelToRed( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+cpExtensions::Algorithms::RGBToSingleChannelFunctor< _TScalar >::
+~RGBToSingleChannelFunctor( )
+{
+}
+
+#endif // __cpExtensions__Algorithms__RGBToSingleChannelFunctor__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+#include <cpPlugins/Pipeline/Functor.h>
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::Functor::
+Functor( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::Functor::
+~Functor( )
+{
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __cpPlugins__Pipeline__Functor__h__
+#define __cpPlugins__Pipeline__Functor__h__
+
+#include <cpPlugins/Pipeline/ProcessObject.h>
+
+// -------------------------------------------------------------------------
+namespace cpPlugins
+{
+ namespace Pipeline
+ {
+ /**
+ */
+ class cpPlugins_EXPORT Functor
+ : public ProcessObject
+ {
+ public:
+ typedef Functor Self;
+ typedef ProcessObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkTypeMacro( Functor, ProcessObject );
+ cpPlugins_Id_Macro( Functor, Object );
+
+ protected:
+ Functor( );
+ virtual ~Functor( );
+
+ private:
+ // Purposely not implemented
+ Functor( const Self& );
+ Self& operator=( const Self& );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __cpPlugins__Pipeline__Functor__h__
+
+// eof - $RCSfile$
--- /dev/null
+#include <cpExtensions/ImageFunctorFilter.h>
+#include <cpInstances/DataObjects/Image.h>
+
+/* TODO
+ #include <cpExtensions/Visualization/ImageFunctorFilter.h>
+*/
+
+// -------------------------------------------------------------------------
+cpPluginscpExtensions::ImageFunctorFilter::
+ImageFunctorFilter( )
+ : Superclass( )
+{
+ typedef cpPlugins::DataObject _TFunctor;
+ typedef cpInstances::DataObjects::Image _TImage;
+
+ this->_ConfigureInput< _TImage >( "Input", true, false );
+ this->_ConfigureInput< _TFunctor >( "Functor", true, false );
+ this->_ConfigureOutput< _TImage >( "Output" );
+}
+
+// -------------------------------------------------------------------------
+cpPluginscpExtensions::ImageFunctorFilter::
+~ImageFunctorFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+void cpPluginscpExtensions::ImageFunctorFilter::
+_GenerateData( )
+{
+ auto o = this->GetInputData( "Input" );
+ cpPlugins_Demangle_Image_ScalarPixels_AllDims_1( o, _GD0 )
+ cpPlugins_Demangle_Image_ComplexPixels_AllDims_1( o, _GD0 )
+ cpPlugins_Demangle_Image_ColorPixels_AllDims_1( o, _GD0 )
+ cpPlugins_Demangle_Image_VectorPixels_AllDims_1( o, _GD0 )
+ this->_Error( "Invalid input image pixel type." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage >
+void cpPluginscpExtensions::ImageFunctorFilter::
+_GD0( _TInputImage* input )
+{
+ /* TODO
+ typedef cpExtensions::Visualization::ImageFunctorFilter< _TPath > _TFilter;
+ auto filter = this->_CreateVTK< _TFilter >( );
+ filter->SetInput( path );
+ filter->Update( );
+ this->GetOutput( "Output" )->SetVTK( filter->GetOutput( ) );
+ */
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void cpPluginscpExtensions::ImageFunctorFilter::
+_GD1( _TInputImage* input )
+{
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __cpPluginscpExtensions__ImageFunctorFilter__h__
+#define __cpPluginscpExtensions__ImageFunctorFilter__h__
+
+#include <cpPlugins_cpExtensions_Export.h>
+#include <cpPlugins/Pipeline/ProcessObject.h>
+
+namespace cpPluginscpExtensions
+{
+ /**
+ */
+ class cpPlugins_cpExtensions_EXPORT ImageFunctorFilter
+ : public cpPlugins::Pipeline::ProcessObject
+ {
+ cpPluginsObject(
+ ImageFunctorFilter,
+ cpPlugins::Pipeline::ProcessObject,
+ cpExtensions
+ );
+
+ protected:
+ template< class _TInputImage >
+ inline void _GD0( _TInputImage* input );
+
+ template< class _TInputImage, class _TOutputImage >
+ inline void _GD1( _TInputImage* input );
+ };
+
+} // ecapseman
+
+#endif // __cpPluginscpExtensions__ImageFunctorFilter__h__
+
+
+// eof - $RCSfile$