milena r3856: HSV type, HSL <-> HSV conversions, and tests

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2009-05-19 Etienne FOLIO <folio@lrde.epita.fr> HSV type, HSL <-> HSV conversions, and tests. * sandbox/folio/mln/fun/v2v/hsl_to_hsv.hh: New algorithms. * sandbox/folio/mln/fun/v2v/rgb_to_hsv.hh: float -> float01_<n>. * sandbox/folio/mln/histo/compute_histo_3d.hh: Some corrections. * sandbox/folio/mln/value/hsv.hh: HSV value type. * sandbox/folio/test/histo/plot_lena.cc: New test. * sandbox/folio/test/histo/plot_lena_3d.cc: New test. * sandbox/folio/test/histo/plot_lena_rgb.cc: New test. * sandbox/folio/test/histo/projected.cc: New test. * sandbox/folio/test/histo/projected3d.cc: New test. * sandbox/folio/test/value/circular.cc: test. * sandbox/folio/test/value/hsv.cc: test. --- mln/fun/v2v/hsl_to_hsv.hh | 141 ++++++++++++++++++++++++++++++++++++++++++ mln/fun/v2v/rgb_to_hsv.hh | 14 +++- mln/histo/compute_histo_3d.hh | 24 +++---- mln/value/hsv.hh | 20 ++--- test/histo/plot_lena.cc | 55 ++++++++++++++++ test/histo/plot_lena_3d.cc | 63 ++++++++++++++++++ test/histo/plot_lena_rgb.cc | 56 ++++++++++++++++ test/histo/projected.cc | 49 ++++++++++++++ test/histo/projected3d.cc | 99 +++++++++++++++++++++++++++++ test/value/circular.cc | 113 ++++++++++++++++++++++----------- test/value/hsv.cc | 27 +++++++- 11 files changed, 595 insertions(+), 66 deletions(-) Index: trunk/milena/sandbox/folio/test/histo/plot_lena.cc =================================================================== --- trunk/milena/sandbox/folio/test/histo/plot_lena.cc (revision 0) +++ trunk/milena/sandbox/folio/test/histo/plot_lena.cc (revision 3856) @@ -0,0 +1,55 @@ +#include <iostream> +#include <mln/debug/println.hh> +#include <mln/literal/all.hh> + +#include <mln/io/pgm/load.hh> +#include <mln/value/int_u8.hh> + +#include "../../mln/histo/compute_histo_rgb.hh" + +namespace mln +{ + namespace histo + { + + template <typename T> + image1d<unsigned> compute_histo_gs(image2d<T> ima) + { + typedef mln_trait_value_comp(T, 0)::enc enc; // -> int_u8 + + // New histogram-image + image1d<unsigned> out(box1d(point1d(mln_min(enc)), // -> 0 + point1d(mln_max(enc)))); // -> 255 + data::fill(out, 0); + + // Compute histogram + mln_fwd_piter(image2d<T>) p(ima.domain()); + for_all(p) + ++out(point1d(ima(p))); + + return out; + } + + } +} + +int main(int argc, char* argv[]) +{ + using namespace mln; + using namespace mln::value; + + // build test image + std::cout << " => loading " << argv[1] << "..." << std::endl; + image2d<int_u8>ima; + io::pgm::load(ima, argv[1]); + + std::cout << " => computing histo..." << std::endl; + image1d<unsigned> out = histo::compute_histo_gs(ima); + + typedef image1d<int_u8> I; + + mln_piter_(I) p(out.domain()); + unsigned i = 0; + for_all(p) + std::cout << i++ << " " << out(p) << std::endl; +} Index: trunk/milena/sandbox/folio/test/histo/projected.cc =================================================================== --- trunk/milena/sandbox/folio/test/histo/projected.cc (revision 0) +++ trunk/milena/sandbox/folio/test/histo/projected.cc (revision 3856) @@ -0,0 +1,49 @@ +#include <iostream> +#include <mln/debug/println.hh> +#include <mln/literal/all.hh> + +#include "../../mln/histo/compute_histo_rgb.hh" + +int main() +{ + using namespace mln; + + // build test image + image2d<value::rgb8> ima(10, 10); + + value::rgb8 red = literal::red; + value::rgb8 green = literal::green; + value::rgb8 black = literal::black; + + for (unsigned i = 0; i < 10; ++i) + for (unsigned j = 5; j < 10; ++j) + { + point2d p(j, i); + ima(p) = black; + } + + for (unsigned i = 0; i < 10; ++i) + for (unsigned j = 0; j < 5; ++j) + { + point2d p(j, i); + ima(p) = red; + } + + point2d p(8, 2); + ima(p) = green; + + std::cout << "input :" << std::endl; + debug::println(ima); + + // let's run ! + image3d<value::int_u8> out = histo::compute_histo_rgb<value::int_u8>(ima); + + // output ? + // std::cout << "out(0, 0, 0) = " << out(point3d(0, 0, 0)) << std::endl; + // std::cout << "out(255, 0, 0) = " << out(point3d(255, 0, 0)) << std::endl; + // std::cout << "out(0, 255, 0) = " << out(point3d(0, 255, 0)) << std::endl; + + + + return 0; +} Index: trunk/milena/sandbox/folio/test/histo/plot_lena_3d.cc =================================================================== --- trunk/milena/sandbox/folio/test/histo/plot_lena_3d.cc (revision 0) +++ trunk/milena/sandbox/folio/test/histo/plot_lena_3d.cc (revision 3856) @@ -0,0 +1,63 @@ +#include <iostream> +#include <mln/debug/println.hh> +#include <mln/literal/all.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/value/int_u8.hh> +#include <mln/value/rgb8.hh> + +//#include "../../mln/histo/compute_histo_rgb.hh" + +namespace mln +{ + namespace histo + { + + template <typename T> + image3d<unsigned> + compute_histo_3d(image2d<T> ima) + { + typedef mln_trait_value_comp(T, 0)::enc enc_0; // R -> int_u8 + typedef mln_trait_value_comp(T, 1)::enc enc_1; // G -> int_u8 + typedef mln_trait_value_comp(T, 2)::enc enc_2; // B -> int_u8 + + // New histogram-image + image3d<unsigned> out(box3d(point3d(mln_min(enc_0), // -> 0 + mln_min(enc_1), // -> 0 + mln_min(enc_2)), // -> 0 + point3d(mln_max(enc_0), // -> 255 + mln_max(enc_1), // -> 255 + mln_max(enc_2)))); // -> 255 + data::fill(out, 0); + + // Compute histogram + mln_fwd_piter(image2d<T>) p(ima.domain()); + for_all(p) + ++out(point3d(ima(p).comp(0), ima(p).comp(1), ima(p).comp(2))); + + return out; + } + + } +} + +int main(int argc, char* argv[]) +{ + using namespace mln; + using namespace mln::value; + + // build test image + std::cout << " => loading " << argv[1] << "..." << std::endl; + image2d<rgb8>ima; + io::ppm::load(ima, argv[1]); + + std::cout << " => computing histo..." << std::endl; + image3d<unsigned> out = histo::compute_histo_3d(ima); + + typedef image3d<rgb8> I; + mln_piter_(I) p(out.domain()); + unsigned i, j, k = 0; + for_all(p) + i += out(p); + std::cout << i << std::endl; +} Index: trunk/milena/sandbox/folio/test/histo/projected3d.cc =================================================================== --- trunk/milena/sandbox/folio/test/histo/projected3d.cc (revision 0) +++ trunk/milena/sandbox/folio/test/histo/projected3d.cc (revision 3856) @@ -0,0 +1,99 @@ +#include <mln/core/var.hh> + +#include <mln/core/image/image1d.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/image/unproject_image.hh> +#include <mln/fun/v2v/projection.hh> + +#include <mln/core/image/image_if.hh> +#include <mln/pw/value.hh> +#include <mln/level/transform.hh> + +#include <mln/arith/revert.hh> +#include <mln/core/alias/neighb3d.hh> +#include <mln/value/label_8.hh> + +#include <mln/morpho/closing/volume.hh> +#include <mln/morpho/watershed/flooding.hh> +#include <mln/morpho/elementary/dilation.hh> + +#include "../../mln/histo/compute_histo_rgb.hh" +#include "../../mln/histo/classify_with_histo_rgb.hh" + +#include <mln/accu/count.hh> +#include <mln/accu/mean.hh> +#include <mln/accu/image/init.hh> +#include <mln/accu/image/take.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/debug/println.hh> + +namespace mln +{ + struct rgb8to6 : Function_v2v< rgb8to6 > + { + typedef value::rgb<6> result; + value::rgb<6> operator()(const value::rgb<8>& c) const + { + value::rgb<6> res(c.red() / 4, c.green() / 4, c.blue() / 4); + return res; + } + }; +} + +int main(int argc, char* argv[]) +{ + if (argc != 3) + { + std::cout << "Usage:" << std::endl + << "./a.out <ima_in> <ima_out>" << std::endl; + } + + using namespace mln; + + using value::int_u8; + typedef value::rgb<6> rgb6; + typedef value::int_u<6> int_u6; + + std::cout << " => loading " << argv[1] << "..." << std::endl; + image2d<value::rgb8> ima; + io::ppm::load(ima, argv[1]); + image2d<rgb6> ima6 = level::transform(ima, rgb8to6()); + + std::cout << " => computing histogram..." << std::endl; + image3d<unsigned> histo = histo::compute_histo_rgb<unsigned>(ima6); + + std::cout << " => computing reverted histogram..." << std::endl; + image3d<unsigned> reverted = arith::revert(histo); + + std::cout << " => computing closure..." << std::endl; + image3d<unsigned> closed = + morpho::closing::volume(reverted, c6(), atoi(argv[2])); + + std::cout << " => computing watershed..." << std::endl; + value::label_8 nbasin; + image3d<value::label_8> labels = + morpho::watershed::flooding(closed, c6(), nbasin); + std::cout << "found " << nbasin << " labels" << std::endl; + + labels = morpho::elementary::dilation(labels, c18()); + + std::cout << " => computing output labelized image..." << std::endl; + image2d<value::label_8> lab = histo::classify_with_histo_rgb(ima, labels); + + std::cout << " => computing projection..." << std::endl; + typedef accu::mean<int_u8, unsigned, int_u8> A; + + image2d<A> vmean(lab.nrows(), lab.ncols()); + accu::image::init(vmean); + { + fun::v2v::projection<point3d, 0> vproj; + mln_VAR( vmean_, unproject(vmean, lab.domain(), vproj) ); + accu::image::take(vmean_, lab); + } + + std::cout << " => saving " << argv[2] << "..." << std::endl; + io::ppm::save(vmean, argv[2]); + +} Index: trunk/milena/sandbox/folio/test/histo/plot_lena_rgb.cc =================================================================== --- trunk/milena/sandbox/folio/test/histo/plot_lena_rgb.cc (revision 0) +++ trunk/milena/sandbox/folio/test/histo/plot_lena_rgb.cc (revision 3856) @@ -0,0 +1,56 @@ +#include <iostream> +#include <mln/debug/println.hh> +#include <mln/literal/all.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/value/int_u8.hh> + +#include "../../mln/histo/compute_histo_rgb.hh" + +#include <vector> + +int main(int argc, char* argv[]) +{ + using namespace mln; + using namespace mln::value; + + // build test image + std::cout << " => loading " << argv[1] << "..." << std::endl; + image2d<rgb8>ima; + io::ppm::load(ima, argv[1]); + + std::cout << " => computing histo..." << std::endl; +// image3d<int_u8> out = histo::compute_histo_rgb<value::int_u8>(ima); + std::vector<unsigned> red(256, 0); + std::vector<unsigned> green(256, 0); + std::vector<unsigned> blue(256, 0); + mln_fwd_piter_(image2d<rgb8>) p(ima.domain()); + for_all(p) + { + ++red[ima(p).red()]; + ++green[ima(p).green()]; + ++blue[ima(p).blue()]; + } + + for (unsigned i = 0; i < 256; ++i) + { + // unsigned acc0 = 0; + // for (unsigned j = 0; j < 256; ++j) + // for (unsigned k = 0; k < 256; ++k) + // acc0 += out(point3d(i, j, k)); + // unsigned acc1 = 0; + // for (unsigned j = 0; j < 256; ++j) + // for (unsigned k = 0; k < 256; ++k) + // acc1 += out(point3d(j, i, k)); + // unsigned acc2 = 0; + // for (unsigned j = 0; j < 256; ++j) + // for (unsigned k = 0; k < 256; ++k) + // acc2 += out(point3d(j, k, i)); + // std::cout << i << " " << acc0 << " " << acc1 << " " << acc2 << std::endl; + std::cout << i << " " + << red[i] << " " + << green[i] << " " + << blue[i] << std::endl; + } + +} Index: trunk/milena/sandbox/folio/test/value/hsv.cc =================================================================== --- trunk/milena/sandbox/folio/test/value/hsv.cc (revision 3855) +++ trunk/milena/sandbox/folio/test/value/hsv.cc (revision 3856) @@ -1,13 +1,34 @@ +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/debug/println.hh> +#include <mln/level/transform.hh> #include <mln/core/image/image2d.hh> -#include "../../mln/value/hsv.hh" +#include "../../mln/fun/v2v/rgb_to_hsv.hh" #include "../../mln/value/circular.hh" -int main() +int main(int argc, char* argv[]) { using namespace mln; using namespace mln::value; - image2d< hsv_< circular<16, 0, 360>, float, float > > ima; + if (argc != 3) + { + std::cout << "Usage:" << std::endl + << "./a.out <ima_in> <ima_out>" << std::endl; + } + + + std::cout << " => loading " << argv[1] << "..." << std::endl; + image2d<value::rgb8> ima; + io::ppm::load(ima, argv[1]); + + image2d<hsv_16f> hsv = level::transform(ima, + fun::v2v::f_rgb_to_hsv_16f); + ima = level::transform(hsv, + fun::v2v::f_hsv_to_rgb_8f); + + std::cout << " => saving " << argv[2] << "..." << std::endl; + io::ppm::save(ima, argv[2]); } Index: trunk/milena/sandbox/folio/test/value/circular.cc =================================================================== --- trunk/milena/sandbox/folio/test/value/circular.cc (revision 3855) +++ trunk/milena/sandbox/folio/test/value/circular.cc (revision 3856) @@ -4,45 +4,86 @@ #include "../../mln/value/circular.hh" +template <typename T> +class DistFct +{ + int_u8 operator()(const value::rg8& a, const value::rg8& b) + { + return a; + } +}; + + +template <typename T, typename N, typename D> +image2d<value::int_u8> +dist_on_pixels(const image2d<T>& input, const N& nbh, + const D& dist) +{ + using value::int_u8; + image2d<int_u8> output(input.domain()); + + mln_piter(box2d) p(input.domain()); + mln_niter(N) n(nbh, p); + for_all(p) + { + int_u8 d = 0u; + for_all(n) if (input.domain().has(n)) + { + int_u8 d_ = dist(input(p), input(n)); + if (d_ > d) + d = d_; + } + output(p) = d; + } + + io::pgm::save(output, "temp_dist.pgm"); + + return output; +} + + int main() { using namespace mln; using namespace mln::value; - circular<12, 0, 360> inter(21); - std::cout << "21: " << inter << " " << float(inter) << std::endl; - inter = 0; - std::cout << "0: " << inter << std::endl; - inter = 42; - std::cout << "42: " << inter << std::endl; - inter = 359; - std::cout << "359: " << inter << std::endl; - inter = 359.5; - std::cout << "359.5: " << inter << std::endl; - inter = 360; - std::cout << "360: " << inter << std::endl; - inter = 360.5; - std::cout << "360.5: " << inter << std::endl; - inter = 361; - std::cout << "361: " << inter << std::endl; - inter = 372; - std::cout << "372: " << inter << std::endl; - inter = 972; - std::cout << "972: " << inter << std::endl; - inter = -0.2; - std::cout << "-0.2: " << inter << std::endl; - inter = -1; - std::cout << "-1: " << inter << std::endl; - inter = -1; - std::cout << "-1: " << inter << std::endl; - inter = -359; - std::cout << "-359: " << inter << std::endl; - inter = -359.5; - std::cout << "-359.5: " << inter << std::endl; - inter = -360; - std::cout << "-360: " << inter << std::endl; - inter = -360.5; - std::cout << "-360.5: " << inter << std::endl; - inter = -361; - std::cout << "-361: " << inter << std::endl; + // circular<12, 0, 360> inter(21); + // std::cout << "21: " << inter << " " << float(inter) << std::endl; + // inter = 0; + // std::cout << "0: " << inter << std::endl; + // inter = 42; + // std::cout << "42: " << inter << std::endl; + // inter = 359; + // std::cout << "359: " << inter << std::endl; + // inter = 359.5; + // std::cout << "359.5: " << inter << std::endl; + // inter = 360; + // std::cout << "360: " << inter << std::endl; + // inter = 360.5; + // std::cout << "360.5: " << inter << std::endl; + // inter = 361; + // std::cout << "361: " << inter << std::endl; + // inter = 372; + // std::cout << "372: " << inter << std::endl; + // inter = 972; + // std::cout << "972: " << inter << std::endl; + // inter = -0.2; + // std::cout << "-0.2: " << inter << std::endl; + // inter = -1; + // std::cout << "-1: " << inter << std::endl; + // inter = -1; + // std::cout << "-1: " << inter << std::endl; + // inter = -359; + // std::cout << "-359: " << inter << std::endl; + // inter = -359.5; + // std::cout << "-359.5: " << inter << std::endl; + // inter = -360; + // std::cout << "-360: " << inter << std::endl; + // inter = -360.5; + // std::cout << "-360.5: " << inter << std::endl; + // inter = -361; + // std::cout << "-361: " << inter << std::endl; + + + } Index: trunk/milena/sandbox/folio/mln/histo/compute_histo_3d.hh =================================================================== --- trunk/milena/sandbox/folio/mln/histo/compute_histo_3d.hh (revision 3855) +++ trunk/milena/sandbox/folio/mln/histo/compute_histo_3d.hh (revision 3856) @@ -31,24 +31,22 @@ image3d<unsigned> operator()(const image2d<T>& ima) const { - typedef mln_trait_value_comp(T, 0)::enc enc_0; - typedef mln_trait_value_comp(T, 1)::enc enc_1; - typedef mln_trait_value_comp(T, 2)::enc enc_2; - - // FIXME: wrong for negative sites! - image3d<unsigned> out(mln_max(enc_0) + abs(mln_min(enc_0)) + 1, - mln_max(enc_1) + abs(mln_min(enc_1)) + 1, - mln_max(enc_2) + abs(mln_min(enc_2)) + 1); - - // Count occurences. + typedef mln_trait_value_comp(T, 0)::enc enc_0; // R -> int_u8 + typedef mln_trait_value_comp(T, 1)::enc enc_1; // G -> int_u8 + typedef mln_trait_value_comp(T, 2)::enc enc_2; // B -> int_u8 + + image3d<unsigned> out(box3d(point1d(mln_min(enc_0)), // -> 0 + point1d(mln_min(enc_1)), // -> 0 + point1d(mln_min(enc_2)), // -> 0 + point1d(mln_max(enc_0)), // -> 255 + point1d(mln_max(enc_1)), // -> 255 + point1d(mln_max(enc_2)))) // -> 255 data::fill(out, 0); - mln_fwd_piter(box2d) p(ima.domain()); + mln_fwd_piter(image2d<T>) p(ima.domain()); for_all(p) - // comp() not implemented everywhere! ++out(point3d(ima(p).comp(0), ima(p).comp(1), ima(p).comp(2))); - // return return out; } Index: trunk/milena/sandbox/folio/mln/fun/v2v/hsl_to_hsv.hh =================================================================== --- trunk/milena/sandbox/folio/mln/fun/v2v/hsl_to_hsv.hh (revision 0) +++ trunk/milena/sandbox/folio/mln/fun/v2v/hsl_to_hsv.hh (revision 3856) @@ -0,0 +1,141 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. +// reasons why the executable file might be covered by the GNU General +// Public License. + +/// \file mln/fin/v2v/hsl_to_hsv.hh +/// +/// Conversion between HSL and HSV. +/// +/// \todo Write a better doc. +/// \todo Correct/write preconditions. + + +#ifndef MLN_FUN_V2V_HSL_TO_HSV_HH +# define MLN_FUN_V2V_HSL_TO_HSV_HH + +# include <cmath> + +# include <mln/trait/value_.hh> +# include <mln/math/max.hh> +# include <mln/math/min.hh> + +# include "../../value/hsl.hh" +# include "../../value/hsv.hh" + +namespace mln +{ + + namespace fun + { + + namespace v2v + { + + template <typename T_hsv> + struct f_hsl_to_hsv_ : public Function_v2v< f_hsl_to_hsv_<T_hsv> > + { + typedef T_hsv result; + + template <typename T_hsl> + T_hsv operator()(const T_hsl& hsl) const; + }; + + extern f_hsl_to_hsv_<value::hsv_16f> f_hsl_to_hsv_16f; + extern f_hsl_to_hsv_<value::hsv_8f> f_hsl_to_hsv_8f; + + template <typename T_hsl> + struct f_hsv_to_hsl_ : public Function_v2v< f_hsv_to_hsl_<T_hsl> > + { + typedef T_hsl result; + + template <typename T_hsv> + T_hsl operator()(const T_hsv& hsv) const; + }; + + extern f_hsv_to_hsl_<value::hsl_8f> f_hsv_to_hsl_8f; + extern f_hsv_to_hsl_<value::hsl_16f> f_hsv_to_hsl_16f; + + +# ifndef MLN_INCLUDE_ONLY + + /// Global variables. + /// \{ + f_hsl_to_hsv_<value::hsv_16f> f_hsl_to_hsv_16f; + f_hsl_to_hsv_<value::hsv_8f> f_hsl_to_hsv_8f; + f_hsv_to_hsl_<value::hsl_8f> f_hsv_to_hsl_8f; + f_hsv_to_hsl_<value::hsl_16f> f_hsv_to_hsl_16f; + /// \} + + template <typename T_hsv> + template <typename T_hsl> + inline + T_hsv + f_hsl_to_hsv_<T_hsv>::operator()(const T_hsl& hsl) const + { + T_hsv hsv; + + // FIXME: take hsl [[0..360], [0..1], [0..1]] + + hsv.hue() = hsl.hue(); + float l = hsl.lum() * 2; + float s = hsl.sat() * ((hsl.lum() <= 1) ? hsl.lum() : 2 - hsl.lum()); + hsv.val() = (l + s) / 2; + hsv.sat() = (2 * s) / (l + s); + + // return hsv [[0..360], [0..1], [0..1]] + return hsv; + } + + + template <typename T_hsl> + template <typename T_hsv> + inline + T_hsl + f_hsv_to_hsl_<T_hsl>::operator()(const T_hsv& hsv) const + { + T_hsl hsl; + + // take hsv [[0..360], [0..1], [0..1]] + + hsl.hue() = hsv.hue(); + hsl.lum() = (2 - hsv.sat()) * hsv.val(); + hsl.sat() = hsv.sat() * hsv.val(); + hsl.sat() /= (hsl.lum() <= 1) ? hsl.lum() : 2 - hsl.lum(); + hsl.lum() /= 2; + + // FIXME: return hsl [[0..360], [0..1], [0..1]] + return hsl; + } + +# endif // !MLN_INCLUDE_ONLY + + } // end of namespace fun::v2v + + } // end of namespace fun + +} // end of namespace mln + +#endif // ! MLN_FUN_V2V_HSL_TO_HSV_HH Index: trunk/milena/sandbox/folio/mln/fun/v2v/rgb_to_hsv.hh =================================================================== --- trunk/milena/sandbox/folio/mln/fun/v2v/rgb_to_hsv.hh (revision 3855) +++ trunk/milena/sandbox/folio/mln/fun/v2v/rgb_to_hsv.hh (revision 3856) @@ -43,6 +43,7 @@ # include <mln/math/min.hh> # include <mln/value/rgb.hh> +# include "../../value/hsv.hh" namespace mln { @@ -62,6 +63,9 @@ T_hsv operator()(const T_rgb& rgb) const; }; + extern f_rgb_to_hsv_<value::hsv_16f> f_rgb_to_hsv_16f; + extern f_rgb_to_hsv_<value::hsv_8f> f_rgb_to_hsv_8f; + template <typename T_rgb> struct f_hsv_to_rgb_ : public Function_v2v< f_hsv_to_rgb_<T_rgb> > { @@ -71,9 +75,17 @@ T_rgb operator()(const T_hsv& hsv) const; }; + extern f_hsv_to_rgb_<value::rgb8> f_hsv_to_rgb_8f; + # ifndef MLN_INCLUDE_ONLY + /// Global variables. + /// \{ + f_rgb_to_hsv_<value::hsv_16f> f_rgb_to_hsv_16f; + f_rgb_to_hsv_<value::hsv_8f> f_rgb_to_hsv_8f; + f_hsv_to_rgb_<value::rgb8> f_hsv_to_rgb_8f; + /// \} template <typename T_hsv> template <typename T_rgb> @@ -116,7 +128,7 @@ { // take hsv [[0..360], [0..1], [0..1]] - float i = floor(hsv.hue() / 60); + unsigned i = floor(hsv.hue() / 60); float f = hsv.hue() / 60 - i; float p = hsv.val() * (1 - hsv.sat()); float q = hsv.val() * (1 - f * hsv.sat()); Index: trunk/milena/sandbox/folio/mln/value/hsv.hh =================================================================== --- trunk/milena/sandbox/folio/mln/value/hsv.hh (revision 3855) +++ trunk/milena/sandbox/folio/mln/value/hsv.hh (revision 3856) @@ -59,6 +59,9 @@ template <typename H, typename S, typename V> class hsv_; + typedef hsv_< circular<8, 0, 360>, float01_<8>, float01_<8> > hsv_8f; + typedef hsv_< circular<16, 0, 360>, float01_<16>, float01_<16> > hsv_16f; + } @@ -69,11 +72,10 @@ namespace over_load { - // ? template <int n> void from_to_(const value::rgb<n>& from, - value::hsv_<value::circular<n, 0, 360>, float, float>& to); + value::hsv_<value::circular<n, 0, 360>, float01_<n>, float01_<n> >& to) } // end of namespace mln::convert::over_load @@ -84,8 +86,6 @@ namespace trait { - // ? - template <typename H, typename S, typename V> struct set_precise_binary_< op::plus, mln::value::hsv_<H, S, V>, @@ -151,7 +151,7 @@ { enum { dim = 3, - nbits = (sizeof (H) + sizeof (S) + sizeof (V)) * 8, // ? + nbits = (sizeof (H) + sizeof (S) + sizeof (V)) * 8, card = mln_value_card_from_(nbits) }; @@ -199,10 +199,8 @@ /// Constructor from component values. hsv_(const H& hue, const S& sat, const V& lum) { - mln_precondition(hue >= 0); mln_precondition(sat >= 0); mln_precondition(val >= 0); - mln_precondition(hue <= 1.); // ? mln_precondition(sat <= 1.); mln_precondition(val <= 1.); hue_ = hue; @@ -215,9 +213,6 @@ const S& sat() const; const V& val() const; - // ? - // hue(float), hue(H) instead? - /// Read-write access to the hue component. H& hue(); S& sat(); @@ -395,15 +390,14 @@ namespace over_load { - // ? template <int n> inline void from_to_(const value::rgb<n>& from, - value::hsv_<value::circular<n, 0, 360>, float, float>& to) + value::hsv_<value::circular<n, 0, 360>, float01_<n>, float01_<n> >& to) { to = fun::v2v::f_rgb_to_hsv_< - value::hsv_<value::circular<n, 0, 360>, float, float> >(from); + value::hsv_<value::circular<n, 0, 360>, float01_<n>, float01_<n> > >(from); } } // end of namespace mln::convert::over_load
participants (1)
-
Etienne FOLIO