URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-05-19 Etienne FOLIO <folio(a)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