
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2008-05-06 Caroline Vigouroux <vigour_c@epita.fr> Add new conversion functions. * conv/rgbto.hh, conv/torgb.hh: New conversions functions. * conv/test.cc: New test on conversions. * conv: New folder. --- rgbto.hh | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test.cc | 33 +++++++++++++ torgb.hh | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 322 insertions(+) Index: trunk/milena/sandbox/vigouroux/conv/test.cc =================================================================== --- trunk/milena/sandbox/vigouroux/conv/test.cc (revision 0) +++ trunk/milena/sandbox/vigouroux/conv/test.cc (revision 1924) @@ -0,0 +1,33 @@ +#include "rgbto.hh" +#include "../color/rgb_to_hsi.hh" +#include "rgbto.hh" +#include "torgb.hh" + +#include <cmath> + +#include <mln/core/image2d.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/math/round.hh> +#include <mln/level/transform.hh> + + +int main(void) +{ +// mln::value::cmy_<float, float, float> cmy(0, 0, 0); +// mln::value::rgb<8> rgb; + +// rgb = mln::fun::v2v::f_rgb_to_< mln::value::cmy_<float, float, float> >(cmy); + using namespace mln; + + image2d<value::rgb8> lena; + io::ppm::load(lena, "../../../img/lena.ppm"); + + image2d<value::hsi_f> lena_hsi = + level::transform(lena, fun::v2v::f_rgb_to_<value::hsi_f> ()); + + image2d<value::rgb8> lena_rgb = + level::transform(lena_hsi, fun::v2v::f_to_rgb_< value::rgb<8> > ()); +} + Index: trunk/milena/sandbox/vigouroux/conv/torgb.hh =================================================================== --- trunk/milena/sandbox/vigouroux/conv/torgb.hh (revision 0) +++ trunk/milena/sandbox/vigouroux/conv/torgb.hh (revision 1924) @@ -0,0 +1,140 @@ +#include <cmath> + +#include <mln/core/image_if_value.hh> +#include <mln/core/inplace.hh> +#include <mln/core/w_window2d_int.hh> +#include <mln/display/show.hh> +#include <mln/io/ppm/save.hh> +#include <mln/display/save_and_show.hh> +#include <mln/level/fill.hh> +#include <mln/value/int_u.hh> +#include <mln/math/round.hh> + +#include "../cmy/my_cmy.hh" +#include "../hsi/my_hsi.hh" +#include "../xyz/my_xyz.hh" +#include "../yiq/my_yiq.hh" +#include "../yuv/my_yuv.hh" + +#ifndef MLN_TO_RGB_HH +# define MLN_TO_RGB_HH + +namespace later +{ + template <typename T> + struct red; +} + +namespace mln +{ + + namespace fun + { + + namespace v2v + { + template <typename T_rgb> + struct f_to_rgb_ : public Function_v2v< f_to_rgb_<T_rgb> > + { + typedef T_rgb result; + + template <typename T> + T_rgb operator()(const value::cmy_<T, T, T>& color) const + { + int red; + int green; + int blue; + + red = int(1 - color.cyan()); + green = int(1 - color.magenta()); + blue = int(1 - color.yellow()); + T_rgb rgb(red, green, blue); + + return rgb; + } + + template <typename T> + T_rgb operator()(const value::hsi_<T, T, T>& color) const + { + typedef typename T_rgb::red_t red_t; + typedef typename T_rgb::green_t green_t; + typedef typename T_rgb::blue_t blue_t; + + static math::round<red_t> to_r; + static math::round<green_t> to_g; + static math::round<blue_t> to_b; + + static const float + sqrt3_3 = std::sqrt(3) / 3, + inv_sqrt6 = 1 / std::sqrt(6), + inv_sqrt2 = 1 / std::sqrt(2); + + float + h = color.hue() / 180.0 * 3.1415, + alpha = color.sat() * std::cos(h), + beta = color.sat() * std::sin(h); + + red_t r = sqrt3_3 * color.inty() + 2 * inv_sqrt6 * beta; + green_t g = sqrt3_3 * color.inty() + inv_sqrt2 * alpha - inv_sqrt6 * beta; + blue_t b = sqrt3_3 * color.inty() - inv_sqrt2 * alpha - inv_sqrt6 * beta; + + T_rgb rgb(r, g, b); + + return rgb; + } + + template <typename T> + T_rgb operator()(const value::xyz_<T, T, T>& color) const + { + int r; + int g; + int b; + + r = int(2.365 * color.x() - 0.896 * color.y() - 0.468 * color.z()); + g = int(-0.515 * color.x() + 1.425 * color.y() + 0.089 * color.z()); + b = int(0.005 * color.x() - 0.014 * color.y() + 1.01 * color.z()); + + struct value::rgb<8> rgb(r, g, b); + + return rgb; + } + + template <typename T> + T_rgb operator()(const value::yuv_<T, T, T>& color) const + { + int r; + int g; + int b; + + r = int(color.y() + 1.13983 * color.v()); + g = int(color.y() - 0.39465 * color.u() - 0.58060 * color.v()); + b = int(color.y() + 2.03211 * color.u()); + + struct value::rgb<8> rgb(r, g, b); + + return (rgb); + } + + template <typename T> + T_rgb operator()(const value::yiq_<T, T, T>& color) const + { + int r; + int g; + int b; + + r = int(0.87 * color.y() + 1.3223 * color.i() + 0.5628 * color.q()); + g = int(1.026 * color.y() - 0.2718 * color.i() - 0.1458 * color.q()); + b = int(1.186 * color.y() - 1.2620 * color.i() + 1.8795 * color.q()); + + struct value::rgb<8> rgb(r, g, b); + + return rgb; + } + + + }; + } + } +} + +#endif // ! MLN_TO_RGB_HH Index: trunk/milena/sandbox/vigouroux/conv/rgbto.hh =================================================================== --- trunk/milena/sandbox/vigouroux/conv/rgbto.hh (revision 0) +++ trunk/milena/sandbox/vigouroux/conv/rgbto.hh (revision 1924) @@ -0,0 +1,149 @@ +#include <cmath> + +#include <mln/core/image_if_value.hh> +#include <mln/core/inplace.hh> +#include <mln/core/w_window2d_int.hh> +#include <mln/display/show.hh> +#include <mln/io/ppm/save.hh> +#include <mln/display/save_and_show.hh> +#include <mln/level/fill.hh> +#include <mln/value/int_u.hh> +#include <mln/math/round.hh> + +#include "../cmy/my_cmy.hh" +#include "../hsi/my_hsi.hh" +#include "../xyz/my_xyz.hh" +#include "../yiq/my_yiq.hh" +#include "../yuv/my_yuv.hh" + +#ifndef MLN_RGB_TO_CMY_HH +# define MLN_RGB_TO_CMY_HH + +namespace later +{ + template <typename T> + struct red; +} + +namespace mln +{ + + namespace fun + { + + namespace v2v + { + template <typename T> + struct f_rgb_to_ : public Function_v2v< f_rgb_to_<T> > + { + typedef typename later::red<T>::result result; + + template <typename T_rgb> + result operator()(const T_rgb& rgb) const + { + return later::red<T>::on(rgb); + } + }; + } + } +} + +namespace later +{ + template <typename T> + struct red< mln::value::cmy_<T, T, T> > + { + typedef mln::value::cmy_<T, T, T> result; + static result on(const mln::value::rgb<8>& rgb) + { + result cmy; + + cmy.cyan() = 1 - rgb.red(); + cmy.magenta() = 1 - rgb.green(); + cmy.yellow() = 1 - rgb.blue(); + + return cmy; + } + }; + + template <typename T> + struct red< mln::value::hsi_<T, T, T> > + { + typedef mln::value::hsi_<T, T, T> result; + static result on(const mln::value::rgb<8>& rgb) + { + static const double sqrt3_3 = std::sqrt(3) / 3; + static const double inv_sqrt6 = 1 / std::sqrt(6); + static const double inv_sqrt2 = 1 / std::sqrt(2); + + result hsi; + + double alpha = inv_sqrt2 * rgb.green() - inv_sqrt2 * rgb.blue(); + double beta = 2 * inv_sqrt6 * rgb.red() - inv_sqrt6 * rgb.green() - inv_sqrt6 * rgb.blue(); + + + float tmp = atan2(beta, alpha) / 3.1415 * 180.0; + + hsi.hue() = atan2(beta, alpha) / 3.1415 * 180.0; + if (hsi.hue() < 0) + hsi.hue() = hsi.hue() + 360.0; + mln_invariant(hsi.hue() >= 0); + hsi.sat() = std::sqrt(alpha * alpha + beta * beta); + hsi.inty() = sqrt3_3 * rgb.red() + sqrt3_3 * rgb.green() + sqrt3_3 * rgb.blue(); + + return hsi; + } + }; + + template <typename T> + struct red< mln::value::xyz_<T, T, T> > + { + typedef mln::value::xyz_<T, T, T> result; + static result on(const mln::value::rgb<8>& rgb) + { + result xyz; + + xyz.x() = 0.490 * rgb.red() + 0.310 * rgb.green() + 0.200 * rgb.blue(); + xyz.y() = 0.177 * rgb.red() + 0.812 * rgb.green() + 0.011 * rgb.blue(); + xyz.z() = 0.010 * rgb.green() + 0.990 * rgb.blue(); + + return xyz; + } + }; + + template <typename T> + struct red< mln::value::yiq_<T, T, T> > + { + typedef mln::value::yiq_<T, T, T> result; + static result on(const mln::value::rgb<8>& rgb) + { + result yiq; + + yiq.y() = 0.1768 * rgb.red() + 0.8130 * rgb.green() + 0.0101 * rgb.blue(); + yiq.i() = 0.5346 * rgb.red() - 0.2461 * rgb.green() - 0.1791 * rgb.blue(); + yiq.q() = 0.2474 * rgb.red() - 0.6783 * rgb.green() + 0.4053 * rgb.blue(); + + return yiq; + } + }; + + template <typename T> + struct red< mln::value::yuv_<T, T, T> > + { + typedef mln::value::yuv_<T, T, T> result; + static result on(const mln::value::rgb<8>& rgb) + { + result yuv; + + yuv.y() = 0.299 * rgb.red() + 0.587 * rgb.green() + 0.114 * rgb.blue(); + yuv.u() = 0.436 * (rgb.blue() - yuv.y()) / (1 - 0.114); + yuv.v() = 0.615 * (rgb.red() - yuv.y()) / (1 - 0.299); + + return yuv; + } + }; + +} + + +#endif // ! MLN_RGB_TO_CMY_HH