
* extract/lines_discontinued.hh: remove. Useless. * extract/primitive/lines_discontinued.hh: enlarge the window used to dilate. * extract/primitive/lines_h_pattern.hh, * extract/primitive/lines_pattern.hh, * extract/primitive/lines_v_pattern.hh: new line extraction algorithm. * headers.mk: remove lines_discontinued.hh from this list. * preprocessing/unskew.hh: fix wrong angle computation. * src/extract/primitive/find_discontinued_lines.cc, * table/extract.hh: use the new line extraction algorithm. * src/preprocess.cc: call scribo::preprocess. --- scribo/ChangeLog | 22 +++ scribo/extract/lines_discontinued.hh | 194 -------------------- scribo/extract/primitive/lines_discontinued.hh | 7 +- scribo/extract/primitive/lines_h_pattern.hh | 99 ++++++++++ scribo/extract/primitive/lines_pattern.hh | 122 ++++++++++++ scribo/extract/primitive/lines_v_pattern.hh | 94 ++++++++++ scribo/headers.mk | 1 - scribo/preprocessing/unskew.hh | 4 +- .../extract/primitive/find_discontinued_lines.cc | 24 +-- scribo/src/preprocess.cc | 4 +- scribo/table/extract.hh | 20 ++- 11 files changed, 366 insertions(+), 225 deletions(-) delete mode 100644 scribo/extract/lines_discontinued.hh create mode 100644 scribo/extract/primitive/lines_h_pattern.hh create mode 100644 scribo/extract/primitive/lines_pattern.hh create mode 100644 scribo/extract/primitive/lines_v_pattern.hh diff --git a/scribo/ChangeLog b/scribo/ChangeLog index 306a272..39c6c72 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,3 +1,25 @@ +2009-06-23 Guillaume Lazzara <lazzara@lrde.epita.fr> + + Update Scribo. + + * extract/lines_discontinued.hh: remove. Useless. + + * extract/primitive/lines_discontinued.hh: enlarge the window used to + dilate. + + * extract/primitive/lines_h_pattern.hh, + * extract/primitive/lines_pattern.hh, + * extract/primitive/lines_v_pattern.hh: new line extraction algorithm. + + * headers.mk: remove lines_discontinued.hh from this list. + + * preprocessing/unskew.hh: fix wrong angle computation. + + * src/extract/primitive/find_discontinued_lines.cc, + * table/extract.hh: use the new line extraction algorithm. + + * src/preprocess.cc: call scribo::preprocess. + 2009-06-19 Guillaume Lazzara <lazzara@lrde.epita.fr> Use scripts located in build-aux in Scribo. diff --git a/scribo/extract/lines_discontinued.hh b/scribo/extract/lines_discontinued.hh deleted file mode 100644 index f966f69..0000000 --- a/scribo/extract/lines_discontinued.hh +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) -// -// This file is part of Olena. -// -// Olena is free software: you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation, version 2 of the License. -// -// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project 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 SCRIBO_EXTRACT_PRIMITIVE_LINES_DISCONTINUED_HH -# define SCRIBO_EXTRACT_PRIMITIVE_LINES_DISCONTINUED_HH - -/// \file -/// -/// Extract discontinued lines in a binary image. - - -# include <mln/core/concept/image.hh> -# include <mln/core/concept/window.hh> -# include <mln/core/concept/neighborhood.hh> -# include <mln/core/site_set/box.hh> - -# include <mln/labeling/blobs.hh> -# include <mln/labeling/compute.hh> - -# include <mln/morpho/rank_filter.hh> -# include <mln/morpho/dilation.hh> - -# include <mln/accu/shape/bbox.hh> - -# include <mln/util/array.hh> -# include <mln/util/couple.hh> - -# include <scribo/core/macros.hh> - -namespace scribo -{ - - namespace extract - { - - namespace primitive - { - - using namespace mln; - - - /// Extract discontinued lines in a binary image. - /*! - * Based on a rank filter. - * - * \param[in] input_ A binary image. - * \param[in] nbh_ The neighborhood used for labeling image - * components. - * \param[in,out] nlines The label type used for labeling. - * \param[in] win_ A Window used to extract lines. - * \param[in] rank_k Rank used for filtering. - * \param[in,out] line_bboxes line bounding boxes. - * - * \return An image in which lines are labeled. - */ - template <typename I, typename N, typename V, typename W> - mln_ch_value(I,V) - lines_discontinued(const Image<I>& input_, - const Neighborhood<N>& nbh_, V& nlines, - const Window<W>& win_, unsigned rank_k, - util::array<box<mln_site(I)> >& line_bboxes); - - - /// \overload - template <typename I, typename N, typename V, typename W> - mln_ch_value(I,V) - lines_discontinued(const Image<I>& input_, - const Neighborhood<N>& nbh_, V& nlines, - const Window<W>& win_, unsigned rank_k); - - - - -# ifndef MLN_INCLUDE_ONLY - - - namespace internal - { - - template <typename I, typename N, typename V, typename W> - void - lines_discontinued_tests(const Image<I>& input, - const Neighborhood<N>& nbh, V& nlines, - const Window<W>& win, unsigned rank_k) - { - mlc_equal(mln_value(I),bool)::check(); - mlc_bool(mln_site_(I)::dim == 2)::check(); - mlc_is_a(V, mln::value::Symbolic)::check(); - - mln_precondition(exact(input).is_valid()); - mln_precondition(exact(nbh).is_valid()); - mln_precondition(exact(win).is_valid()); - - (void) nlines; - (void) rank_k; - } - - } // end of namespace scribo::primitive::internal - - - - template <typename I, typename N, typename V, typename W> - inline - mln_ch_value(I,V) - lines_discontinued(const Image<I>& input_, - const Neighborhood<N>& nbh_, V& nlines, - const Window<W>& win_, unsigned rank_k) - { - trace::entering("scribo::primitive::lines_discontinued"); - - internal::lines_discontinued_tests(input_, nbh_, nlines, win_, rank_k); - - const I& input = exact(input_); - const N& nbh = exact(nbh_); - const W& win = exact(win_); - - mln_ch_value(I,bool) filter = morpho::rank_filter(input, win, rank_k); - mln_ch_value(I,V) output = labeling::blobs(filter, nbh, nlines); - - //FIXME: we would like to enlarge the component in the right direction, - // in order to avoid rank filter side effects (smaller components). - - trace::exiting("scribo::primitive::lines_discontinued"); - return output; - } - - - - - template <typename I, typename N, typename V, typename W> - inline - mln_ch_value(I,V) - lines_discontinued(const Image<I>& input_, - const Neighborhood<N>& nbh_, V& nlines, - const Window<W>& win_, unsigned rank_k, - util::array<box<mln_site(I)> >& line_bboxes) - { - trace::entering("scribo::primitive::lines_discontinued"); - - internal::lines_discontinued_tests(input_, nbh_, nlines, win_, rank_k); - - const I& input = exact(input_); - const N& nbh = exact(nbh_); - const W& win = exact(win_); - - mln_ch_value(I,V) - output = lines_discontinued(input, nbh, nlines, win, rank_k); - - line_bboxes = labeling::compute(accu::meta::shape::bbox(), output, nlines); - mln_postcondition(line_bboxes.nelements() == nlines.next()); - - //FIXME: is it correct? - for_all_components(i, line_bboxes) - { - line_bboxes[i].enlarge(W::dir, win.delta_() - rank_k); - line_bboxes[i].crop_wrt(input.domain()); - } - - trace::exiting("scribo::primitive::lines_discontinued"); - return output; - } - -# endif // ! MLN_INCLUDE_ONLY - - - } // end of namespace scribo::extract::primitive - - } // end of namespace scribo::extract - -} // end of namespace scribo - -#endif // ! SCRIBO_EXTRACT_PRIMITIVE_LINES_DISCONTINUED_HH diff --git a/scribo/extract/primitive/lines_discontinued.hh b/scribo/extract/primitive/lines_discontinued.hh index 0e87efd..97d08f8 100644 --- a/scribo/extract/primitive/lines_discontinued.hh +++ b/scribo/extract/primitive/lines_discontinued.hh @@ -123,18 +123,15 @@ namespace scribo int dil; if (!(rank_k % 2)) - dil = win.length() / 2 + rank_k; + dil = win.length() / 2 + 2 * rank_k + 2; else - dil = win.length() / 2 + rank_k + 1; + dil = win.length() / 2 + 2 * rank_k + 3; mln_ch_value(I,bool) filter = morpho::dilation(morpho::rank_filter(input, win, rank_k), W(dil)); object_image(mln_ch_value(I,V)) output = extract::primitive::objects(filter, nbh, nlines); - //FIXME: we would like to enlarge the component in the right direction, - // in order to avoid rank filter side effects (smaller components). - trace::exiting("scribo::primitive::lines_discontinued"); return output; } diff --git a/scribo/extract/primitive/lines_h_pattern.hh b/scribo/extract/primitive/lines_h_pattern.hh new file mode 100644 index 0000000..10dcfe5 --- /dev/null +++ b/scribo/extract/primitive/lines_h_pattern.hh @@ -0,0 +1,99 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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 SCRIBO_EXTRACT_PRIMITIVE_LINES_H_PATTERN_HH +# define SCRIBO_EXTRACT_PRIMITIVE_LINES_H_PATTERN_HH + +/// \file +/// +/// Extract horizontal lines matching a specific pattern. + +#include <mln/core/concept/image.hh> +#include <mln/core/alias/window2d.hh> + +# include <mln/win/hline2d.hh> + +# include <mln/morpho/dilation.hh> + +# include <scribo/extract/primitive/lines_pattern.hh> + +namespace scribo +{ + + namespace extract + { + + namespace primitive + { + using namespace mln; + + /// Extract horizontal lines matching a specific pattern. + /// + /// \param[in] input A binary image. + /// \param[in] length The minimum line length. + /// + /// \result An image of horizontal lines. + // + template <typename I> + mln_concrete(I) + lines_h_pattern(const Image<I>& input, unsigned length); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + mln_concrete(I) + lines_h_pattern(const Image<I>& input, unsigned length) + { + mlc_is(mln_value(I), bool)::check(); + mln_precondition(exact(input).is_valid()); + mln_precondition(length % 2 == 1); + + bool win_def[7][1] = { {1}, + {0}, + {0}, + {0}, + {0}, + {0}, + {1} }; + + window2d win; + convert::from_to(win_def, win); + + win::hline2d hwin(length/2 + 2); + return morpho::dilation(lines_pattern(input, length, 1, win), hwin); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::impl::generic + + } // end of namespace mln::impl + +} // end of namespace mln + + +#endif // ! SCRIBO_EXTRACT_PRIMITIVE_LINES_H_PATTERN_HH + diff --git a/scribo/extract/primitive/lines_pattern.hh b/scribo/extract/primitive/lines_pattern.hh new file mode 100644 index 0000000..45bc487 --- /dev/null +++ b/scribo/extract/primitive/lines_pattern.hh @@ -0,0 +1,122 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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 SCRIBO_EXTRACT_PRIMITIVE_LINES_PATTERN_HH +# define SCRIBO_EXTRACT_PRIMITIVE_LINES_PATTERN_HH + +/// \file +/// +/// Extract lines matching a specific pattern. + +# include <mln/core/concept/image.hh> +# include <mln/core/alias/window2d.hh> +# include <mln/core/routine/duplicate.hh> + +# include <mln/accu/transform_line.hh> +# include <mln/accu/count_value.hh> + +# include <mln/data/paste.hh> + + +namespace scribo +{ + + namespace extract + { + + namespace primitive + { + + using namespace mln; + + + /// Extract lines with a specific pattern + /// + /// \param[in] input_ A binary image. + /// \param[in] length The minimum line length. + /// \param[in] dir The direction of the lines. + /// \param[in] win_ A window corresponding to the line pattern. + /// + /// \return A image with lines of direction \p dir. + // + template <typename I, typename W> + mln_concrete(I) + lines_pattern(const Image<I>& input_, unsigned length, + unsigned dir, const Window<W>& win_); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename W> + mln_concrete(I) + lines_pattern(const Image<I>& input_, unsigned length, + unsigned dir, const Window<W>& win_) + { + trace::entering("mln::lines_pattern"); + + const I& input = exact(input_); + const W& win = exact(win_); + mlc_is(mln_value(I), bool)::check(); + mln_precondition(input.is_valid()); + + accu::count_value<bool> accu(true); + mln_ch_value(I,unsigned) + tmp = accu::transform_line(accu, input, length, dir); + + mln_concrete(I) output; + initialize(output, input); + + mln_piter(I) p(input.domain()); + mln_qiter(window2d) q(win, p); + for_all(p) + { + if (length - tmp(p) > (0.2f * length)) + { + output(p) = false; + continue; + } + + unsigned bg_count = 0; + for_all(q) + bg_count += tmp(q); + + output(p) = (2 * length - bg_count) > (2 * length * 0.90f); + } + + + trace::exiting("mln::lines_pattern"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::impl::generic + + } // end of namespace mln::impl + +} // end of namespace mln + + +#endif // ! SCRIBO_EXTRACT_PRIMITIVE_LINES_PATTERN_HH diff --git a/scribo/extract/primitive/lines_v_pattern.hh b/scribo/extract/primitive/lines_v_pattern.hh new file mode 100644 index 0000000..43727d1 --- /dev/null +++ b/scribo/extract/primitive/lines_v_pattern.hh @@ -0,0 +1,94 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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 SCRIBO_EXTRACT_PRIMITIVE_LINES_V_PATTERN_HH +# define SCRIBO_EXTRACT_PRIMITIVE_LINES_V_PATTERN_HH + +/// \file +/// +/// Extract vertical lines matching a specific pattern. + +#include <mln/core/concept/image.hh> +#include <mln/core/alias/window2d.hh> + +# include <mln/win/hline2d.hh> + +# include <mln/morpho/dilation.hh> + +# include <scribo/extract/primitive/lines_pattern.hh> + +namespace scribo +{ + + namespace extract + { + + namespace primitive + { + using namespace mln; + + + /// Extract vertical lines matching a specific pattern. + /// + /// \param[in] input A binary image. + /// \param[in] length The minimum line length. + /// + /// \result An image of vertical lines. + // + template <typename I> + mln_concrete(I) + lines_v_pattern(const Image<I>& input, unsigned length); + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename I> + mln_concrete(I) + lines_v_pattern(const Image<I>& input, unsigned length) + { + mln_precondition(length % 2 == 1); + + bool win_def[1][7] = { { 1, 0, 0, 0, 0, 0, 1 } }; + + window2d win; + convert::from_to(win_def, win); + + win::vline2d vwin(length/2 + 2); + return morpho::dilation(lines_pattern(input, length, 0, win), vwin); + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::impl::generic + + } // end of namespace mln::impl + +} // end of namespace mln + + +#endif // ! SCRIBO_EXTRACT_PRIMITIVE_LINES_V_PATTERN_HH + diff --git a/scribo/headers.mk b/scribo/headers.mk index 4846d70..ad834f7 100644 --- a/scribo/headers.mk +++ b/scribo/headers.mk @@ -18,7 +18,6 @@ nobase_include_HEADERS = \ ./draw/all.hh \ ./draw/bounding_box_links.hh \ ./draw/bounding_boxes.hh \ -./extract/lines_discontinued.hh \ ./extract/primitive/canvas.hh \ ./extract/primitive/cells.hh \ ./extract/primitive/lines_discontinued.hh \ diff --git a/scribo/preprocessing/unskew.hh b/scribo/preprocessing/unskew.hh index 2563c25..aa82f44 100644 --- a/scribo/preprocessing/unskew.hh +++ b/scribo/preprocessing/unskew.hh @@ -80,11 +80,12 @@ namespace scribo double angle = 0; int max_angle = max_p.col(); + std::cout << "max_angle = " << max_angle << std::endl; if (max_angle > 180) max_angle = - max_angle % 180; if (max_angle < 90 && max_angle > 0) - angle = - max_angle; + angle = 90 - max_angle; else if (max_angle < 0 && max_angle > -90) angle = max_angle; else if (max_angle < 180 && max_angle > 90) @@ -92,6 +93,7 @@ namespace scribo else if (max_angle < -90 && max_angle > -180) angle = 180 + max_angle; + std::cout << "effective angle = " << angle << std::endl; mln_concrete(I) output = transformation::rotate(input, angle); trace::exiting("scribo::preprocessing::unskew"); diff --git a/scribo/src/extract/primitive/find_discontinued_lines.cc b/scribo/src/extract/primitive/find_discontinued_lines.cc index 8f81770..4fc76f6 100644 --- a/scribo/src/extract/primitive/find_discontinued_lines.cc +++ b/scribo/src/extract/primitive/find_discontinued_lines.cc @@ -32,15 +32,15 @@ #include <mln/data/convert.hh> #include <mln/debug/superpose.hh> -#include <scribo/extract/primitive/lines_h_discontinued.hh> -#include <scribo/extract/primitive/lines_v_discontinued.hh> #include <scribo/debug/usage.hh> +#include <scribo/extract/primitive/lines_h_pattern.hh> +#include <scribo/extract/primitive/lines_v_pattern.hh> + const char *args_desc[][2] = { { "input.pbm", "A binary image." }, { "length", " Minimum line length." }, - { "rank", " Filter rank." }, {0, 0} }; @@ -49,10 +49,10 @@ int main(int argc, char *argv[]) { using namespace mln; - if (argc != 5) + if (argc != 4) return scribo::debug::usage(argv, "Extract discontinued horizontal and vertical lines", - "input.pbm length rank output.pbm", + "input.pbm length output.pbm", args_desc, "A binary image of horizontal and vertical lines."); @@ -64,23 +64,15 @@ int main(int argc, char *argv[]) value::label_16 nhlines; image2d<bool> hlines = data::convert(bool(), - scribo::extract::primitive::lines_h_discontinued(input, - c8(), - nhlines, - atoi(argv[2]), - atoi(argv[3]))); + scribo::extract::primitive::lines_h_pattern(input, atoi(argv[2]))); value::label_16 nvlines; image2d<bool> vlines = data::convert(bool(), - scribo::extract::primitive::lines_v_discontinued(input, - c8(), - nvlines, - atoi(argv[2]), - atoi(argv[3]))); + scribo::extract::primitive::lines_v_pattern(input, atoi(argv[2]))); data::fill((hlines | pw::value(vlines)).rw(), true); image2d<value::rgb8> out = debug::superpose(input, hlines); - io::ppm::save(out, argv[4]); + io::ppm::save(out, argv[3]); trace::exiting("main"); } diff --git a/scribo/src/preprocess.cc b/scribo/src/preprocess.cc index bc1a1c7..c9f74c7 100644 --- a/scribo/src/preprocess.cc +++ b/scribo/src/preprocess.cc @@ -65,11 +65,11 @@ int main(int argc, char *argv[]) image2d<bool> input_bw = scribo::binarization::simple(input); logical::not_inplace(input_bw); - input_bw = scribo::preprocessing::unskew(input_bw); - input_bw = scribo::filter::small_objects(input_bw, c8(), value::label_16(), 3); input_bw = scribo::filter::thin_objects(input_bw, c8(), value::label_16(), 1); + input_bw = scribo::preprocessing::unskew(input_bw); + logical::not_inplace(input_bw); io::pbm::save(input_bw, argv[2]); diff --git a/scribo/table/extract.hh b/scribo/table/extract.hh index 026343d..a553ccc 100644 --- a/scribo/table/extract.hh +++ b/scribo/table/extract.hh @@ -35,18 +35,24 @@ # include <mln/util/couple.hh> # include <mln/util/array.hh> +# include <mln/io/ppm/all.hh> +# include <mln/labeling/colorize.hh> + # include <scribo/core/object_image.hh> # include <scribo/table/rebuild.hh> # include <scribo/table/erase.hh> -# include <scribo/extract/primitive/lines_h_discontinued.hh> -# include <scribo/extract/primitive/lines_v_discontinued.hh> +# include <scribo/extract/primitive/lines_h_pattern.hh> +# include <scribo/extract/primitive/lines_v_pattern.hh> +# include <scribo/extract/primitive/objects.hh> +# include <scribo/debug/save_bboxes_image.hh> namespace scribo { namespace table { + using namespace mln; /// Extract tables from a binary image. /// Use arbitrary criterions. @@ -80,12 +86,14 @@ namespace scribo mln_precondition(input.is_valid()); mlc_equal(mln_value(I), bool)::check(); + image2d<bool> + bhlines = scribo::extract::primitive::lines_h_pattern(input, 51), + bvlines = scribo::extract::primitive::lines_v_pattern(input, 51); + V nhlines, nvlines; object_image(mln_ch_value(I,V)) - hlines = scribo::extract::primitive::lines_h_discontinued(input, c8(), - nhlines, 51, 6), - vlines = scribo::extract::primitive::lines_v_discontinued(input, c8(), - nvlines, 51, 6); + hlines = scribo::extract::primitive::objects(bhlines, c8(), nhlines), + vlines = scribo::extract::primitive::objects(bvlines, c8(), nvlines); typedef mln::util::couple<mln_ch_value(I,V), mln::util::couple<mln::util::array<box<mln_site(I)> >, -- 1.5.6.5