// ------------------------------------------------------------------------- // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) // ------------------------------------------------------------------------- #ifndef __cpExtensions__Algorithms__RGBToSingleChannelFunctor__hxx__ #define __cpExtensions__Algorithms__RGBToSingleChannelFunctor__hxx__ #include #include #include // ------------------------------------------------------------------------- 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$