// ------------------------------------------------------------------------- // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) // ------------------------------------------------------------------------- #ifndef __CPEXTENSIONS__ALGORITHMS__RGBTOHSVFUNCTION__H__ #define __CPEXTENSIONS__ALGORITHMS__RGBTOHSVFUNCTION__H__ #include #include #include #include namespace cpExtensions { namespace Algorithms { /** */ template< class P > struct RGBToHSVFunction { typedef RGBToHSVFunction Self; typedef P TOutPixel; typedef typename P::ValueType TValue; template< class Tr, class Tg, class Tb > P operator()( const Tr& r, const Tg& g, const Tb& b ) const { static const double mVal = double( std::numeric_limits< TValue >::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 ); P 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 ] = TValue( mVal * ( ( G >= B )? A: _1 - A ) ); // Saturation if( sRGB != _0 ) { double C = ( G < R )? G: R; C = ( B < C )? B: C; hsv[ 1 ] = TValue( mVal * ( _1 - ( ( _3 * C ) / sRGB ) ) ); } else hsv[ 1 ] = TValue( 0 ); // Value hsv[ 2 ] = TValue( 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 #endif // __CPEXTENSIONS__ALGORITHMS__RGBTOHSVFUNCTION__H__ // eof - $RCSfile$