
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]); +}