--- /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$