URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-07-01 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Retrieval of components whose maximize mean color difference.
* edwin/exec/color_distance.hh: Some routines about color distances.
* edwin/exec/max_delta_colormean_obj.cc: Main file for
components retrieval with respect to their mean color difference.
* edwin/mln/morpho/tree/components.hh: Minor fixes.
---
exec/color_distance.hh | 80 +++++++++++++++++
exec/max_delta_colormean_obj.cc | 179 ++++++++++++++++++++++++++++++++++++++++
mln/morpho/tree/components.hh | 15 ++-
3 files changed, 268 insertions(+), 6 deletions(-)
Index: trunk/milena/sandbox/edwin/exec/color_distance.hh
===================================================================
--- trunk/milena/sandbox/edwin/exec/color_distance.hh (revision 0)
+++ trunk/milena/sandbox/edwin/exec/color_distance.hh (revision 4225)
@@ -0,0 +1,80 @@
+//Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+
+// This file is part of Olena.
+
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+
+// As a special exception, you may use this file as part of a free
+// software project 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. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+// From theo's sandbox ~theo/color/filter_meandist_rgb_pixels.cc
+
+
+#ifndef COLOR_DISTANCE_HH
+# define COLOR_DISTANCE_HH
+
+#include <mln/value/rgb8.hh>
+#include <mln/math/diff_abs.hh>
+
+namespace mln
+{
+
+ value::int_u8 dist_mean(const value::rgb8& c1, const value::rgb8& c2)
+ {
+ unsigned d = 0;
+ d += (math::diff_abs(c1.red(), c2.red()) + 2) / 3;
+ d += (math::diff_abs(c1.green(), c2.green()) + 2) / 3;
+ d += (math::diff_abs(c1.blue(), c2.blue()) + 2) / 3;
+ if (d > 255)
+ d = 255;
+ return d;
+ }
+
+ value::int_u8 dist_sat(const value::rgb8& c1, const value::rgb8& c2)
+ {
+ unsigned d = 0;
+ d += math::diff_abs(c1.red(), c2.red());
+ d += math::diff_abs(c1.green(), c2.green());
+ d += math::diff_abs(c1.blue(), c2.blue());
+ if (d > 255)
+ d = 255;
+ return d;
+ }
+
+ value::int_u8 dist_max(const value::rgb8& c1, const value::rgb8& c2)
+ {
+ unsigned d = 0, d_;
+ d_ = math::diff_abs(c1.red(), c2.red());
+ if (d_ > d) d = d_;
+ d_ = math::diff_abs(c1.green(), c2.green());
+ if (d_ > d) d = d_;
+ d_ = math::diff_abs(c1.blue(), c2.blue());
+ if (d_ > d) d = d_;
+ return d;
+ }
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln.
+
+#endif // ! COLOR_DISTANCE_HH
Index: trunk/milena/sandbox/edwin/exec/max_delta_colormean_obj.cc
===================================================================
--- trunk/milena/sandbox/edwin/exec/max_delta_colormean_obj.cc (revision 0)
+++ trunk/milena/sandbox/edwin/exec/max_delta_colormean_obj.cc (revision 4225)
@@ -0,0 +1,179 @@
+//Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+
+// This file is part of Olena.
+
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+
+// As a special exception, you may use this file as part of a free
+// software project 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. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+
+#include <mln/morpho/tree/data.hh>
+#include <mln/morpho/tree/compute_attribute_image.hh>
+#include <mln/morpho/tree/components.hh>
+#include <mln/morpho/tree/propagate.hh>
+
+#include <mln/accu/stat/mean.hh>
+
+#include <mln/data/sort_psites.hh>
+#include <mln/data/convert.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pbm/save.hh>
+
+
+#include "color_distance.hh"
+#include <iostream>
+#include <cstring>
+
+using namespace mln;
+using value::int_u8;
+
+
+void usage(char** argv)
+{
+ std::cout << "Usage: " << argv[0] << " in:input.pgm
in:source(.pgm|.ppm) [out:attribute.pbm]"
+ << std::endl
+ << "Compute the mean attribute image from 'source' values using
'input'"
+ " min tree structure. Then, compute the delta image d (parent(n) - n) and
retrieve"
+ " components that maximizes the delta. The retrieved components are stored
through a mask"
+ " where objects are set to 1 and background to 0 in
'attribute.pbm'."
+ << std::endl;
+
+ abort();
+}
+
+const char* get_extension(const char* filename)
+{
+ return (filename + strlen(filename) - 3);
+}
+
+
+template <typename T, typename S>
+inline
+mln_ch_value(typename T::function, int_u8)
+compute_delta_mean(const value::int_u8&, const T& tree, const Image<S>&
source)
+{
+
+ typedef mln_ch_value(typename T::function, mln_sum(mln_value(S))) O;
+ O out =
morpho::tree::compute_attribute_image_from(accu::stat::mean<mln_value(S)>(),
+ tree, source);
+
+ // Compute delta image.
+ mln_ch_value(typename T::function, int_u8) dist;
+ initialize(dist, tree.f());
+
+ mln_up_node_piter(T) n(tree);
+ for_all(n)
+ dist(n) = out(tree.parent(n)) - out(n);
+
+ return dist;
+}
+
+template <typename T, typename S>
+inline
+mln_ch_value(typename T::function, int_u8)
+compute_delta_mean(const value::rgb8&, const T& tree, const Image<S>&
source)
+{
+
+ typedef mln_ch_value(typename T::function, mln_sum(mln_value(S))) O;
+ O out =
morpho::tree::compute_attribute_image_from(accu::stat::mean<mln_value(S)>(),
+ tree, source);
+
+ // Compute delta image.
+ mln_ch_value(typename T::function, int_u8) dist;
+ initialize(dist, tree.f());
+
+ mln_up_node_piter(T) n(tree);
+ for_all(n)
+ {
+ // Fixme: rewrite distance routines with vector instead of convert ?
+ dist(n) = dist_mean(convert::to<value::rgb8>(out(tree.parent(n))),
convert::to<value::rgb8>(out(n)));
+ }
+
+ return dist;
+}
+
+template <typename T, typename S>
+inline
+mln_ch_value(typename T::function, int_u8)
+compute_delta_mean(const T& tree, const Image<S>& source)
+{
+ return compute_delta_mean(mln_value(S) (), tree, source);
+}
+
+
+
+int main(int argc, char** argv)
+{
+
+
+ if (argc < 3)
+ usage(argv);
+
+ const char* finput = argv[1];
+ const char* fsource = argv[2];
+ const char* foutput = argc > 3 ? argv[3] : "mask.pbm";
+
+ // Image loadin'.
+ typedef image2d<value::int_u8> I;
+ I input;
+ io::pgm::load(input, finput);
+
+
+ // Tree construction.
+ typedef p_array<mln_psite_(I)> S;
+ typedef morpho::tree::data<I, S> T;
+
+ S s = data::sort_psites_increasing(input);
+ T tree(input, s, c4());
+
+ // Attribute computation.
+ mln_ch_value_(I, int_u8) delta;
+
+ const char* extension = get_extension(fsource);
+ if (strcmp(extension, "pgm") == 0)
+ {
+ image2d<value::int_u8> src;
+ io::pgm::load(src, fsource);
+ delta = compute_delta_mean(tree, src);
+ }
+ else if (strcmp(extension, "ppm") == 0)
+ {
+ image2d<value::rgb8> src;
+ io::ppm::load(src, fsource);
+ delta = compute_delta_mean(tree, src);
+ }
+ else
+ usage(argv); // Type not handled.
+
+ // Get the max components of the delta image.
+ p_array<mln_psite_(I)> obj = morpho::tree::get_components(tree, delta);
+
+ typedef mln_ch_value_(I, bool) O;
+ O out = morpho::tree::set_value_to_components(tree, obj, true, false);
+
+ io::pbm::save(out, foutput);
+}
Index: trunk/milena/sandbox/edwin/mln/morpho/tree/components.hh
===================================================================
--- trunk/milena/sandbox/edwin/mln/morpho/tree/components.hh (revision 4224)
+++ trunk/milena/sandbox/edwin/mln/morpho/tree/components.hh (revision 4225)
@@ -49,7 +49,9 @@
namespace mln {
+
namespace morpho {
+
namespace tree {
/**
@@ -237,7 +239,6 @@
p = max_arr[arr_pos];
if (a(p) == 0)
break;
- std::cout << p << " " << a(p) << std::endl;
components.insert(p);
morpho::tree::propagate_node_to_descendants(p, tree, activity, false, nb_leaves);
morpho::tree::propagate_node_to_ancestors(p, tree, activity, false);
@@ -262,7 +263,7 @@
trace::entering("mln::morpho::tree::get_components");
const A& a = exact(attr_image);
- mln_precondition(tree.f().domain() == a.domain());
+ mln_precondition(tree.f().domain() == a.domain()); // May be to strong.
mln_precondition(a.is_valid());
p_array< mln_psite(A) > components =
@@ -280,7 +281,7 @@
trace::entering("mln::morpho::tree::get_components");
const A& a = exact(attr_image);
- mln_precondition(tree.f().domain() == a.domain());
+ mln_precondition(tree.f().domain() == a.domain()); // May be to strong.
mln_precondition(a.is_valid());
p_array< mln_psite(A) > components;
@@ -300,7 +301,7 @@
const A& a = exact(attr_image);
const P2B& predicate = exact(pred);
- mln_precondition(tree.f().domain() == a.domain());
+ mln_precondition(tree.f().domain() == a.domain()); // May be to strong.
mln_precondition(a.is_valid());
p_array< mln_psite(A) > components =
@@ -310,10 +311,12 @@
return components;
}
+# endif /* !MLN_INCLUDE_ONLY */
+
} // end of namespace mln::morpho::tree
+
} // end of namespace mln::morpho
-} // end of namespace mln
-# endif /* !MLN_INCLUDE_ONLY */
+} // end of namespace mln
#endif /* !MLN_MORPHO_TREE_COMPONENTS_HH_ */