r3849: inim: Improve boxes algorithm
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2009-05-16 Vincent Ordy <ordy@lrde.epita.fr> inim: Improve boxes algorithm. Because of recent changes in scribo, the current work won't compile with the last SVN revision. However, it used to compile with r3697. * boxes.cc: Fix a couple of bugs. --- boxes.cc | 156 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 85 insertions(+), 71 deletions(-) Index: trunk/milena/sandbox/inim/2010/boxes/boxes.cc =================================================================== --- trunk/milena/sandbox/inim/2010/boxes/boxes.cc (revision 3848) +++ trunk/milena/sandbox/inim/2010/boxes/boxes.cc (revision 3849) @@ -38,16 +38,13 @@ #include <scribo/debug/save_linked_textbboxes_image.hh> #include <scribo/text/grouping/group_from_double_link.hh> #include <scribo/filter/small_components.hh> - #include <scribo/debug/save_textbboxes_image.hh> #include <scribo/make/debug_filename.hh> #include <mln/logical/not.hh> #include <mln/io/dump/save.hh> - #include <mln/io/pgm/save.hh> #include <mln/fun/v2v/wrap.hh> - #include <mln/math/abs.hh> int usage(const char *name) @@ -61,103 +58,127 @@ typedef image2d<value::label_16> scribo_image; -template< typename T > -double vec_y_norm(const T& t) -{ - return mln::math::abs(t[1] / t[0]); -} template< typename T > -double bboxes_y_mean(const T& bboxes) +double +bboxes_height_mean(const T& bboxes) { double mean = 0.; + unsigned count = 0; for (unsigned i = 1; i < bboxes.nelements(); i++) { mln_VAR(s, bboxes[i].pmax() - bboxes[i].pmin()); - mean += (s[1] / s[0]); + if (s[1] < 10 || s[1] > 300) + continue; + + mean += s[1]; + count++; } - mean /= static_cast<double>(bboxes.nelements()); + mean /= static_cast<double>(count); return mean; } + +template <typename I> +scribo::util::text<I> +group_from_line_array(const scribo::util::text<I>& text, + mln::util::array<unsigned>& array) +{ + /// Accumulator array + mln::util::array< accu::bbox<mln_site(I)> > tboxes; + tboxes.resize(text.bboxes().nelements()); + + /// Adding bounding boxes to accumulator + for (unsigned label = 0; label < array.size(); ++label) + for (unsigned i = label; i < array.size(); i++) + { + if (label != array[i]) + continue; + + tboxes[label].take(text.bbox(i)); + } + + fun::i2v::array<unsigned> f; + convert::from_to(array, f); + + /// Finding valid bounding boxes + mln::util::array< box<mln_site(I)> > bresult; + bresult.append(box<mln_site(I)>()); + for_all_components(i, tboxes) + if (tboxes[i].is_valid()) + bresult.append(tboxes[i]); + + /// Labelizing (FIXME) + mln_value(I) new_nbboxes; + I new_lbl = labeling::relabel(text.label_image(), + text.nbboxes(), + mln::make::relabelfun(f, text.nbboxes(), + new_nbboxes)); + + scribo::util::text<I> result(bresult, new_lbl, new_nbboxes); + return result; +} + + int main(int argc, char* argv[]) { if (argc != 3) return usage(argv[0]); - scribo::make::internal::debug_filename_prefix = "extract_text_double_link"; + std::cout << "# Line detection algorithm (boxes)" << std::endl << std::endl; - std::cout << "Debug 1" << std::endl; + scribo::make::internal::debug_filename_prefix = "extract_text_double_link"; + /// Loading image image2d<bool> input; io::pbm::load(input, argv[1]); - - std::cout << "Debug 2" << std::endl; - logical::not_inplace(input); - std::cout << "Debug 3" << std::endl; - + /// Extract boxes value::label_16 nbboxes; scribo::util::text<image2d<value::label_16> > text = text::extract_bboxes(input, c8(), nbboxes); - - std::cout << "Debug 4" << std::endl; - text = filter::small_components(text,4); - std::cout << "Debug 5" << std::endl; - + /// Grouping components mln::util::array<unsigned> 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; - + std::cout << "* Before validation: " << nbboxes << " boxes" << std::endl; - std::cout << "Debug 6" << std::endl; scribo::debug::save_linked_textbboxes_image(input, text, left_link, right_link, - literal::red, literal::cyan, literal::yellow, + literal::red, + literal::cyan, + literal::yellow, literal::green, scribo::make::debug_filename("links.ppm")); - std::cout << "Debug 7" << std::endl; - - // Validation. + // Validation scribo::util::text< scribo_image > grouped_text = text::grouping::group_from_double_link(text, left_link, right_link); - std::cout << "AFTER double grouping - nbboxes = " << grouped_text.bboxes().nelements() << std::endl; - - io::dump::save(grouped_text.label_image(), argv[2]); + std::cout << "* After validation: " << grouped_text.bboxes().nelements() + << " boxes" << std::endl; + /// Save grouped text image io::pgm::save(level::transform(grouped_text.label_image(), fun::v2v::wrap<value::int_u8>()), - "tmp.pgm"); - - std::cout << "Debug 8" << std::endl; - - - - - - + "words.pgm"); mln_VAR(b, grouped_text.bboxes()); - std::cout << "Bounding boxes: " << std::endl << b << std::endl; - mln_VAR(m, grouped_text.mass_centers()); - std::cout << "Mass centers: " << std::endl << m << std::endl; - // Mean of the y components of the bounding boxes - double mean = bboxes_y_mean(b); - std::cout << "Mean: " << mean << std::endl; + // Word height mean + double word_height_mean = bboxes_height_mean(b); + std::cout << "* Word height mean: " << word_height_mean << std::endl; + mln::util::array< unsigned > lines(m.size()); @@ -172,36 +193,29 @@ if (i == j) continue; - double y_norm_diff = vec_y_norm(m[j] - m[i]); -// std::cout << "y_norm_diff: " << y_norm_diff << std::endl; - if (y_norm_diff > 1000) - { - std::cout << "(" << i << "," << j << ")" << std::endl; - continue; - } - if (y_norm_diff < mean * 2) - { + double component_y_diff = mln::math::abs(m[j][0] - m[i][0]); + + if (component_y_diff < 0.3 * word_height_mean) lines[j] = lines[i]; -// std::cout << "Associating " << i << " to " << j << std::endl; - } } - std::cout << "Lines: " << std::endl << lines << std::endl; - -// scribo::util::text< scribo_image > grouped_lines -// = text::grouping::group_from_single_link(text, lines); - - - - - - + scribo::util::text< scribo_image > grouped_lines + = group_from_line_array(grouped_text, lines); + std::cout << "* Line number: " << grouped_lines.bboxes().nelements() + << std::endl; scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(), literal::red, scribo::make::debug_filename("boxes.ppm")); - std::cout << "Debug 9" << std::endl; -} + /// Does not seem to work (FIXME) + io::pgm::save(level::transform(grouped_lines.label_image(), + fun::l2l::wrap<value::int_u8>()), + "fixme.ppm"); + /// Alternative save + scribo::debug::save_textbboxes_image(input, grouped_lines.bboxes(), + literal::red, + argv[2]); +}
Vincent Ordy <ordy@lrde.epita.fr> writes:
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog: 2009-05-16 Vincent Ordy <ordy@lrde.epita.fr>
inim: Improve boxes algorithm. Because of recent changes in scribo, the current work won't compile with the last SVN revision. However, it used to compile with r3697.
Ce n'est pas le genre d'information qui doit figurer dans un ChangeLog. Ce fichier décrit ce qui se passe dans la distribution des fichiers, pas dans le dépôt.
* boxes.cc: Fix a couple of bugs.
Mauvais chemin. Attention aux bugs de svn-wrapper : il faut faire `svn commit' depuis le répertoire qui contient le ChangeLog où seront inscrits les changements (en l'occurrence milena/sandbox/).
participants (2)
-
Roland Levillain -
Vincent Ordy