https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)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");
}