4315: Augment ICDAR module code.

https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Augment ICDAR module code. * modules/icdar/words.cc: Cosmetic change. * modules/icdar/lines.cc: Augment. lines.cc | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- words.cc | 1 2 files changed, 155 insertions(+), 19 deletions(-) Index: modules/icdar/words.cc --- modules/icdar/words.cc (revision 4314) +++ modules/icdar/words.cc (working copy) @@ -222,4 +222,3 @@ io::ppm::save(labeling::colorize(output, n_words), "ws_large.ppm"); } - Index: modules/icdar/lines.cc --- modules/icdar/lines.cc (revision 4314) +++ modules/icdar/lines.cc (working copy) @@ -53,6 +53,7 @@ #include <mln/morpho/closing/structural.hh> #include <mln/core/alias/neighb2d.hh> #include <mln/morpho/watershed/flooding.hh> +#include <mln/labeling/wrap.hh> #include <mln/algebra/vec.hh> #include <mln/accu/stat/var.hh> @@ -60,6 +61,13 @@ #include <mln/make/vertex_image.hh> #include <mln/make/edge_image.hh> +#include <mln/morpho/elementary/dilation.hh> +#include <mln/data/transform.hh> +#include <mln/core/image/imorph/tr_image.hh> +#include <mln/core/routine/duplicate.hh> +#include <mln/labeling/colorize.hh> + + void usage(char* argv[]) { @@ -105,25 +113,120 @@ } - struct bloup : Function_vv2v<bloup> +// struct bloup : Function_vv2v<bloup> +// { +// typedef float result; + +// template <typename Var, typename V> +// float dist(const Var& var, const V& v) const +// { +// mln_precondition(var.is_valid()); +// V v_ = v - var.mean(); +// return v_.t() * var.variance()._1() * v_; +// } + +// template <typename Var> +// float operator()(const Var& var1, const Var& var2) const +// { +// return std::min(dist(var1, var2.mean()), dist(var2, var1.mean())); +// } +// }; + + + struct pass : Function_vv2v<pass> { - typedef float result; + typedef bool result; - template <typename Var, typename V> - float dist(const Var& var, const V& v) const + template <typename A> + bool operator()(const A& a1, const A& a2) const + { + if (! a1.is_valid() || ! a2.is_valid()) + return false; + A l, r; + if (a1.mean()[1] < a2.mean()[1]) + { + l = a1; + r = a2; + } + else { - mln_precondition(var.is_valid()); - V v_ = v - var.mean(); - return v_.t() * var.variance()._1() * v_; + l = a2; + r = a1; + } + float + // vertical std deviations + vs_l = std::sqrt(l.variance()(0, 0)), + vs_r = std::sqrt(r.variance()(0, 0)), + // vertical distance + vd = std::abs(l.mean()[0] - r.mean()[0]), + // horizontal std deviations + hs_l = std::sqrt(l.variance()(1, 1)), + hs_r = std::sqrt(r.variance()(1, 1)), + // horizontal means (column coordinates) + hm_l = l.mean()[1], + hm_r = r.mean()[1]; + + bool + v_criterion = (vd < 5 * std::sqrt(vs_l * vs_r)), // FIXME: say 4? + h_criterion = (hm_r - 1 * hs_r > hm_l + 1 * hs_l); // FIXME: say 1.5? + + return v_criterion && h_criterion; } + }; + - template <typename Var> - float operator()(const Var& var1, const Var& var2) const + template <typename L> + inline + L find_root_(util::array<L>& parent, L l) { - return std::min(dist(var1, var2.mean()), dist(var2, var1.mean())); + if (parent[l] == l) + return l; + return parent[l] = find_root_(parent, parent[l]); } + + + template <unsigned n> + struct over_; + + template <unsigned n> + struct sub_ : Function_v2v< sub_<n> > + { + typedef point2d result; + point2d operator()(const point2d& p) const + { + return point2d(p.row() / n, p.col() / n); + } + over_<n> inv() const; }; + template <unsigned n> + struct over_ : Function_v2v< over_<n> > + { + typedef point2d result; + point2d operator()(const point2d& p) const + { + return point2d(p.row() * n, p.col() * n); + } + sub_<n> inv() const + { + return sub_<n>(); + } + }; + + template <unsigned n> + over_<n> sub_<n>::inv() const + { + return over_<n>(); + } + + + template <typename S, typename I, typename F> + tr_image<S,I,F> + transform(const Site_Set<S>& s, const Image<I>& ima, const Function_v2v<F>& t) + { + tr_image<S,I,F> tmp(exact(s), exact(ima), exact(t)); + return tmp; + } } // local @@ -184,6 +287,8 @@ L n_basins; image2d<L> ws = morpho::watershed::flooding(clo, c4(), n_basins); + io::pgm::save(labeling::wrap(ws), "temp_ws.pgm"); + std::cout << "n basins = " << n_basins << std::endl; local::superimpose_save(small, ws, "temp_small_ws.ppm"); @@ -197,25 +302,57 @@ n_basins, (pw::cst(255) - pw::value(small)) | small.domain()); - for (unsigned l = 1; l <= n_basins; ++l) - std::cout << l << ' ' << arr[l].n_items() << ' ' << arr[l].mean() << std::endl; + // for (unsigned l = 1; l <= n_basins; ++l) + // std::cout << l << ' ' << arr[l].n_items() << ' ' << arr[l].mean() << std::endl; typedef util::graph G; G gr = make::region_adjacency_graph(ws, c8(), n_basins); vertex_image<void,A,G> v_ima = make::vertex_image(gr, arr); - edge_image<void,float,G> e_ima = make::edge_image(v_ima, - local::bloup()); + edge_image<void,bool,G> e_ima = make::edge_image(v_ima, + local::pass()); - { - typedef edge_image<void,float,G> I; + + util::array<L> parent(n_basins.next()); + for (L l = 0; l <= n_basins; ++l) + parent[l] = l; + + typedef edge_image<void,bool,G> I; mln_piter_(I) e(e_ima.domain()); for_all(e) { - std::cout << e.element().v1() << '-' << e.element().v2() << " : " << e_ima(e) << std::endl; - } + if (! e_ima(e)) + continue; + + unsigned + l1 = e.element().v1(), + l2 = e.element().v2(); + if (l1 > l2) + std::swap(l1, l2); + parent[l1] = l2; + + // std::cout << e.element().v1() << '-' << e.element().v2() << " : " + // << (e_ima(e) ? "OK" : "ko") << std::endl; } + // for (L l = 1; l <= n_basins; ++l) + // { + // parent[l] = local::find_root_(parent, l); + // std::cout << l << " -> " << parent[l] << std::endl; + // } + + io::pgm::save(labeling::wrap(data::transform(ws, parent)), "temp_relab.pgm"); + + + ws = morpho::elementary::dilation(ws, c8()); + + image2d<L> ws_(input.domain()); + data::fill(ws_, local::transform(input.domain(), ws, local::over_<4>())); + + io::ppm::save(labeling::colorize(rgb8(), ws_), argv[2]); + + + trace::exiting("main"); }
participants (1)
-
Thierry Geraud