https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a 1st threshold code.
* theo/icdar/dibco/main.cc: New.
First threshold attempt.
* theo/icdar/hsc/boxes.cc (param): Set to a reasonable value.
(tmp_pgm): Save this temp image.
* theo/exec/subsample.cc: New.
exec/subsample.cc | 43 ++++++++++++
icdar/dibco/main.cc | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++
icdar/hsc/boxes.cc | 11 ++-
3 files changed, 236 insertions(+), 2 deletions(-)
Index: theo/icdar/dibco/main.cc
--- theo/icdar/dibco/main.cc (revision 0)
+++ theo/icdar/dibco/main.cc (revision 0)
@@ -0,0 +1,184 @@
+// 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.
+
+/// \file theo/icdar/dibco/main.cc
+///
+/// Simple thresholding of a gray-level document.
+
+# include <mln/io/pgm/load.hh>
+# include <mln/io/pgm/save.hh>
+# include <mln/io/pbm/save.hh>
+
+# include <mln/debug/println.hh>
+# include <mln/fun/l2l/wrap.hh>
+# include <mln/level/transform.hh>
+
+# include <mln/core/image/image1d.hh>
+# include <mln/core/alias/neighb1d.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/core/routine/duplicate.hh>
+# include <mln/core/image/image_if.hh>
+# include <mln/pw/all.hh>
+
+# include <mln/histo/compute.hh>
+# include <mln/debug/histo.hh>
+# include <mln/convert/from_to.hh>
+
+# include <mln/morpho/elementary/gradient_internal.hh>
+# include <mln/morpho/elementary/gradient_external.hh>
+# include <mln/morpho/closing/height.hh>
+# include <mln/morpho/closing/volume.hh>
+# include <mln/morpho/watershed/flooding.hh>
+
+# include <mln/linear/gaussian_1d.hh>
+# include <mln/labeling/regional_minima.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/value/label_8.hh>
+# include <mln/accu/center.hh>
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm
output.pbm" << std::endl
+ << " ICDAR'2009: DIBCO." << std::endl;
+ std::abort();
+}
+
+
+namespace mln
+{
+
+ int
+ find_threshold(const histo::array<value::int_u8>& h)
+ {
+
+ const float sigma = 5; // FIXME: hard-coded!
+
+ util::array<point1d> c;
+ value::label_8 n;
+
+ {
+ image1d<unsigned> h_, hs_;
+ image1d<value::label_8> l;
+
+ convert::from_to(h, h_);
+ hs_ = linear::gaussian_1d(h_, sigma, 0);
+ l = labeling::regional_minima(hs_, c2(), n);
+
+ {
+// debug::println("l", l);
+// debug::histo(h, "tmp_h.txt");
+
+// std::ofstream file("tmp_hs.txt");
+// mln_piter_(box1d) p(h_.domain());
+// for_all(p)
+// file << p.ind() << ' ' << hs_(p) << std::endl;
+// file.close();
+ }
+
+ accu::center<point1d, point1d> a;
+ c = labeling::compute(a, l, n);
+
+ c[0] = point1d(0); // Force a neutral value for the non-label value (0).
+
+ // std::cout << "c = " << c << std::endl;
+ }
+
+
+ int threshold;
+
+ {
+ std::vector<int> v;
+ for (unsigned i = 0; i <= n; ++i)
+ v.push_back(c[i].ind());
+ std::sort(v.begin(), v.end());
+
+ for (unsigned i = 0; i <= n; ++i)
+ if (v[i] != 0)
+ {
+ threshold = v[i];
+ break;
+ }
+
+ std::cout << "threshold = " << threshold << std::endl;
+ }
+
+ return threshold;
+ }
+
+
+} // ! mln
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc != 3)
+ usage(argv);
+
+ image2d<int_u8> input;
+ io::pgm::load(input, argv[1]);
+
+ typedef int_u8 V;
+ histo::array<V> h;
+
+ image2d<int_u8> g;
+ g = morpho::elementary::gradient_internal(input, c4());
+ io::pgm::save(g, "tmp_g.pgm");
+
+ g = morpho::closing::height(g, c4(), 3); // FIXME: hard-coded!
+
+ unsigned nbasins;
+ image2d<unsigned> w = morpho::watershed::flooding(g, c4(), nbasins);
+
+ io::pgm::save(level::transform(w,
+ fun::l2l::wrap<int_u8>()),
+ "tmp_w.pgm");
+
+ h = histo::compute(g | (pw::value(w) == pw::cst(0)));
+
+ unsigned threshold = find_threshold(h);
+
+// output = duplicate((pw::value(g) > pw::cst(threshold)) | input.domain());
+
+ io::pbm::save((pw::value(g) > pw::cst(threshold)) | input.domain(),
+ "tmp_g.pbm");
+
+ image2d<bool> output;
+ output = duplicate((pw::value(g) > pw::cst(threshold)
+ && pw::value(w) == pw::cst(0)) | input.domain());
+
+ io::pbm::save(output, argv[2]);
+}
Index: theo/icdar/hsc/boxes.cc
--- theo/icdar/hsc/boxes.cc (revision 3597)
+++ theo/icdar/hsc/boxes.cc (working copy)
@@ -44,6 +44,9 @@
#include <mln/logical/not.hh>
#include <mln/io/dump/save.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/fun/l2l/wrap.hh>
+
int usage(const char *name)
{
@@ -74,8 +77,8 @@
text = filter::small_components(text,4);
mln::util::array<unsigned>
- left_link = text::grouping::group_with_single_left_link(text, 100),
- right_link = text::grouping::group_with_single_right_link(text, 100);
+ left_link = text::grouping::group_with_single_left_link(text, 30),
+ right_link = text::grouping::group_with_single_right_link(text, 30);
std::cout << "BEFORE - nbboxes = " << nbboxes <<
std::endl;
@@ -94,6 +97,10 @@
io::dump::save(grouped_text.label_image(), argv[2]);
+ io::pgm::save(level::transform(grouped_text.label_image(),
+ fun::l2l::wrap<value::int_u8>()),
+ "tmp.pgm");
+
scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
scribo::make::debug_filename("boxes.ppm"));
Index: theo/exec/subsample.cc
--- theo/exec/subsample.cc (revision 0)
+++ theo/exec/subsample.cc (revision 0)
@@ -0,0 +1,43 @@
+#include "filetype.hh"
+
+#include <mln/world/binary_2d/subsample.hh>
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pbm n
output.pgm" << std::endl
+ << " Subsampling." << std::endl
+ << " n >= 2." << std::endl;
+ std::abort();
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc != 4)
+ usage(argv);
+
+
+ trace::entering("main");
+
+ int n = std::atoi(argv[2]);
+ if (n < 2)
+ {
+ std::cerr << "bad n!" << std::endl;
+ usage(argv);
+ }
+
+
+ image2d<bool> ima;
+ io::pbm::load(ima, argv[1]);
+ io::pgm::save(world::binary_2d::subsample(ima,
+ n),
+ argv[3]);
+
+ trace::exiting("main");
+}