URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2008-05-06 Caroline Vigouroux <vigour_c(a)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