Commit a39035a9 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

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.

git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@4225 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 9c820ced
2009-07-01 Edwin Carlinet <carlinet@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.
2009-06-25 Fabien Freling <fabien.freling@lrde.epita.fr>
Update for US images.
......
//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
//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);
}
......@@ -49,7 +49,9 @@
namespace mln {
namespace morpho {
namespace tree {
/**
......@@ -237,7 +239,6 @@ namespace mln {
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 @@ namespace mln {
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 @@ namespace mln {
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 @@ namespace mln {
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 @@ namespace mln {
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_ */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment