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