r4329: Fixes about IZ method

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2009-07-24 Edwin Carlinet <carlinet@lrde.epita.fr> Fixes about IZ method. * edwin/exec/zi.cc: Some tries... * edwin/exec/zi.hh: Real distance between components. --- zi.cc | 106 +++++++++++++++++++++++++++++++++++---------- zi.hh | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+), 23 deletions(-) Index: trunk/milena/sandbox/edwin/exec/zi.hh =================================================================== --- trunk/milena/sandbox/edwin/exec/zi.hh (revision 0) +++ trunk/milena/sandbox/edwin/exec/zi.hh (revision 4329) @@ -0,0 +1,153 @@ +// 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. + +#ifndef ZI_HH +# define ZI_HH + + +// From mln/canvas/distance_geodesic.hh + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/core/routine/duplicate.hh> +# include <mln/core/site_set/p_queue_fast.hh> +# include <queue> +# include <mln/data/fill.hh> +# include <mln/extension/adjust_fill.hh> + + +// Local. + +#include <map> +#include <mln/core/image/image2d.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/value/int_u8.hh> +#include <mln/io/pbm/load.hh> +#include <mln/labeling/blobs.hh> +#include <mln/debug/println.hh> + + + + +namespace mln +{ + + // Theo's code + + // From mln/canvas/distance_geodesic.hh + // and mln/transform/internal/influence_zone_functor.hh + // and mln/transform/influence_zone_geodesic.hh + + + template <typename I, typename N> + std::map< std::pair<mln_value(I),mln_value(I)>, unsigned > + distances(// in: + const I& input, const N& nbh, + // out: + mln_ch_value(I, unsigned)& dmap, + mln_concrete(I)& iz) + { + trace::entering("canvas::impl::generic::distance_geodesic"); + + typedef mln_value(I) L; + std::map< std::pair<L,L>, unsigned > dist; // NEW + + const unsigned max = mln_max(unsigned); + typedef mln_site(I) P; + p_queue_fast<P> q; + + // Initialization. + { + iz = duplicate(input); // <-- init + + data::fill(dmap, max); + + mln_piter(I) p(input.domain()); + mln_niter(N) n(nbh, p); + for_all(p) + if (input(p) != 0) // <-- inqueue_p_wrt_input_p + { + ; // <-- init_p + dmap(p) = 0; + for_all(n) + if (input.domain().has(n) && + input(n) == 0) // <-- inqueue_p_wrt_input_n + { + q.push(p); + break; + } + } + } + + // Propagation. + { + P p; + mln_niter(N) n(nbh, p); + while (! q.is_empty()) + { + p = q.pop_front(); + if (dmap(p) == max) + { + // Saturation so stop. + q.clear(); + break; + } + for_all(n) + { + if (! input.domain().has(n)) + continue; + if (dmap(n) == max) + { + dmap(n) = dmap(p) + 1; + iz(n) = iz(p); // <- process + q.push(n); + } + else + { + if (iz(n) != iz(p)) + { + L l1 = iz(n), l2 = iz(p); + if (l1 > l2) + std::swap(l1, l2); + unsigned& d_ = dist[std::make_pair(l1,l2)]; + unsigned d12 = dmap(p) + dmap(n) + 1; + if (d_ == 0 || d12 < d_) + d_ = d12; + } + } + } + } + } + + return dist; + } + +} // mln + +# ifndef MLN_INCLUDE_ONLY + +# endif // ! MLN_INCLUDE_ONLY + +#endif // ! ZI_HH Index: trunk/milena/sandbox/edwin/exec/zi.cc =================================================================== --- trunk/milena/sandbox/edwin/exec/zi.cc (revision 4328) +++ trunk/milena/sandbox/edwin/exec/zi.cc (revision 4329) @@ -33,6 +33,7 @@ #include <mln/value/int_u8.hh> #include <mln/value/label_16.hh> #include <mln/value/label_8.hh> +#include <mln/data/convert.hh> #include <mln/util/graph.hh> #include <mln/io/pbm/load.hh> @@ -50,10 +51,13 @@ #include <mln/make/edge_image.hh> #include <mln/make/vertex_image.hh> +#include <mln/morpho/closing/height.hh> + #include <mln/math/max.hh> #include <mln/norm/l1.hh> #include "color_distance.hh" +#include "zi.hh" #include <iostream> namespace mln @@ -94,6 +98,7 @@ } + // distance entre les centres de masses. template <typename P> inline value::int_u8 @@ -103,6 +108,7 @@ } + // distance entre les boites englobantes. inline value::int_u8 distance_box(const box<point2d>& b1, const box<point2d>& b2) @@ -125,6 +131,35 @@ return math::max(math::max(w_dist, h_dist), 0); } + + // distance geodesic entre les composantes. + template <typename G, typename L> + struct distance_t : Function_v2v< distance_t<G, L> > + { + typedef unsigned result; + typedef util::vertex_id_t V; + typedef util::edge_id_t E; + + distance_t(const std::map< std::pair<L, L>, unsigned >& d_, + const G& graph) + : d(d_), + g(graph) + { + } + + unsigned + operator () (const E& e_id) const + { + typename G::edge_t e = g.edge(e_id); + std::pair<L, L> p((value::label_8)e.v1(), (value::label_8)e.v2()); + return d.find(p)->second; + } + + private: + const std::map< std::pair<L, L>, unsigned >& d; + const G& g; + }; + } @@ -147,12 +182,13 @@ using namespace mln; using value::int_u8; - if (argc < 3) + if (argc < 4) usage(argv); const char* finput = argv[1]; const char* fsource = argv[2]; - const char* foutput = argc > 3 ? argv[3] : "zi.pgm"; + const unsigned lambda = atoi(argv[3]); + const char* foutput = argc > 4 ? argv[4] : "zi.pgm"; // Image loadin' image2d<bool> input; @@ -167,11 +203,17 @@ typedef image2d<L> I; I labels, iz, out; + image2d<unsigned> dmap; L nlabel; + typedef std::map< std::pair<L,L>, unsigned > map_t; labels = labeling::blobs(input, c4(), nlabel); - iz = transform::influence_zone_geodesic(labels, c4()); + initialize(iz, input); + initialize(dmap, input); + + map_t d = distances(labels, c4(), dmap, iz); + io::pgm::save(data::convert(int_u8(), dmap), "dmap.pgm"); io::pgm::save(iz, foutput); // I.Z Graph @@ -179,29 +221,33 @@ // Valuation of color distance - // util::array<value::rgb8> mean_colors; - // convert::from_to(labeling::compute(accu::stat::mean<value::rgb8>(), source, labels, nlabel), - // mean_colors); + /* + util::array<value::rgb8> mean_colors; + convert::from_to(labeling::compute(accu::stat::mean<value::rgb8>(), source, labels, nlabel), + mean_colors); - // typedef vertex_image<void, value::rgb8, util::graph> V; - // V v_ima = make::vertex_image(izg, mean_colors); - - // typedef edge_image<void, value::int_u8, util::graph> E; - // E e_ima = make::edge_image(v_ima, convert::tofun(dist_mean)); + typedef vertex_image<void, value::rgb8, util::graph> V; + V v_ima = make::vertex_image(izg, mean_colors); + typedef edge_image<void, value::int_u8, util::graph> E; + E e_ima = make::edge_image(v_ima, convert::tofun(dist_mean)); + */ // Valuation of geometric distance - // util::array<mln_psite_(I)> mass_centers; -// convert::from_to(labeling::compute(accu::center<mln_psite_(I)>(), labels, nlabel), -// mass_centers); + /* + util::array<mln_psite_(I)> mass_centers; + convert::from_to(labeling::compute(accu::center<mln_psite_(I)>(), labels, nlabel), + mass_centers); -// typedef vertex_image<void, mln_psite_(I), util::graph> V; -// V v_ima = make::vertex_image(izg, mass_centers); + typedef vertex_image<void, mln_psite_(I), util::graph> V; + V v_ima = make::vertex_image(izg, mass_centers); -// typedef edge_image<void, value::int_u8, util::graph> E; -// E e_ima = make::edge_image(v_ima, convert::tofun(distance<mln_psite_(I)>)); + typedef edge_image<void, value::int_u8, util::graph> E; + E e_ima = make::edge_image(v_ima, convert::tofun(distance<mln_psite_(I)>)); + */ // Valuation of distance between bounding boxes + /* util::array< box<mln_psite_(I)> > bboxes; convert::from_to(labeling::compute(accu::shape::bbox<mln_psite_(I)>(), labels, nlabel), bboxes); @@ -211,15 +257,23 @@ typedef edge_image<void, value::int_u8, util::graph> E; E e_ima = make::edge_image(v_ima, convert::tofun(distance_box)); + */ + + // Valuation of components geodesic distance. + typedef edge_image<void, unsigned, util::graph> E; + E e_ima = make::edge_image(izg, distance_t<util::graph, value::label_8>(d, izg)); + // Closing + e_ima = morpho::closing::height(e_ima, E::nbh_t (), lambda); + // WST. - typedef mln_ch_value_(V, L) v_ima_labels_t; - v_ima_labels_t v_ima_labels; - initialize(v_ima_labels, v_ima); + typedef vertex_image<void, L, util::graph> V; + p_vertices<util::graph> pv(izg); + V v_ima_labels(pv); - typedef mln_ch_value_(E, L) e_ima_wst_t; + typedef edge_image<void, L, util::graph> e_ima_wst_t; L nbasins; e_ima_wst_t e_ima_wst = morpho::watershed::flooding(e_ima, E::nbh_t (), nbasins); @@ -240,13 +294,19 @@ // Relabeling util::array<L> tr(nlabel); - mln_piter_(V) v(v_ima.domain()); + mln_piter_(V) v(v_ima_labels.domain()); for_all(v) { std::cout << v.id() << " : " << v_ima_labels(v) << std::endl; tr[v.id()] = v_ima_labels(v); } + //print distance + for (map_t::const_iterator it = d.begin(); it != d.end(); ++it) + std::cout << it->first.first << ", " + << it->first.second << " -> " + << it->second << std::endl; + labeling::relabel_inplace(iz, nlabel, tr); io::pgm::save(iz, "zi_wst.pgm");
participants (1)
-
Edwin Carlinet