* icdar/2009/hsc/input_lines_to_lines.cc: Iterate on lbl.domain().
* icdar/2009/hsc/label_maj.hh: new accumulator computing the most
represented label in a component.
* icdar/2009/hsc/lines_to_words.cc: basic canvas for splitting lines
into words.
---
milena/sandbox/ChangeLog | 12 ++
.../sandbox/icdar/2009/hsc/input_lines_to_lines.cc | 12 +-
milena/sandbox/icdar/2009/hsc/label_maj.hh | 197 ++++++++++++++++++++
milena/sandbox/icdar/2009/hsc/lines_to_words.cc | 98 ++++++++++
4 files changed, 314 insertions(+), 5 deletions(-)
create mode 100644 milena/sandbox/icdar/2009/hsc/label_maj.hh
create mode 100644 milena/sandbox/icdar/2009/hsc/lines_to_words.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index ba700f8..37485b0 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,17 @@
2009-04-07 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add new small tools for ICDAR.
+
+ * icdar/2009/hsc/input_lines_to_lines.cc: Iterate on lbl.domain().
+
+ * icdar/2009/hsc/label_maj.hh: new accumulator computing the most
+ represented label in a component.
+
+ * icdar/2009/hsc/lines_to_words.cc: basic canvas for splitting lines
+ into words.
+
+2009-04-07 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new known bugs in sandbox.
* bugs/algebra_vec_ne_op.cc: issues with algebra::vec operators.
diff --git a/milena/sandbox/icdar/2009/hsc/input_lines_to_lines.cc
b/milena/sandbox/icdar/2009/hsc/input_lines_to_lines.cc
index eb46b36..56aafab 100644
--- a/milena/sandbox/icdar/2009/hsc/input_lines_to_lines.cc
+++ b/milena/sandbox/icdar/2009/hsc/input_lines_to_lines.cc
@@ -6,17 +6,17 @@
#include <mln/value/label_16.hh>
#include <mln/io/pbm/load.hh>
#include <mln/io/pgm/all.hh>
-#include <mln/accu/lbl_maj.hh>
#include <mln/labeling/compute.hh>
#include <mln/pw/all.hh>
#include <mln/core/image/image_if.hh>
#include <mln/data/fill.hh>
+#include "label_maj.hh"
void usage(char* argv[])
{
std::cerr << "usage: " << argv[0] << " input.pbm
lines.pgm output.pgm" << std::endl
<< " HSC @ ICDAR'2009" << std::endl
- << " Rebuild splitted components from a label image." <<
std::endl;
+ << " Rebuild splitted components from a label image." <<
std::endl
<< " input.pbm: input 2D binary image (text is black; background is
white)" << std::endl
<< " lines.pgm: output image where line components are labeled
(int_u8)" << std::endl
<< " 0 is the background label." << std::endl
@@ -45,8 +45,8 @@ int main(int argc, char *argv[])
util::array<box2d> bboxes = labeling::compute(accu::meta::bbox(), lbl, nlabels);
/// Compute the most represented label for each component.
- accu::lbl_maj<label_16, int_u8> accu(nlabels.next());
- mln_piter_(image2d<int_u8>) p(lines.domain());
+ accu::label_maj<label_16, int_u8> accu(nlabels.next());
+ mln_piter_(image2d<int_u8>) p(lbl.domain());
for_all(p)
if (lines(p) != 0u)
accu.take(lbl(p), lines(p));
@@ -55,8 +55,10 @@ int main(int argc, char *argv[])
// Rebuild components.
util::array<util::couple<int_u8, float> > res = accu.to_result();
for (unsigned i = 1; i < res.nelements(); ++i)
- if (res[i].second() >= 0.9f)
+ if (res[i].second() >= 0.70f)
data::fill(((lines | bboxes[i]).rw() | (pw::value(lbl) != 0u)).rw(),
res[i].first());
+ else
+ std::cout << res[i].first() << " - " << res[i].second()
<< std::endl;
// Save result.
io::pgm::save(lines, argv[3]);
diff --git a/milena/sandbox/icdar/2009/hsc/label_maj.hh
b/milena/sandbox/icdar/2009/hsc/label_maj.hh
new file mode 100644
index 0000000..a46241c
--- /dev/null
+++ b/milena/sandbox/icdar/2009/hsc/label_maj.hh
@@ -0,0 +1,197 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_ACCU_LABEL_MAJ_HH
+# define MLN_ACCU_LABEL_MAJ_HH
+
+/// \file mln/accu/label_maj.hh
+///
+/// Define an accumulator that computes the most represented label in
+/// a component.
+
+
+# include <mln/core/concept/meta_accumulator.hh>
+# include <mln/accu/internal/base.hh>
+# include <mln/trait/value_.hh>
+# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
+# include <vector>
+# include <map>
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+
+ /// Computes the most represented label in a component.
+ /// The parameter \c L1 is the label type of the component in the
+ /// first label image.
+ /// The parameter \c L2 is the label type in the second label image.
+ template <typename L1, typename L2>
+ struct label_maj
+// : public mln::accu::internal::base<
util::array<util::couple<L2,float> >,
+// label_maj<L1,L2> >
+ {
+ typedef L2 argument;
+
+ label_maj();
+ label_maj(unsigned nlabels);
+
+ /// Manipulators.
+ /// \{
+ void init();
+ void take(const L1& l, const L2& L);
+ void take(const label_maj<L1,L2>& other);
+ /// \}
+
+ /// Get the value of the accumulator.
+ util::array< util::couple<L2,float> > to_result() const;
+
+ //operator L2 () const;
+
+ /// Check whether this accu is able to return a result.
+ /// Always true here.
+ bool is_valid() const;
+
+ util::array< util::couple<L2,float> > finalize_() const;
+
+ const util::array<std::map<L2,unsigned> >& maj_array_() const;
+
+ protected:
+ util::array<std::map<L2,unsigned> > maj_;
+
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L1, typename L2>
+ inline
+ label_maj<L1,L2>::label_maj()
+ {
+ }
+
+ template <typename L1, typename L2>
+ inline
+ label_maj<L1,L2>::label_maj(unsigned nlabels)
+ : maj_(nlabels + 1) // Do not forget to count the background label.
+ {
+ }
+
+ template <typename L1, typename L2>
+ inline
+ void
+ label_maj<L1,L2>::init()
+ {
+ }
+
+ template <typename L1, typename L2>
+ inline
+ void
+ label_maj<L1,L2>::take(const L1& l, const L2& L)
+ {
+ if (maj_[l].find(L) != maj_[l].end())
+ maj_[l][static_cast<unsigned>(L)] += 1;
+ else
+ maj_[l][static_cast<unsigned>(L)] = 1;
+ }
+
+ template <typename L1, typename L2>
+ inline
+ void
+ label_maj<L1,L2>::take(const label_maj<L1,L2>& other)
+ {
+ //FIXME
+ abort();
+ }
+
+ template <typename L1, typename L2>
+ inline
+ util::array< util::couple<L2,float> >
+ label_maj<L1,L2>::finalize_() const
+ {
+ util::array< util::couple<L2,float> > p(maj_.nelements());
+ for (unsigned i = 1; i < maj_.nelements(); ++i)
+ {
+ L2
+ maj_l = literal::zero;
+ unsigned
+ maj_card = 0,
+ total_card = 0;
+
+ for (typename std::map<L2,unsigned>::const_iterator it = maj_[i].begin();
+ it != maj_[i].end(); ++it)
+ {
+ if (maj_card < it->second)
+ {
+ maj_l = it->first;
+ maj_card = it->second;
+ }
+ total_card += it->second;
+ }
+
+ p[i] = make::couple(maj_l, maj_card / static_cast<float>(total_card));
+ }
+
+ return p;
+ }
+
+ template <typename L1, typename L2>
+ inline
+ const util::array<std::map<L2,unsigned> >&
+ label_maj<L1,L2>::maj_array_() const
+ {
+ return maj_;
+ }
+
+
+ template <typename L1, typename L2>
+ inline
+ util::array< util::couple<L2,float> >
+ label_maj<L1,L2>::to_result() const
+ {
+ return finalize_();
+ }
+
+ template <typename L1, typename L2>
+ inline
+ bool
+ label_maj<L1,L2>::is_valid() const
+ {
+ return maj_.nelements() > 0;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_LABEL_MAJ_H _HH
diff --git a/milena/sandbox/icdar/2009/hsc/lines_to_words.cc
b/milena/sandbox/icdar/2009/hsc/lines_to_words.cc
new file mode 100644
index 0000000..cd4b1c3
--- /dev/null
+++ b/milena/sandbox/icdar/2009/hsc/lines_to_words.cc
@@ -0,0 +1,98 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_8.hh>
+#include <mln/value/label_16.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/io/ppm/all.hh>
+#include <mln/accu/bbox.hh>
+#include <mln/labeling/compute.hh>
+#include <mln/pw/all.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/routine/extend.hh>
+#include <mln/transform/distance_geodesic.hh>
+#include <mln/win/disk2d.hh>
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/morpho/closing/structural.hh>
+#include <mln/transform/distance_geodesic.hh>
+#include <mln/core/image/extended.hh>
+#include <mln/core/var.hh>
+#include <mln/level/convert.hh>
+#include <mln/level/compute.hh>
+#include <mln/accu/count_labels.hh>
+#include <mln/labeling/relabel.hh>
+#include <mln/labeling/wrap.hh>
+#include <mln/core/routine/extend.hh>
+#include <mln/morpho/watershed/superpose.hh>
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << "lines.pgm nlines
output.pgm" << std::endl
+ << " HSC @ ICDAR'2009" << std::endl
+ << " Split lines into words." << std::endl
+ << " input.pbm: input 2D binary image (text is black; background is
white)" << std::endl
+ << " lines.pgm: output image where line components are labeled
(int_u8)" << std::endl
+ << " 0 is the background label." << std::endl
+ << " output.pgm: output image where line components are labeled
(int_u8)" << std::endl
+ << " 0 is the background label." << std::endl;
+ std::abort();
+}
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace mln::value;
+
+ if (argc < 4)
+ usage(argv);
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ image2d<int_u8> lines_;
+ io::pgm::load(lines_, argv[2]);
+ image2d<label_16> lines = level::convert(label_16(), lines_);
+
+ unsigned delta = 10;
+
+ label_16 nlines;
+ labeling::relabel_inplace(lines, nlines);
+
+
+ std::cout << "nlines = " << nlines << std::endl;
+ util::array<box2d> bboxes = labeling::compute(accu::meta::bbox(), lines,
nlines);
+
+ std::cout << "BBoxes computed" << std::endl;
+
+ for (unsigned i = 1; i < nlines; ++i)
+ {
+ std::cout << "* Processing line " << i << std::endl;
+ typedef image2d<bool> line_t;
+ line_t line = duplicate((pw::value(lines) == i) | (lines | bboxes[i]).domain());
+// io::pbm::save(line, "l2w_line.pbm");
+
+ box2d b = geom::bbox(line);
+ b.enlarge(delta);
+
+ mln_VAR(line_ext, extended_to(extend(line,false),b));
+
+// io::pbm::save(line_ext, "l2w_line_ext.pbm");
+
+ std::cout << " Distance geodesic" << std::endl;
+ mln_VAR(line_dmap, transform::distance_geodesic(line_ext, c4(), mln_max(unsigned)));
+
+ std::cout << " closing structural" << std::endl;
+ mln_VAR(line_clo, morpho::closing::structural(line_dmap, win::disk2d(21)));
+
+
+ std::cout << " Watershed" << std::endl;
+ label_16 nwords;
+ mln_VAR(wst, morpho::watershed::flooding(line_clo, c4(), nwords));
+
+// io::ppm::save(morpho::watershed::superpose(input | bboxes[i], wst),
"l2w_wst.ppm");
+// abort();
+ }
+}
--
1.5.6.5