00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_FUN_V2V_RGB_TO_HSI_HH
00027 # define MLN_FUN_V2V_RGB_TO_HSI_HH
00028
00029 #include <cmath>
00030
00031 #include <mln/value/rgb8.hh>
00032 #include <mln/math/round.hh>
00033
00034 #include <mln/value/hsi.hh>
00035
00036
00037 namespace mln
00038 {
00039
00040
00041 namespace fun
00042 {
00043
00044 namespace v2v
00045 {
00046
00047 template <typename T_hsi>
00048 struct f_rgb_to_hsi_ : public Function_v2v< f_rgb_to_hsi_<T_hsi> >
00049 {
00050 typedef T_hsi result;
00051
00052 template <typename T_rgb>
00053 T_hsi operator()(const T_rgb& rgb) const;
00054
00055 };
00056
00057 typedef f_rgb_to_hsi_<value::hsi_f> f_rgb_to_hsi_f_t;
00058
00059 extern f_rgb_to_hsi_f_t f_rgb_to_hsi_f;
00060
00061
00062 # ifndef MLN_INCLUDE_ONLY
00063
00066 f_rgb_to_hsi_f_t f_rgb_to_hsi_f;
00068
00069
00070 template <typename T_hsi>
00071 template <typename T_rgb>
00072 inline
00073 T_hsi
00074 f_rgb_to_hsi_<T_hsi>::operator()(const T_rgb& rgb) const
00075 {
00076
00077 static const double sqrt3_3 = std::sqrt(3) / 3;
00078 static const double inv_sqrt6 = 1 / std::sqrt(6);
00079 static const double inv_sqrt2 = 1 / std::sqrt(2);
00080
00081 T_hsi hsi;
00082
00083 double alpha = inv_sqrt2 * rgb.green() - inv_sqrt2 * rgb.blue();
00084 double beta =
00085 2 * inv_sqrt6 * rgb.red() -
00086 inv_sqrt6 * rgb.green() -
00087 inv_sqrt6 * rgb.blue();
00088
00089
00090 hsi.hue() = atan2(beta, alpha) / 3.1415 * 180.0;
00091 if (hsi.hue() < 0)
00092 hsi.hue() = hsi.hue() + 360.0;
00093 mln_invariant(hsi.hue() >= 0);
00094 hsi.sat() = std::sqrt(alpha * alpha + beta * beta);
00095 hsi.inty() =
00096 sqrt3_3 * rgb.red() +
00097 sqrt3_3 * rgb.green() +
00098 sqrt3_3 * rgb.blue();
00099
00100 return hsi;
00101 }
00102
00103
00104 # endif // !MLN_INCLUDE_ONLY
00105
00106 }
00107
00108 }
00109
00110 }
00111
00112 #endif // ! MLN_FUN_V2V_RGB_TO_HSI_HH