From 483d0cad67a04fc8c3613ceb3a20a2ab02c29822 Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Mon, 30 Mar 2015 11:11:28 -0500 Subject: [PATCH] YPbPr color model added --- appli/examples/CMakeLists.txt | 1 + .../example_RGBImageToHSVChannels.cxx | 5 +- .../example_RGBImageToYPbPrChannels.cxx | 109 +++++++++ .../RGBImageToHSVChannelsFilter.hxx | 230 ------------------ ...lter.h => RGBImageToOtherChannelsFilter.h} | 50 ++-- .../RGBImageToOtherChannelsFilter.hxx | 190 +++++++++++++++ .../Extensions/Algorithms/RGBToHSVFunction.h | 91 +++++++ .../Algorithms/RGBToYPbPrFunction.h | 69 ++++++ lib/cpPlugins/Plugins/CMakeLists.txt | 1 + lib/cpPlugins/Plugins/Host.cxx | 2 + .../Plugins/RGBImageToHSVChannelsFilter.cxx | 13 +- .../Plugins/RGBImageToYPbPrChannelsFilter.cxx | 136 +++++++++++ .../Plugins/RGBImageToYPbPrChannelsFilter.h | 62 +++++ 13 files changed, 695 insertions(+), 264 deletions(-) create mode 100644 appli/examples/example_RGBImageToYPbPrChannels.cxx delete mode 100644 lib/cpPlugins/Extensions/Algorithms/RGBImageToHSVChannelsFilter.hxx rename lib/cpPlugins/Extensions/Algorithms/{RGBImageToHSVChannelsFilter.h => RGBImageToOtherChannelsFilter.h} (53%) create mode 100644 lib/cpPlugins/Extensions/Algorithms/RGBImageToOtherChannelsFilter.hxx create mode 100644 lib/cpPlugins/Extensions/Algorithms/RGBToHSVFunction.h create mode 100644 lib/cpPlugins/Extensions/Algorithms/RGBToYPbPrFunction.h create mode 100644 lib/cpPlugins/Plugins/RGBImageToYPbPrChannelsFilter.cxx create mode 100644 lib/cpPlugins/Plugins/RGBImageToYPbPrChannelsFilter.h diff --git a/appli/examples/CMakeLists.txt b/appli/examples/CMakeLists.txt index 43938d9..c986abe 100644 --- a/appli/examples/CMakeLists.txt +++ b/appli/examples/CMakeLists.txt @@ -12,6 +12,7 @@ SET( example_ReadQuadEdgeMesh example_RenderQuadEdgeMesh example_RGBImageToHSVChannels + example_RGBImageToYPbPrChannels example_MPR ) diff --git a/appli/examples/example_RGBImageToHSVChannels.cxx b/appli/examples/example_RGBImageToHSVChannels.cxx index 565c44f..4e8e6bf 100644 --- a/appli/examples/example_RGBImageToHSVChannels.cxx +++ b/appli/examples/example_RGBImageToHSVChannels.cxx @@ -26,9 +26,10 @@ void SaveImage( return; } // fi + // Configure reader TParameters writer_params = writer->GetDefaultParameters( ); - writer_params.AddValueToStringList( "FileName", fname ); + writer_params.SetValueAsString( "FileName", fname ); writer->SetParameters( writer_params ); writer->SetInput( 0, image ); @@ -85,7 +86,7 @@ int main( int argc, char* argv[] ) // Configure reader TParameters reader_params = reader->GetDefaultParameters( ); - reader_params.SetValueAsString( "FileName", input_image_file ); + reader_params.AddValueToStringList( "FileNames", input_image_file ); reader_params.SetValueAsString( "PixelType", pixel_type ); reader_params.SetValueAsUint( "ImageDimension", dimensions ); reader_params.SetValueAsUint( "IsColorImage", 1 ); diff --git a/appli/examples/example_RGBImageToYPbPrChannels.cxx b/appli/examples/example_RGBImageToYPbPrChannels.cxx new file mode 100644 index 0000000..f94f203 --- /dev/null +++ b/appli/examples/example_RGBImageToYPbPrChannels.cxx @@ -0,0 +1,109 @@ +#include +#include +#include + +#include +#include +#include + +// ------------------------------------------------------------------------- +typedef cpPlugins::Interface::Interface TInterface; +typedef cpPlugins::Interface::DataObject TDataObject; +typedef TInterface::TClasses TClasses; +typedef cpPlugins::Interface::ProcessObject TProcessObject; +typedef cpPlugins::Interface::Parameters TParameters; + +// ------------------------------------------------------------------------- +void SaveImage( + TInterface& plugins, const std::string& fname, TDataObject* image + ) +{ + TProcessObject::Pointer writer; + writer = plugins.CreateProcessObject( "cpPlugins::Plugins::ImageWriter" ); + if( writer.IsNull( ) ) + { + std::cerr << "No suitable writer found in plugins." << std::endl; + return; + + } // fi + + // Configure reader + TParameters writer_params = writer->GetDefaultParameters( ); + writer_params.SetValueAsString( "FileName", fname ); + writer->SetParameters( writer_params ); + + writer->SetInput( 0, image ); + std::string msg = writer->Update( ); + if( msg != "" ) + std::cerr << "ERROR: " << msg << std::endl; +} + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 8 ) + { + std::cerr + << "Usage: " << argv[ 0 ] + << " plugins_file" + << " input_image" + << " output_hue_image output_saturation_image output_value_image" + << " dimensions pixel_type" << std::endl; + return( 1 ); + + } // fi + std::string plugins_file = argv[ 1 ]; + std::string input_image_file = argv[ 2 ]; + std::string output_hue_image_file = argv[ 3 ]; + std::string output_saturation_image_file = argv[ 4 ]; + std::string output_value_image_file = argv[ 5 ]; + unsigned int dimensions = std::atoi( argv[ 6 ] ); + std::string pixel_type = argv[ 7 ]; + + // Create interface + + TInterface plugins; + plugins.Load( plugins_file ); + + // Create objects + TProcessObject::Pointer reader; + TProcessObject::Pointer filter; + + reader = plugins.CreateProcessObject( "cpPlugins::Plugins::ImageReader" ); + if( reader.IsNull( ) ) + { + std::cerr << "No suitable reader found in plugins." << std::endl; + return( 1 ); + + } // fi + filter = plugins.CreateProcessObject( "cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter" ); + if( filter.IsNull( ) ) + { + std::cerr << "No suitable filter found in plugins." << std::endl; + return( 1 ); + + } // fi + + // Configure reader + TParameters reader_params = reader->GetDefaultParameters( ); + reader_params.AddValueToStringList( "FileNames", input_image_file ); + reader_params.SetValueAsString( "PixelType", pixel_type ); + reader_params.SetValueAsUint( "ImageDimension", dimensions ); + reader_params.SetValueAsUint( "IsColorImage", 1 ); + reader->SetParameters( reader_params ); + + // Connect pipeline + TParameters filter_params = filter->GetDefaultParameters( ); + filter_params.SetValueAsString( "OutputPixelType", "float" ); + filter->SetParameters( filter_params ); + filter->SetInput( 0, reader->GetOutput( 0 ) ); + + // Save outputs + SaveImage( plugins, output_hue_image_file, filter->GetOutput( 0 ) ); + SaveImage( plugins, output_saturation_image_file, filter->GetOutput( 1 ) ); + SaveImage( plugins, output_value_image_file, filter->GetOutput( 2 ) ); + + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/RGBImageToHSVChannelsFilter.hxx b/lib/cpPlugins/Extensions/Algorithms/RGBImageToHSVChannelsFilter.hxx deleted file mode 100644 index b45a953..0000000 --- a/lib/cpPlugins/Extensions/Algorithms/RGBImageToHSVChannelsFilter.hxx +++ /dev/null @@ -1,230 +0,0 @@ -// ------------------------------------------------------------------------- -// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) -// ------------------------------------------------------------------------- - -#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOHSVCHANNELSFILTER__HXX__ -#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOHSVCHANNELSFILTER__HXX__ - -#include -#include -#include - -#include -#include - -// ------------------------------------------------------------------------- -template< class I, class O > -O* cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GetHueOutput( ) -{ - return( this->GetOutput( 0 ) ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -O* cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GetSaturationOutput( ) -{ - return( this->GetOutput( 1 ) ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -O* cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GetValueOutput( ) -{ - return( this->GetOutput( 2 ) ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -const O* -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GetHueOutput( ) const -{ - if( this->GetNumberOfOutputs( ) > 0 ) - return( - dynamic_cast< const O* >( - this->itk::ProcessObject::GetOutput( 0 ) - ) - ); - else - return( NULL ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -const O* -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GetSaturationOutput( ) const -{ - if( this->GetNumberOfOutputs( ) > 1 ) - return( - dynamic_cast< const O* >( - this->itk::ProcessObject::GetOutput( 1 ) - ) - ); - else - return( NULL ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -const O* -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GetValueOutput( ) const -{ - if( this->GetNumberOfOutputs( ) > 2 ) - return( - dynamic_cast< const O* >( - this->itk::ProcessObject::GetOutput( 2 ) - ) - ); - else - return( NULL ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -void -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GraftHueOutput( O* hue ) -{ - this->GraftNthOutput( 0, hue ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -void -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GraftSaturationOutput( O* saturation ) -{ - this->GraftNthOutput( 1, saturation ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -void -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -GraftValueOutput( O* value ) -{ - this->GraftNthOutput( 2, value ); -} - -// ------------------------------------------------------------------------- -template< class I, class O > -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -RGBImageToHSVChannelsFilter( ) - : Superclass( ) -{ - this->SetNumberOfRequiredInputs( 1 ); - this->SetNumberOfRequiredOutputs( 3 ); - for( unsigned int i = 0; i < 3; i++ ) - { - typename O::Pointer o = O::New( ); - this->SetNthOutput( i, o ); - - } // rof -} - -// ------------------------------------------------------------------------- -template< class I, class O > -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -~RGBImageToHSVChannelsFilter( ) -{ -} - -// ------------------------------------------------------------------------- -template< class I, class O > -void -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -BeforeThreadedGenerateData( ) -{ -} - -// ------------------------------------------------------------------------- -template< class I, class O > -void cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -AfterThreadedGenerateData( ) -{ -} - -// ------------------------------------------------------------------------- -template< class I, class O > -void -cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -ThreadedGenerateData( - const typename Superclass::OutputImageRegionType& region, - itk::ThreadIdType threadId - ) -{ - typedef itk::ImageRegionConstIterator< I > TInIt; - typedef itk::ImageRegionIterator< O > TOutIt; - - TInIt inIt( this->GetInput( ), region ); - TOutIt hIt( this->GetHueOutput( ), region ); - TOutIt sIt( this->GetSaturationOutput( ), region ); - TOutIt vIt( this->GetValueOutput( ), region ); - inIt.GoToBegin( ); - hIt.GoToBegin( ); - sIt.GoToBegin( ); - vIt.GoToBegin( ); - for( ; !inIt.IsAtEnd( ); ++inIt, ++hIt, ++sIt, ++vIt ) - { - TOutputPixel H, S, V; - Self::_RGB2HSV( inIt.Get( ), H, S, V ); - hIt.Set( H ); - sIt.Set( S ); - vIt.Set( V ); - - } // rof -} - -// ------------------------------------------------------------------------- -template< class I, class O > -void cpPlugins::Extensions::Algorithms::RGBImageToHSVChannelsFilter< I, O >:: -_RGB2HSV( - const TInputPixel& RGB, - TOutputPixel& H, TOutputPixel& S, TOutputPixel& V - ) -{ - typedef typename TInputPixel::ComponentType TComponent; - const double mVal = double( std::numeric_limits< TComponent >::max( ) ); - const double _0 = double( 0 ); - const double _1 = double( 1 ); - const double _2 = double( 2 ); - const double _3 = double( 3 ); - const double _2pi = _2 * double( vnl_math::pi ); - - double R = double( RGB.GetRed( ) ); - double G = double( RGB.GetGreen( ) ); - double B = double( RGB.GetBlue( ) ); - double sRGB = R + G + B; - double RG = R - G; - double RB = R - B; - double GB = G - B; - - // Hue - double A = std::sqrt( ( RG * RG ) + ( RB * GB ) ); - if( A != _0 ) - A = std::acos( ( RG + RB ) / ( _2 * A ) ); - A /= _2pi; - H = TOutputPixel( mVal * ( ( G >= B )? A: _1 - A ) ); - - // Saturation - if( sRGB != _0 ) - { - double C = ( G < R )? G: R; - C = ( B < C )? B: C; - S = TOutputPixel( mVal * ( _1 - ( ( _3 * C ) / sRGB ) ) ); - } - else - S = TOutputPixel( 0 ); - - // Value - V = TOutputPixel( sRGB / _3 ); -} - -#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOHSVCHANNELSFILTER__HXX__ - -// eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/RGBImageToHSVChannelsFilter.h b/lib/cpPlugins/Extensions/Algorithms/RGBImageToOtherChannelsFilter.h similarity index 53% rename from lib/cpPlugins/Extensions/Algorithms/RGBImageToHSVChannelsFilter.h rename to lib/cpPlugins/Extensions/Algorithms/RGBImageToOtherChannelsFilter.h index c497d55..ad91f37 100644 --- a/lib/cpPlugins/Extensions/Algorithms/RGBImageToHSVChannelsFilter.h +++ b/lib/cpPlugins/Extensions/Algorithms/RGBImageToOtherChannelsFilter.h @@ -2,8 +2,8 @@ // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) // ------------------------------------------------------------------------- -#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOHSVCHANNELSFILTER__H__ -#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOHSVCHANNELSFILTER__H__ +#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOOTHERCHANNELSFILTER__H__ +#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOOTHERCHANNELSFILTER__H__ #include @@ -15,41 +15,42 @@ namespace cpPlugins { /** */ - template< class I, class O > - class RGBImageToHSVChannelsFilter + template< class I, class O, class C > + class RGBImageToOtherChannelsFilter : public itk::ImageToImageFilter< I, O > { public: - typedef RGBImageToHSVChannelsFilter Self; + typedef RGBImageToOtherChannelsFilter 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 C TConverter; typedef typename I::PixelType TInputPixel; typedef typename O::PixelType TOutputPixel; public: itkNewMacro( Self ); - itkTypeMacro( RGBImageToHSVChannelsFilter, itkImageToImageFilter ); + itkTypeMacro( RGBImageToOtherChannelsFilter, itkImageToImageFilter ); public: - O* GetHueOutput( ); - O* GetSaturationOutput( ); - O* GetValueOutput( ); + O* GetChannel1( ); + O* GetChannel2( ); + O* GetChannel3( ); - const O* GetHueOutput( ) const; - const O* GetSaturationOutput( ) const; - const O* GetValueOutput( ) const; + const O* GetChannel1( ) const; + const O* GetChannel2( ) const; + const O* GetChannel3( ) const; - void GraftHueOutput( O* hue ); - void GraftSaturationOutput( O* saturation ); - void GraftValueOutput( O* value ); + void GraftChannel1( O* c1 ); + void GraftChannel2( O* c2 ); + void GraftChannel3( O* c3 ); protected: - RGBImageToHSVChannelsFilter( ); - virtual ~RGBImageToHSVChannelsFilter( ); + RGBImageToOtherChannelsFilter( ); + virtual ~RGBImageToOtherChannelsFilter( ); virtual void BeforeThreadedGenerateData( ); virtual void AfterThreadedGenerateData( ); @@ -59,16 +60,13 @@ namespace cpPlugins itk::ThreadIdType threadId ); - protected: - static void _RGB2HSV( - const TInputPixel& RGB, - TOutputPixel& H, TOutputPixel& S, TOutputPixel& V - ); - private: // Purposely not implemented - RGBImageToHSVChannelsFilter( const Self& other ); + RGBImageToOtherChannelsFilter( const Self& other ); void operator=( const Self& other ); + + private: + TConverter Converter; }; } // ecapseman @@ -77,8 +75,8 @@ namespace cpPlugins } // ecapseman -#include +#include -#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOHSVCHANNELSFILTER__H__ +#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOOTHERCHANNELSFILTER__H__ // eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/RGBImageToOtherChannelsFilter.hxx b/lib/cpPlugins/Extensions/Algorithms/RGBImageToOtherChannelsFilter.hxx new file mode 100644 index 0000000..d0301c9 --- /dev/null +++ b/lib/cpPlugins/Extensions/Algorithms/RGBImageToOtherChannelsFilter.hxx @@ -0,0 +1,190 @@ +// ------------------------------------------------------------------------- +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ------------------------------------------------------------------------- + +#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOOTHERCHANNELSFILTER__HXX__ +#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOOTHERCHANNELSFILTER__HXX__ + +#include +#include +#include + +#include +#include + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +O* +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GetChannel1( ) +{ + return( this->GetOutput( 0 ) ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +O* +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GetChannel2( ) +{ + return( this->GetOutput( 1 ) ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +O* +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GetChannel3( ) +{ + return( this->GetOutput( 2 ) ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +const O* +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GetChannel1( ) const +{ + if( this->GetNumberOfOutputs( ) > 0 ) + return( + dynamic_cast< const O* >( + this->itk::ProcessObject::GetOutput( 0 ) + ) + ); + else + return( NULL ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +const O* +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GetChannel2( ) const +{ + if( this->GetNumberOfOutputs( ) > 1 ) + return( + dynamic_cast< const O* >( + this->itk::ProcessObject::GetOutput( 1 ) + ) + ); + else + return( NULL ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +const O* +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GetChannel3( ) const +{ + if( this->GetNumberOfOutputs( ) > 2 ) + return( + dynamic_cast< const O* >( + this->itk::ProcessObject::GetOutput( 2 ) + ) + ); + else + return( NULL ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +void +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GraftChannel1( O* hue ) +{ + this->GraftNthOutput( 0, hue ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +void +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GraftChannel2( O* saturation ) +{ + this->GraftNthOutput( 1, saturation ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +void +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +GraftChannel3( O* value ) +{ + this->GraftNthOutput( 2, value ); +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +RGBImageToOtherChannelsFilter( ) + : Superclass( ) +{ + this->SetNumberOfRequiredInputs( 1 ); + this->SetNumberOfRequiredOutputs( 3 ); + for( unsigned int i = 0; i < 3; i++ ) + { + typename O::Pointer o = O::New( ); + this->SetNthOutput( i, o ); + + } // rof +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +~RGBImageToOtherChannelsFilter( ) +{ +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +void +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +BeforeThreadedGenerateData( ) +{ +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +void +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +AfterThreadedGenerateData( ) +{ +} + +// ------------------------------------------------------------------------- +template< class I, class O, class C > +void +cpPlugins::Extensions::Algorithms::RGBImageToOtherChannelsFilter< I, O, C >:: +ThreadedGenerateData( + const typename Superclass::OutputImageRegionType& region, + itk::ThreadIdType threadId + ) +{ + // typedef typename TInputPixel::ComponentType _TComponent; + typedef itk::ImageRegionConstIterator< I > _TInIt; + typedef itk::ImageRegionIterator< O > _TOutIt; + typedef typename C::TOutPixel _TOutPixel; + + _TInIt inIt( this->GetInput( ), region ); + _TOutIt hIt( this->GetChannel1( ), region ); + _TOutIt sIt( this->GetChannel2( ), region ); + _TOutIt vIt( this->GetChannel3( ), region ); + inIt.GoToBegin( ); + hIt.GoToBegin( ); + sIt.GoToBegin( ); + vIt.GoToBegin( ); + for( ; !inIt.IsAtEnd( ); ++inIt, ++hIt, ++sIt, ++vIt ) + { + _TOutPixel other = this->Converter( inIt.Get( ) ); + hIt.Set( other[ 0 ] ); + sIt.Set( other[ 1 ] ); + vIt.Set( other[ 2 ] ); + + } // rof +} + +#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBIMAGETOOTHERCHANNELSFILTER__HXX__ + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/RGBToHSVFunction.h b/lib/cpPlugins/Extensions/Algorithms/RGBToHSVFunction.h new file mode 100644 index 0000000..81f7edd --- /dev/null +++ b/lib/cpPlugins/Extensions/Algorithms/RGBToHSVFunction.h @@ -0,0 +1,91 @@ +// ------------------------------------------------------------------------- +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ------------------------------------------------------------------------- + +#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBTOHSVFUNCTION__H__ +#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBTOHSVFUNCTION__H__ + +#include +#include +#include + +#include +#include + +namespace cpPlugins +{ + namespace Extensions + { + namespace Algorithms + { + /** + */ + template< class O > + struct RGBToHSVFunction + { + typedef RGBToHSVFunction Self; + typedef itk::Vector< O, 3 > TOutPixel; + + template< class Tr, class Tg, class Tb > + TOutPixel operator()( const Tr& r, const Tg& g, const Tb& b ) const + { + static const double mVal = + double( std::numeric_limits< O >::max( ) ); + static const double _0 = double( 0 ); + static const double _1 = double( 1 ); + static const double _2 = double( 2 ); + static const double _3 = double( 3 ); + static const double _2pi = _2 * double( vnl_math::pi ); + + TOutPixel hsv; + + 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; + + // Hue + double A = std::sqrt( ( RG * RG ) + ( RB * GB ) ); + if( A != _0 ) + A = std::acos( ( RG + RB ) / ( _2 * A ) ); + A /= _2pi; + hsv[ 0 ] = O( mVal * ( ( G >= B )? A: _1 - A ) ); + + // Saturation + if( sRGB != _0 ) + { + double C = ( G < R )? G: R; + C = ( B < C )? B: C; + hsv[ 1 ] = O( mVal * ( _1 - ( ( _3 * C ) / sRGB ) ) ); + } + else + hsv[ 1 ] = O( 0 ); + + // Value + hsv[ 2 ] = O( sRGB / _3 ); + return( hsv ); + } + + template< class C > + TOutPixel operator()( const itk::RGBPixel< C >& rgb ) const + { + return( + this->operator()( + rgb.GetRed( ), rgb.GetGreen( ), rgb.GetBlue( ) + ) + ); + } + }; + + } // ecapseman + + } // ecapseman + +} // ecapseman + +#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBTOHSVFUNCTION__H__ + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/RGBToYPbPrFunction.h b/lib/cpPlugins/Extensions/Algorithms/RGBToYPbPrFunction.h new file mode 100644 index 0000000..def48e8 --- /dev/null +++ b/lib/cpPlugins/Extensions/Algorithms/RGBToYPbPrFunction.h @@ -0,0 +1,69 @@ +// ------------------------------------------------------------------------- +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ------------------------------------------------------------------------- + +#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBTOYPBPRFUNCTION__H__ +#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBTOYPBPRFUNCTION__H__ + +#include +#include +#include +#include + +#include +#include +#include + +namespace cpPlugins +{ + namespace Extensions + { + namespace Algorithms + { + /** + */ + template< class O > + struct RGBToYPbPrFunction + { + typedef RGBToYPbPrFunction Self; + typedef itk::Vector< O, 3 > TOutPixel; + + template< class Tr, class Tg, class Tb > + TOutPixel operator()( const Tr& r, const Tg& g, const Tb& b ) const + { + static const O M[] = + { + O( 0.2126 ), O( 0.7152 ), O( 0.0722 ), + O( -0.2126 ), O( -0.7152 ), O( 0.9278 ), + O( 0.7874 ), O( -0.7152 ), O( -0.0722 ) + }; + static const vnl_matrix< O > vM( M, 3, 3 ); + static const itk::Matrix< O, 3, 3 > iM( vM ); + + TOutPixel rgb; + rgb[ 0 ] = O( r ); + rgb[ 1 ] = O( g ); + rgb[ 2 ] = O( b ); + return( iM * rgb ); + } + + template< class C > + TOutPixel operator()( const itk::RGBPixel< C >& rgb ) const + { + return( + this->operator()( + rgb.GetRed( ), rgb.GetGreen( ), rgb.GetBlue( ) + ) + ); + } + }; + + } // ecapseman + + } // ecapseman + +} // ecapseman + +#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__RGBTOYPBPRFUNCTION__H__ + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Plugins/CMakeLists.txt b/lib/cpPlugins/Plugins/CMakeLists.txt index 7558bf4..7bf21b5 100644 --- a/lib/cpPlugins/Plugins/CMakeLists.txt +++ b/lib/cpPlugins/Plugins/CMakeLists.txt @@ -35,6 +35,7 @@ TARGET_LINK_LIBRARIES( ${ITK_LIBRARIES} ${VTK_LIBRARIES} vtkIOLegacy + ITKIOImageBase ) ## eof - $RCSfile$ diff --git a/lib/cpPlugins/Plugins/Host.cxx b/lib/cpPlugins/Plugins/Host.cxx index 8cffd6c..ad93e89 100644 --- a/lib/cpPlugins/Plugins/Host.cxx +++ b/lib/cpPlugins/Plugins/Host.cxx @@ -6,6 +6,7 @@ #include #include #include +#include /// TODO: doc PLUMA_CONNECTOR @@ -20,6 +21,7 @@ bool connect( pluma::Host& host ) host.add( new MeshReaderProvider( ) ); host.add( new PolyDataReaderProvider( ) ); host.add( new RGBImageToHSVChannelsFilterProvider( ) ); + host.add( new RGBImageToYPbPrChannelsFilterProvider( ) ); return( true ); } diff --git a/lib/cpPlugins/Plugins/RGBImageToHSVChannelsFilter.cxx b/lib/cpPlugins/Plugins/RGBImageToHSVChannelsFilter.cxx index 8985c61..166dfee 100644 --- a/lib/cpPlugins/Plugins/RGBImageToHSVChannelsFilter.cxx +++ b/lib/cpPlugins/Plugins/RGBImageToHSVChannelsFilter.cxx @@ -1,6 +1,7 @@ #include #include -#include +#include +#include #define ITK_MANUAL_INSTANTIATION #include @@ -18,7 +19,6 @@ ) \ r = this->f< p, d >( ) - // ------------------------------------------------------------------------- std::string cpPlugins::Plugins::RGBImageToHSVChannelsFilter:: GetClassName( ) const @@ -89,8 +89,9 @@ _GD1( ) { typedef itk::Image< itk::RGBPixel< P >, D > _TImage; typedef itk::Image< P, D > _TChannel; + typedef cpPlugins::Extensions::Algorithms::RGBToHSVFunction< P > _TFunction; typedef cpPlugins::Extensions::Algorithms:: - RGBImageToHSVChannelsFilter< _TImage, _TChannel > _TFilter; + RGBImageToOtherChannelsFilter< _TImage, _TChannel, _TFunction > _TFilter; // Filter creation _TFilter* filter = @@ -105,9 +106,9 @@ _GD1( ) filter->SetInput( dynamic_cast< _TImage* >( this->_GetInput( 0 ) ) ); filter->Update( ); - this->_SetOutput( 0, filter->GetHueOutput( ) ); - this->_SetOutput( 1, filter->GetSaturationOutput( ) ); - this->_SetOutput( 2, filter->GetValueOutput( ) ); + this->_SetOutput( 0, filter->GetChannel1( ) ); + this->_SetOutput( 1, filter->GetChannel2( ) ); + this->_SetOutput( 2, filter->GetChannel3( ) ); return( "" ); } diff --git a/lib/cpPlugins/Plugins/RGBImageToYPbPrChannelsFilter.cxx b/lib/cpPlugins/Plugins/RGBImageToYPbPrChannelsFilter.cxx new file mode 100644 index 0000000..85393b0 --- /dev/null +++ b/lib/cpPlugins/Plugins/RGBImageToYPbPrChannelsFilter.cxx @@ -0,0 +1,136 @@ +#include +#include +#include +#include + +#define ITK_MANUAL_INSTANTIATION +#include +#include + +// ------------------------------------------------------------------------- +#define cpPlugins_RGB2YPbPr_Dimension( r, d, o, f ) \ + if( dynamic_cast< itk::ImageBase< d >* >( o ) != NULL ) \ + r = this->f< d >( ) + +// ------------------------------------------------------------------------- +#define cpPlugins_RGB2YPbPr_RGB( r, p, d, o, f ) \ + if( \ + dynamic_cast< itk::Image< itk::RGBPixel< p >, d >* >( o ) != NULL \ + ) \ + r = this->f< p, d >( ) + +// ------------------------------------------------------------------------- +std::string cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter:: +GetClassName( ) const +{ + return( "cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter" ); +} + +// ------------------------------------------------------------------------- +cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter:: +RGBImageToYPbPrChannelsFilter( ) + : Superclass( ) +{ + this->SetNumberOfInputs( 1 ); + this->SetNumberOfOutputs( 3 ); + this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_MakeOutput< cpPlugins::Interface::Image >( 1 ); + this->_MakeOutput< cpPlugins::Interface::Image >( 2 ); + + using namespace cpPlugins::Interface; + this->m_DefaultParameters.Configure( Parameters::String, "OutputPixelType" ); + this->m_DefaultParameters.SetValueAsString( "PixelType", "float" ); + this->m_Parameters = this->m_DefaultParameters; +} + +// ------------------------------------------------------------------------- +cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter:: +~RGBImageToYPbPrChannelsFilter( ) +{ +} + +// ------------------------------------------------------------------------- +std::string cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter:: +_GenerateData( ) +{ + itk::DataObject* o = this->_GetInput( 0 ); + + std::string r = "cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter: itk::Image dimension not supported."; + cpPlugins_RGB2YPbPr_Dimension( r, 1, o, _GD0 ); + else cpPlugins_RGB2YPbPr_Dimension( r, 2, o, _GD0 ); + else cpPlugins_RGB2YPbPr_Dimension( r, 3, o, _GD0 ); + else cpPlugins_RGB2YPbPr_Dimension( r, 4, o, _GD0 ); + return( r ); +} + +// ------------------------------------------------------------------------- +template< unsigned int D > +std::string cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter:: +_GD0( ) +{ + itk::ImageBase< D >* i = + dynamic_cast< itk::ImageBase< D >* >( this->_GetInput( 0 ) ); + + std::string r = "cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter: itk::Image pixel type not supported"; + cpPlugins_RGB2YPbPr_RGB( r, char, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, short, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, int, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, long, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, unsigned char, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, unsigned short, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, unsigned int, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, unsigned long, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, float, D, i, _GD1 ); + else cpPlugins_RGB2YPbPr_RGB( r, double, D, i, _GD1 ); + return( r ); +} + +// ------------------------------------------------------------------------- +template< class P, unsigned int D > +std::string cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter:: +_GD1( ) +{ + using namespace cpPlugins::Interface; + Parameters::TString pt = + this->m_Parameters.GetValueAsString( "OutputPixelType" ); + + std::string r = "cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter: itk::Image output pixel type not supported"; + if( pt == "float" ) + r = this->_GD2< P, float, D >( ); + else if( pt == "double" ) + r = this->_GD2< P, double, D >( ); + return( r ); +} + +// ------------------------------------------------------------------------- +template< class P, class O, unsigned int D > +std::string cpPlugins::Plugins::RGBImageToYPbPrChannelsFilter:: +_GD2( ) +{ + typedef itk::Image< itk::RGBPixel< P >, D > _TImage; + typedef itk::Image< O, D > _TChannel; + typedef cpPlugins::Extensions::Algorithms::RGBToYPbPrFunction< O > _TFunction; + typedef cpPlugins::Extensions::Algorithms:: + RGBImageToOtherChannelsFilter< _TImage, _TChannel, _TFunction > _TFilter; + + // Filter creation + _TFilter* filter = + dynamic_cast< _TFilter* >( this->m_RealProcessObject.GetPointer( ) ); + if( filter == NULL ) + { + this->m_RealProcessObject = _TFilter::New( ); + filter = + dynamic_cast< _TFilter* >( this->m_RealProcessObject.GetPointer( ) ); + + } // fi + filter->SetInput( dynamic_cast< _TImage* >( this->_GetInput( 0 ) ) ); + filter->Update( ); + + this->_SetOutput( 0, filter->GetChannel1( ) ); + this->_SetOutput( 1, filter->GetChannel2( ) ); + this->_SetOutput( 2, filter->GetChannel3( ) ); + + return( "" ); +} + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Plugins/RGBImageToYPbPrChannelsFilter.h b/lib/cpPlugins/Plugins/RGBImageToYPbPrChannelsFilter.h new file mode 100644 index 0000000..eb9c461 --- /dev/null +++ b/lib/cpPlugins/Plugins/RGBImageToYPbPrChannelsFilter.h @@ -0,0 +1,62 @@ +#ifndef __CPPLUGINS__PLUGINS__RGBIMAGETOYPBPRCHANNELSFILTER__H__ +#define __CPPLUGINS__PLUGINS__RGBIMAGETOYPBPRCHANNELSFILTER__H__ + +#include +#include + +namespace cpPlugins +{ + namespace Plugins + { + /** + */ + class cpPlugins_EXPORT RGBImageToYPbPrChannelsFilter + : public cpPlugins::Interface::ImageToImageFilter + { + public: + typedef RGBImageToYPbPrChannelsFilter Self; + typedef cpPlugins::Interface::ImageToImageFilter Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + public: + itkNewMacro( Self ); + itkTypeMacro( + RGBImageToYPbPrChannelsFilter, + cpPluginsInterfaceImageToImageFilter + ); + + public: + virtual std::string GetClassName( ) const; + + protected: + RGBImageToYPbPrChannelsFilter( ); + virtual ~RGBImageToYPbPrChannelsFilter( ); + + virtual std::string _GenerateData( ); + + template< unsigned int D > + std::string _GD0( ); + + template< class P, unsigned int D > + std::string _GD1( ); + + template< class P, class O, unsigned int D > + std::string _GD2( ); + + private: + // Purposely not implemented + RGBImageToYPbPrChannelsFilter( const Self& ); + Self& operator=( const Self& ); + }; + + // --------------------------------------------------------------------- + CPPLUGINS_INHERIT_PROVIDER( RGBImageToYPbPrChannelsFilter ); + + } // ecapseman + +} // ecapseman + +#endif // __CPPLUGINS__PLUGINS__RGBIMAGETOYPBPRCHANNELSFILTER__H__ + +// eof - $RCSfile$ -- 2.47.1