Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
last-svn-commit-117-g464d58f Add A first draft of a README in Scribo.
by Guillaume Lazzara 03 Jun '10
by Guillaume Lazzara 03 Jun '10
03 Jun '10
* README: New.
---
scribo/ChangeLog | 72 +++++++++++++++++++++++++++++------------------------
scribo/README | 51 ++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 33 deletions(-)
create mode 100644 scribo/README
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 0a98d9a..b4d325e 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,40 +1,46 @@
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add A first draft of a README in Scribo.
+
+ * README: New.
+
+2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Move AFP's GUI into Scribo's demo directory.
- * milena/sandbox/lazzara/afp/photos/gui/gui.pro,
- * milena/sandbox/lazzara/afp/photos/gui/gui.qrc,
- * milena/sandbox/lazzara/afp/photos/gui/icons/next.png,
- * milena/sandbox/lazzara/afp/photos/gui/icons/ok.png,
- * milena/sandbox/lazzara/afp/photos/gui/icons/photos.png,
- * milena/sandbox/lazzara/afp/photos/gui/icons/prev.png,
- * milena/sandbox/lazzara/afp/photos/gui/icons/remove.png,
- * milena/sandbox/lazzara/afp/photos/gui/src/custom_delegate.cc,
- * milena/sandbox/lazzara/afp/photos/gui/src/custom_delegate.hh,
- * milena/sandbox/lazzara/afp/photos/gui/src/launch_dialog.cc,
- * milena/sandbox/lazzara/afp/photos/gui/src/launch_dialog.hh,
- * milena/sandbox/lazzara/afp/photos/gui/src/main.cc,
- * milena/sandbox/lazzara/afp/photos/gui/src/main_window.cc,
- * milena/sandbox/lazzara/afp/photos/gui/src/main_window.hh,
- * milena/sandbox/lazzara/afp/photos/gui/ui/launch_dialog.ui,
- * milena/sandbox/lazzara/afp/photos/gui/ui/main_window.ui: Move...
-
- * scribo/demo/tip/gui.pro,
- * scribo/demo/tip/gui.qrc,
- * scribo/demo/tip/icons/next.png,
- * scribo/demo/tip/icons/ok.png,
- * scribo/demo/tip/icons/photos.png,
- * scribo/demo/tip/icons/prev.png,
- * scribo/demo/tip/icons/remove.png,
- * scribo/demo/tip/src/custom_delegate.cc,
- * scribo/demo/tip/src/custom_delegate.hh,
- * scribo/demo/tip/src/launch_dialog.cc,
- * scribo/demo/tip/src/launch_dialog.hh,
- * scribo/demo/tip/src/main.cc,
- * scribo/demo/tip/src/main_window.cc,
- * scribo/demo/tip/src/main_window.hh,
- * scribo/demo/tip/ui/launch_dialog.ui,
- * scribo/demo/tip/ui/main_window.ui: ... here.
+ * ../milena/sandbox/lazzara/afp/photos/gui/gui.pro,
+ * ../milena/sandbox/lazzara/afp/photos/gui/gui.qrc,
+ * ../milena/sandbox/lazzara/afp/photos/gui/icons/next.png,
+ * ../milena/sandbox/lazzara/afp/photos/gui/icons/ok.png,
+ * ../milena/sandbox/lazzara/afp/photos/gui/icons/photos.png,
+ * ../milena/sandbox/lazzara/afp/photos/gui/icons/prev.png,
+ * ../milena/sandbox/lazzara/afp/photos/gui/icons/remove.png,
+ * ../milena/sandbox/lazzara/afp/photos/gui/src/custom_delegate.cc,
+ * ../milena/sandbox/lazzara/afp/photos/gui/src/custom_delegate.hh,
+ * ../milena/sandbox/lazzara/afp/photos/gui/src/launch_dialog.cc,
+ * ../milena/sandbox/lazzara/afp/photos/gui/src/launch_dialog.hh,
+ * ../milena/sandbox/lazzara/afp/photos/gui/src/main.cc,
+ * ../milena/sandbox/lazzara/afp/photos/gui/src/main_window.cc,
+ * ../milena/sandbox/lazzara/afp/photos/gui/src/main_window.hh,
+ * ../milena/sandbox/lazzara/afp/photos/gui/ui/launch_dialog.ui,
+ * ../milena/sandbox/lazzara/afp/photos/gui/ui/main_window.ui: Move...
+
+ * demo/tip/gui.pro,
+ * demo/tip/gui.qrc,
+ * demo/tip/icons/next.png,
+ * demo/tip/icons/ok.png,
+ * demo/tip/icons/photos.png,
+ * demo/tip/icons/prev.png,
+ * demo/tip/icons/remove.png,
+ * demo/tip/src/custom_delegate.cc,
+ * demo/tip/src/custom_delegate.hh,
+ * demo/tip/src/launch_dialog.cc,
+ * demo/tip/src/launch_dialog.hh,
+ * demo/tip/src/main.cc,
+ * demo/tip/src/main_window.cc,
+ * demo/tip/src/main_window.hh,
+ * demo/tip/ui/launch_dialog.ui,
+ * demo/tip/ui/main_window.ui: ... here.
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/README b/scribo/README
new file mode 100644
index 0000000..b8b7ca2
--- /dev/null
+++ b/scribo/README
@@ -0,0 +1,51 @@
+Copyright (C) 2009, 2010 EPITA Research and Development Laboratory (LRDE)
+
+This file is part of Scribo.
+
+Scribo 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.
+
+Scribo 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/>.
+
+The complete GNU General Public License Notice can also be found in
+the 'COPYING' file in the root directory.
+
+
+======================
+ Introduction to Olena
+======================
+
+Scribo aims to provide tools for Document Image Analysis (DIA).
+
+
+========
+ Content
+========
+
+demo/
+
+ demat
+ Sample GUI used to retrieve text from a whole document or a
+ region of interest.
+
+ wizard
+ Sample GUI used to retrieve text from a whole document or a
+ region of interest.
+
+ tip
+ Sample GUI used to display text localization in picture results.
+
+
+src/
+ text_in_article_pbm
+ Retrieve text from a document.
+
+ text_in_picture_fast
+ Localize text in pictures.
\ No newline at end of file
--
1.5.6.5
1
0
03 Jun '10
* scribo/primitive/extract/horizontal_separators.hh,
* scribo/primitive/extract/separators.hh,
* scribo/primitive/extract/vertical_separators.hh,
* scribo/primitive/remove/separators.hh: New.
---
scribo/ChangeLog | 9 ++
.../primitive/extract/horizontal_separators.hh | 69 ++++++++--------
.../extract/{lines_v_pattern.hh => separators.hh} | 78 ++++++++----------
.../primitive/extract/vertical_separators.hh | 69 ++++++++--------
.../lines_v_pattern.hh => remove/separators.hh} | 86 +++++++++----------
5 files changed, 155 insertions(+), 156 deletions(-)
copy milena/mln/world/inter_pixel/full2image.hh => scribo/primitive/extract/horizontal_separators.hh (53%)
copy scribo/primitive/extract/{lines_v_pattern.hh => separators.hh} (53%)
copy milena/mln/world/inter_pixel/full2image.hh => scribo/primitive/extract/vertical_separators.hh (53%)
copy scribo/primitive/{extract/lines_v_pattern.hh => remove/separators.hh} (50%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index b4d325e..4aa545d 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,14 @@
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add new routines to detect separators.
+
+ * scribo/primitive/extract/horizontal_separators.hh,
+ * scribo/primitive/extract/separators.hh,
+ * scribo/primitive/extract/vertical_separators.hh,
+ * scribo/primitive/remove/separators.hh: New.
+
+2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add A first draft of a README in Scribo.
* README: New.
diff --git a/milena/mln/world/inter_pixel/full2image.hh b/scribo/primitive/extract/horizontal_separators.hh
similarity index 53%
copy from milena/mln/world/inter_pixel/full2image.hh
copy to scribo/primitive/extract/horizontal_separators.hh
index db3bcf3..9a6ea39 100644
--- a/milena/mln/world/inter_pixel/full2image.hh
+++ b/scribo/primitive/extract/horizontal_separators.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -23,37 +23,44 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_WORLD_INTER_PIXEL_FULL2IMAGE_HH
-# define MLN_WORLD_INTER_PIXEL_FULL2IMAGE_HH
+#ifndef SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
+# define SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
/// \file
///
-/// Convert an inter-pixel image to a classical image.
+/// Extract vertical separators.
# include <mln/core/concept/image.hh>
-# include <mln/data/paste_without_localization.hh>
-# include <mln/geom/nsites.hh>
-# include <mln/world/inter_pixel/is_pixel.hh>
+# include <mln/arith/plus.hh>
+# include <scribo/primitive/extract/lines_v_pattern.hh>
-namespace mln
+
+namespace scribo
{
- namespace world
+ namespace primitive
{
- namespace inter_pixel
+ namespace extract
{
- /// Convert an inter-pixel image to a classical image.
- ///
- /// \param[in] input An inter-pixel image.
- ///
- /// \return A classical image without inter-pixel data.
- //
+ using namespace mln;
+
+ /// \brief Extract vertical separators.
+ /*!
+ *
+ * \param[in] input A binary image.
+ * \param[in] line_length The minimum line length.
+ *
+ * \return A binary image were separators are set to 'True'.
+ *
+ * \sa primitive::remove::separators
+ */
template <typename I>
mln_concrete(I)
- full2image(const Image<I>& input);
+ vertical_separators(const Image<I>& input, unsigned line_length);
+
# ifndef MLN_INCLUDE_ONLY
@@ -61,34 +68,28 @@ namespace mln
template <typename I>
mln_concrete(I)
- full2image(const Image<I>& input_)
+ vertical_separators(const Image<I>& input_, unsigned line_length)
{
- trace::entering("world::inter_pixel::full2image");
-
- mlc_is_a(mln_domain(I), Box)::check();
+ trace::entering("scribo::primitive::extract::vertical_separators");
const I& input = exact(input_);
+ mlc_is(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
- mln_domain(I) b(input.domain().pmin() / 2,
- input.domain().pmax() / 2);
- mln_concrete(I) output(b);
- mln_assertion(geom::nsites(output) == geom::nsites(input | is_pixel()));
+ mln_concrete(I)
+ vlines = extract::lines_v_pattern(input, line_length, 3);
- data::paste_without_localization(input | is_pixel(), output);
-
- trace::exiting("world::inter_pixel::full2image");
- return output;
+ trace::exiting("scribo::primitive::extract::vertical_separators");
+ return vlines;
}
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace scribo::primitive::extract
- } // end of namespace mln::world::inter_pixel
-
- } // end of namespace mln::world
+ } // end of namespace scribo::primitive
-} // end of namespace mln
+} // end of namespace scribo
-#endif // ! MLN_WORLD_INTER_PIXEL_FULL2IMAGE_HH
+#endif // ! SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
diff --git a/scribo/primitive/extract/lines_v_pattern.hh b/scribo/primitive/extract/separators.hh
similarity index 53%
copy from scribo/primitive/extract/lines_v_pattern.hh
copy to scribo/primitive/extract/separators.hh
index ccd21c5..2ba22b4 100644
--- a/scribo/primitive/extract/lines_v_pattern.hh
+++ b/scribo/primitive/extract/separators.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -23,21 +23,19 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_PRIMITIVE_EXTRACT_LINES_V_PATTERN_HH
-# define SCRIBO_PRIMITIVE_EXTRACT_LINES_V_PATTERN_HH
+#ifndef SCRIBO_PRIMITIVE_EXTRACT_SEPARATORS_HH
+# define SCRIBO_PRIMITIVE_EXTRACT_SEPARATORS_HH
/// \file
///
-/// Extract vertical lines matching a specific pattern.
+/// Extract vertical and horizontal separators.
-#include <mln/core/concept/image.hh>
-#include <mln/core/alias/window2d.hh>
+# include <mln/core/concept/image.hh>
+# include <mln/arith/plus.hh>
-# include <mln/win/hline2d.hh>
+# include <scribo/primitive/extract/lines_h_pattern.hh>
+# include <scribo/primitive/extract/lines_v_pattern.hh>
-# include <mln/morpho/dilation.hh>
-
-# include <scribo/primitive/extract/lines_pattern.hh>
namespace scribo
{
@@ -50,17 +48,20 @@ namespace scribo
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.
- //
+ /// \brief Extract vertical and horizontal separators.
+ /*!
+ *
+ * \param[in] input A binary image.
+ * \param[in] line_length The minimum line length.
+ *
+ * \return A binary image were separators are set to 'True'.
+ *
+ * \sa primitive::remove::separators
+ */
template <typename I>
mln_concrete(I)
- lines_v_pattern(const Image<I>& input, unsigned length, unsigned delta);
+ separators(const Image<I>& input, unsigned line_length);
+
# ifndef MLN_INCLUDE_ONLY
@@ -68,28 +69,21 @@ namespace scribo
template <typename I>
mln_concrete(I)
- lines_v_pattern(const Image<I>& input, unsigned length, unsigned delta)
+ separators(const Image<I>& input_, unsigned line_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);
-
- // FIXME: not generic.
- window2d win;
- mln_deduce(I, site, dpsite)
- dp1(0, -delta),
- dp2(0, delta);
- win.insert(dp1);
- win.insert(dp2);
-
- //FIXME: Add reconstruction instead of this arbitrary dilation.
- win::vline2d vwin(length/2 + 2);
-// win::vline2d vwin(length);
- return morpho::dilation(lines_pattern(input, length, 0, win), vwin);
-// return lines_pattern(input, length, 0, win);
+ trace::entering("scribo::primitive::extract::separators");
+
+ const I& input = exact(input_);
+ mlc_is(mln_value(I), bool)::check();
+ mln_precondition(input.is_valid());
+
+ mln_concrete(I)
+ hlines = extract::lines_h_pattern(input, line_length, 3),
+ vlines = extract::lines_v_pattern(input, line_length, 3);
+ hlines += vlines;
+
+ trace::exiting("scribo::primitive::extract::separators");
+ return hlines;
}
@@ -101,6 +95,4 @@ namespace scribo
} // end of namespace scribo
-
-#endif // ! SCRIBO_PRIMITIVE_EXTRACT_LINES_V_PATTERN_HH
-
+#endif // ! SCRIBO_PRIMITIVE_EXTRACT_SEPARATORS_HH
diff --git a/milena/mln/world/inter_pixel/full2image.hh b/scribo/primitive/extract/vertical_separators.hh
similarity index 53%
copy from milena/mln/world/inter_pixel/full2image.hh
copy to scribo/primitive/extract/vertical_separators.hh
index db3bcf3..9a6ea39 100644
--- a/milena/mln/world/inter_pixel/full2image.hh
+++ b/scribo/primitive/extract/vertical_separators.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -23,37 +23,44 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_WORLD_INTER_PIXEL_FULL2IMAGE_HH
-# define MLN_WORLD_INTER_PIXEL_FULL2IMAGE_HH
+#ifndef SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
+# define SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
/// \file
///
-/// Convert an inter-pixel image to a classical image.
+/// Extract vertical separators.
# include <mln/core/concept/image.hh>
-# include <mln/data/paste_without_localization.hh>
-# include <mln/geom/nsites.hh>
-# include <mln/world/inter_pixel/is_pixel.hh>
+# include <mln/arith/plus.hh>
+# include <scribo/primitive/extract/lines_v_pattern.hh>
-namespace mln
+
+namespace scribo
{
- namespace world
+ namespace primitive
{
- namespace inter_pixel
+ namespace extract
{
- /// Convert an inter-pixel image to a classical image.
- ///
- /// \param[in] input An inter-pixel image.
- ///
- /// \return A classical image without inter-pixel data.
- //
+ using namespace mln;
+
+ /// \brief Extract vertical separators.
+ /*!
+ *
+ * \param[in] input A binary image.
+ * \param[in] line_length The minimum line length.
+ *
+ * \return A binary image were separators are set to 'True'.
+ *
+ * \sa primitive::remove::separators
+ */
template <typename I>
mln_concrete(I)
- full2image(const Image<I>& input);
+ vertical_separators(const Image<I>& input, unsigned line_length);
+
# ifndef MLN_INCLUDE_ONLY
@@ -61,34 +68,28 @@ namespace mln
template <typename I>
mln_concrete(I)
- full2image(const Image<I>& input_)
+ vertical_separators(const Image<I>& input_, unsigned line_length)
{
- trace::entering("world::inter_pixel::full2image");
-
- mlc_is_a(mln_domain(I), Box)::check();
+ trace::entering("scribo::primitive::extract::vertical_separators");
const I& input = exact(input_);
+ mlc_is(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
- mln_domain(I) b(input.domain().pmin() / 2,
- input.domain().pmax() / 2);
- mln_concrete(I) output(b);
- mln_assertion(geom::nsites(output) == geom::nsites(input | is_pixel()));
+ mln_concrete(I)
+ vlines = extract::lines_v_pattern(input, line_length, 3);
- data::paste_without_localization(input | is_pixel(), output);
-
- trace::exiting("world::inter_pixel::full2image");
- return output;
+ trace::exiting("scribo::primitive::extract::vertical_separators");
+ return vlines;
}
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace scribo::primitive::extract
- } // end of namespace mln::world::inter_pixel
-
- } // end of namespace mln::world
+ } // end of namespace scribo::primitive
-} // end of namespace mln
+} // end of namespace scribo
-#endif // ! MLN_WORLD_INTER_PIXEL_FULL2IMAGE_HH
+#endif // ! SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
diff --git a/scribo/primitive/extract/lines_v_pattern.hh b/scribo/primitive/remove/separators.hh
similarity index 50%
copy from scribo/primitive/extract/lines_v_pattern.hh
copy to scribo/primitive/remove/separators.hh
index ccd21c5..9b45919 100644
--- a/scribo/primitive/extract/lines_v_pattern.hh
+++ b/scribo/primitive/remove/separators.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -23,21 +23,22 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_PRIMITIVE_EXTRACT_LINES_V_PATTERN_HH
-# define SCRIBO_PRIMITIVE_EXTRACT_LINES_V_PATTERN_HH
+#ifndef SCRIBO_PRIMITIVE_REMOVE_SEPARATORS_HH
+# define SCRIBO_PRIMITIVE_REMOVE_SEPARATORS_HH
/// \file
///
-/// Extract vertical lines matching a specific pattern.
+/// Remove separators in a binary image.
-#include <mln/core/concept/image.hh>
-#include <mln/core/alias/window2d.hh>
+# include <mln/core/concept/image.hh>
-# include <mln/win/hline2d.hh>
+# include <mln/core/routine/duplicate.hh>
-# include <mln/morpho/dilation.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/pw/all.hh>
+
+# include <mln/data/fill.hh>
-# include <scribo/primitive/extract/lines_pattern.hh>
namespace scribo
{
@@ -45,22 +46,26 @@ namespace scribo
namespace primitive
{
- namespace extract
+ namespace remove
{
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.
- //
+ /// \brief Remove separators in a binary image.
+ /*!
+ *
+ * \param[in] input A binary image. 'True' for objects, 'False'
+ * for the background.
+ * \param[in] separators A binary image of separators.
+ *
+ * \return \p input without separators.
+ *
+ * \sa primitive::extract::separators
+ */
template <typename I>
mln_concrete(I)
- lines_v_pattern(const Image<I>& input, unsigned length, unsigned delta);
+ separators(const Image<I>& input, const Image<I>& separators);
+
# ifndef MLN_INCLUDE_ONLY
@@ -68,39 +73,30 @@ namespace scribo
template <typename I>
mln_concrete(I)
- lines_v_pattern(const Image<I>& input, unsigned length, unsigned delta)
+ separators(const Image<I>& input_, const Image<I>& separators_)
{
- 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);
-
- // FIXME: not generic.
- window2d win;
- mln_deduce(I, site, dpsite)
- dp1(0, -delta),
- dp2(0, delta);
- win.insert(dp1);
- win.insert(dp2);
-
- //FIXME: Add reconstruction instead of this arbitrary dilation.
- win::vline2d vwin(length/2 + 2);
-// win::vline2d vwin(length);
- return morpho::dilation(lines_pattern(input, length, 0, win), vwin);
-// return lines_pattern(input, length, 0, win);
- }
+ trace::entering("scribo::primitive::remove::separators");
+
+ const I& input = exact(input_);
+ const I& separators = exact(separators_);
+ mlc_is(mln_value(I), bool)::check();
+ mln_precondition(input.is_valid());
+ mln_precondition(separators.is_valid());
+ mln_concrete(I) output = duplicate(input);
+ data::fill((output | (pw::value(separators) == pw::cst(true))).rw(),
+ false);
+
+ trace::exiting("scribo::primitive::remove::separators");
+ return output;
+ }
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace scribo::primitive::extract
+ } // end of namespace scribo::primitive::remove
} // end of namespace scribo::primitive
} // end of namespace scribo
-
-#endif // ! SCRIBO_PRIMITIVE_EXTRACT_LINES_V_PATTERN_HH
-
+#endif // ! SCRIBO_PRIMITIVE_REMOVE_SEPARATORS_HH
--
1.5.6.5
1
0
last-svn-commit-119-g28453cf postprocessing/fill_object_holes.hh: New routine.
by Guillaume Lazzara 03 Jun '10
by Guillaume Lazzara 03 Jun '10
03 Jun '10
---
scribo/ChangeLog | 12 ++-
.../fill_object_holes.hh} | 134 ++++++++++++++++----
2 files changed, 118 insertions(+), 28 deletions(-)
copy scribo/{filter/object_groups_with_holes.hh => postprocessing/fill_object_holes.hh} (65%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 4aa545d..97f15b8 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,11 +1,15 @@
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * postprocessing/fill_object_holes.hh: New routine.
+
+2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new routines to detect separators.
- * scribo/primitive/extract/horizontal_separators.hh,
- * scribo/primitive/extract/separators.hh,
- * scribo/primitive/extract/vertical_separators.hh,
- * scribo/primitive/remove/separators.hh: New.
+ * primitive/extract/horizontal_separators.hh,
+ * primitive/extract/separators.hh,
+ * primitive/extract/vertical_separators.hh,
+ * primitive/remove/separators.hh: New.
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/filter/object_groups_with_holes.hh b/scribo/postprocessing/fill_object_holes.hh
similarity index 65%
copy from scribo/filter/object_groups_with_holes.hh
copy to scribo/postprocessing/fill_object_holes.hh
index 570ae6a..4771844 100644
--- a/scribo/filter/object_groups_with_holes.hh
+++ b/scribo/postprocessing/fill_object_holes.hh
@@ -23,12 +23,16 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH
-# define SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH
+#ifndef SCRIBO_POSTPROCESSING_FILL_OBJECT_HOLES_HH
+# define SCRIBO_POSTPROCESSING_FILL_OBJECT_HOLES_HH
/// \file
///
-/// \brief Remove groups not having a minimum number of holes.
+/// \brief Fill-in object small holes.
+
+/// \FIXME share code with filter/object_groups_with_holes.hh
+/// \FIXME Merge the two following routines.
+/// \FIXME Use a size ratio in both overloads.
# include <sstream>
@@ -47,28 +51,32 @@
# include <mln/fun/i2v/array.hh>
# include <scribo/core/macros.hh>
-# include <scribo/core/component_set.hh>
+# include <scribo/core/object_groups.hh>
+# include <scribo/primitive/group/apply.hh>
namespace scribo
{
- namespace filter
+ namespace postprocessing
{
using namespace mln;
- /*! \brief Remove groups not having a minimum number of holes.
+ /*! \brief Fill-in object small holes.
+ */
+ template <typename I>
+ inline
+ mln_concrete(I)
+ fill_object_holes(const Image<I>& input, float ratio);
- */
template <typename L>
inline
object_groups<L>
- object_groups_with_holes(const object_groups<L>& components,
- unsigned min_size);
-
+ fill_object_holes(const object_groups<L>& groups,
+ unsigned min_size);
# ifndef MLN_INCLUDE_ONLY
@@ -124,7 +132,7 @@ namespace scribo
}
- } // end of namespace scribo::filter::internal
+ } // end of namespace scribo::postprocessing::internal
@@ -139,10 +147,10 @@ namespace scribo
template <typename L>
inline
object_groups<L>
- object_groups_with_holes(const object_groups<L>& groups,
+ fill_object_holes(const object_groups<L>& groups,
unsigned min_size)
{
- trace::entering("scribo::filter::impl::generic::object_groups_with_holes");
+ trace::entering("scribo::postprocessing::impl::generic::fill_object_holes");
// Grouping groups and relabel the underlying labeled image.
// Groups are now considered as components.
@@ -259,7 +267,7 @@ namespace scribo
if (kept == components.nelements())
{
- trace::exiting("scribo::filter::impl::generic::object_groups_with_holes");
+ trace::exiting("scribo::postprocessing::impl::generic::fill_object_holes");
return groups.duplicate();
}
@@ -269,15 +277,15 @@ namespace scribo
output(c) = 0;
- trace::exiting("scribo::filter::impl::generic::object_groups_with_holes");
+ trace::exiting("scribo::postprocessing::impl::generic::fill_object_holes");
return output;
}
}
- } // end of namespace scribo::filter::impl::generic
+ } // end of namespace scribo::postprocessing::impl::generic
- } // end of namespace scribo::filter::impl
+ } // end of namespace scribo::postprocessing::impl
@@ -286,25 +294,103 @@ namespace scribo
template <typename L>
inline
object_groups<L>
- object_groups_with_holes(const object_groups<L>& groups,
- unsigned min_size)
+ fill_object_holes(const object_groups<L>& groups,
+ unsigned min_size)
{
- trace::entering("scribo::filter::object_groups_with_holes");
+ trace::entering("scribo::postprocessing::fill_object_holes");
mln_precondition(groups.is_valid());
object_groups<L>
- output = impl::generic::object_groups_with_holes(groups, min_size);
+ output = impl::generic::fill_object_holes(groups, min_size);
+
+ trace::exiting("scribo::postprocessing::fill_object_holes");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ fill_object_holes(const Image<I>& input_, float ratio)
+ {
+ trace::entering("scribo::postprocessing::fill_object_holes");
+
+ mln_precondition(input.is_valid());
+ mlc_is(mln_value(I), bool)::check();
+
+ const I& input = exact(input_);
+ mln_concrete(I) output = duplicate(input);
+
+ typedef value::int_u16 L;
+ typedef mln_ch_value(I, L) Li;
+ typedef accu::math::count<mln_site(Li)> A;
+
+ typedef util::couple<Li, util::couple<util::array<unsigned>,
+ util::array<A> > > res_t;
+
+ // Holes card Image
+
+ std::cout << "> Holes card image" << std::endl;
+
+ L nlabels;
+
+ res_t res = labeling::blobs_and_compute(input, c8(), nlabels, A());
- trace::exiting("scribo::filter::object_groups_with_holes");
+ util::array<unsigned>& holes_card = res.second().first();
+ mln_ch_value(I, unsigned)
+ holes = data::transform(res.first(), holes_card);
+
+
+
+ // Threshold Image
+
+ std::cout << "> Threshold image" << std::endl;
+
+
+ I input_i = logical::not_(input);
+ res = labeling::blobs_and_compute(input_i, c8(), nlabels, A());
+
+ util::array<unsigned>& card = res.second().first();
+ for (unsigned i = 1; i < card.size(); ++i)
+ card(i) = card(i) * ratio;
+
+ mln_ch_value(I, unsigned)
+ thres = data::transform(res.first(), card);
+ thres = transform::influence_zone_geodesic(thres, c8());
+
+
+
+ // Thresholding
+
+ std::cout << "> Thresholding" << std::endl;
+
+ I hole_mask;
+ initialize(hole_mask, holes);
+ data::fill(hole_mask, false);
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (holes(p))
+ hole_mask(p) = holes(p) < thres(p);
+
+
+ // Cleanup
+
+ std::cout << "> Cleanup" << std::endl;
+
+ data::fill((output | pw::value(hole_mask)).rw(), false);
+
+
+ trace::exiting("scribo::postprocessing::fill_object_holes");
return output;
}
+
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace scribo::filter
+ } // end of namespace scribo::postprocessing
} // end of namespace scribo
-#endif // ! SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH
+#endif // ! SCRIBO_POSTPROCESSING_FILL_OBJECT_HOLES_HH
--
1.5.6.5
1
0
* src/text_in_article_pbm.cc: Update call to text::recognition.
* text/clean.hh: Resize text lines according to their x_height.
* text/extract_lines.hh: Update call to extract::components.
* text/merging.hh: Remove Debug.
* text/recognition.hh: Update call to text::clean and do
recognition only on lines considered as text.
* subsampling/bilinear.hh,
* upsampling/bs2x.hh: New.
---
scribo/ChangeLog | 18 +++++
scribo/src/text_in_article_pbm.cc | 147 +++++++++++++++++++------------------
scribo/subsampling/bilinear.hh | 114 ++++++++++++++++++++++++++++
scribo/text/clean.hh | 86 ++++++++++------------
scribo/text/extract_lines.hh | 6 +-
scribo/text/merging.hh | 30 ++++----
scribo/text/recognition.hh | 5 +-
scribo/upsampling/bs2x.hh | 147 +++++++++++++++++++++++++++++++++++++
8 files changed, 413 insertions(+), 140 deletions(-)
create mode 100644 scribo/subsampling/bilinear.hh
create mode 100644 scribo/upsampling/bs2x.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 97f15b8..f2850e0 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,23 @@
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Improve OCR recognition.
+
+ * src/text_in_article_pbm.cc: Update call to text::recognition.
+
+ * text/clean.hh: Resize text lines according to their x_height.
+
+ * text/extract_lines.hh: Update call to extract::components.
+
+ * text/merging.hh: Remove Debug.
+
+ * text/recognition.hh: Update call to text::clean and do
+ recognition only on lines considered as text.
+
+ * subsampling/bilinear.hh,
+ * upsampling/bs2x.hh: New.
+
+2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+
* postprocessing/fill_object_holes.hh: New routine.
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/src/text_in_article_pbm.cc b/scribo/src/text_in_article_pbm.cc
index 3f37529..e71d21b 100644
--- a/scribo/src/text_in_article_pbm.cc
+++ b/scribo/src/text_in_article_pbm.cc
@@ -48,12 +48,14 @@
#include <scribo/primitive/remove/separators.hh>
#include <scribo/primitive/link/merge_double_link.hh>
+#include <scribo/primitive/link/internal/dmax_width_and_height.hh>
#include <scribo/primitive/link/with_single_left_link_dmax_ratio.hh>
#include <scribo/primitive/link/with_single_right_link_dmax_ratio.hh>
#include <scribo/primitive/group/from_single_link.hh>
#include <scribo/filter/object_links_bbox_h_ratio.hh>
+#include <scribo/filter/objects_small.hh>
#include <scribo/debug/usage.hh>
@@ -71,6 +73,7 @@
#include <scribo/preprocessing/denoise_fg.hh>
+#include <scribo/io/xml/save_text_lines.hh>
// #include <mln/morpho/closing/structural.hh>
// #include <mln/win/rectangle2d.hh>
@@ -80,6 +83,7 @@ const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. 'False' for object, 'True'\
for the background." },
+ { "out.txt", "Text output" },
{ "denoise", "1 enables denoising, 0 disables it. (enabled by default)" },
{ "debug_dir", "Output directory for debug image" },
{0, 0}
@@ -95,8 +99,7 @@ int main(int argc, char* argv[])
return scribo::debug::usage(argv,
"Find text lines using left/right validation and display x-height in a binarized article.",
"input.pbm out.txt <denoise: 0|1> <debug_dir>",
- args_desc,
- "Text output.");
+ args_desc);
if (argc == 5)
scribo::make::internal::debug_filename_prefix = argv[4];
@@ -151,13 +154,19 @@ int main(int argc, char* argv[])
components.add_separators(separators);
// components.add_separators(whitespaces);
+ components = scribo::filter::components_small(components, 3);
+
/// Linking potential objects
std::cout << "Linking objects..." << std::endl;
object_links<L> left_link
- = primitive::link::with_single_left_link_dmax_ratio(components, 2);
+ = primitive::link::with_single_left_link_dmax_ratio(components,
+ primitive::link::internal::dmax_width_and_height(1),
+ anchor::MassCenter);
object_links<L> right_link
- = primitive::link::with_single_right_link_dmax_ratio(components, 2);
+ = primitive::link::with_single_right_link_dmax_ratio(components,
+ primitive::link::internal::dmax_width_and_height(1),
+ anchor::MassCenter);
// Validating left and right links.
object_links<L>
@@ -218,38 +227,38 @@ int main(int argc, char* argv[])
scribo::make::debug_filename("step1_looks_like_a_text_line.ppm"));
- // Bboxes + line infos
- {
- std::ofstream file(scribo::make::debug_filename("step1_bboxes_100p.txt").c_str());
- std::ofstream file_50p(scribo::make::debug_filename("step1_bboxes_50p.txt").c_str());
-
- for_all_lines(l, lines)
- if (lines(l).tag() != line::Merged
- && lines(l).tag() != line::Ignored
- && lines(l).tag() != line::Pathological)
- {
- file << lines(l).bbox().pmin().row() << " "
- << lines(l).bbox().pmin().col() << " "
- << lines(l).bbox().pmax().row() << " "
- << lines(l).bbox().pmax().col() << " "
- << lines(l).card() << " "
- << lines(l).baseline() << " "
- << lines(l).x_height() << " "
- << lines(l).meanline() << " "
- << lines(l).d_height() << " "
- << lines(l).a_height() << " "
- << lines(l).char_space() << " "
- << lines(l).char_width() << std::endl;
+// // Bboxes + line infos
+// {
+// std::ofstream file(scribo::make::debug_filename("step1_bboxes_100p.txt").c_str());
+// // std::ofstream file_50p(scribo::make::debug_filename("step1_bboxes_50p.txt").c_str());
- file_50p << lines(l).bbox().pmin().row() / 2 << " "
- << lines(l).bbox().pmin().col() / 2 << " "
- << lines(l).bbox().pmax().row() / 2 << " "
- << lines(l).bbox().pmax().col() / 2 << std::endl;
- }
+// for_all_lines(l, lines)
+// if (lines(l).tag() != line::Merged
+// && lines(l).tag() != line::Ignored
+// && lines(l).tag() != line::Pathological)
+// {
+// file << lines(l).bbox().pmin().row() << " "
+// << lines(l).bbox().pmin().col() << " "
+// << lines(l).bbox().pmax().row() << " "
+// << lines(l).bbox().pmax().col() << " "
+// << lines(l).card() << " "
+// << lines(l).baseline() << " "
+// << lines(l).x_height() << " "
+// << lines(l).meanline() << " "
+// << lines(l).d_height() << " "
+// << lines(l).a_height() << " "
+// << lines(l).char_space() << " "
+// << lines(l).char_width() << std::endl;
+
+// // file_50p << lines(l).bbox().pmin().row() / 2 << " "
+// // << lines(l).bbox().pmin().col() / 2 << " "
+// // << lines(l).bbox().pmax().row() / 2 << " "
+// // << lines(l).bbox().pmax().col() / 2 << std::endl;
+// }
- file.close();
- file_50p.close();
- }
+// file.close();
+// // file_50p.close();
+// }
// mean and base lines.
@@ -280,57 +289,49 @@ int main(int argc, char* argv[])
scribo::debug::save_bboxes_image(input, lines,
scribo::make::debug_filename("step2_bboxes.ppm"));
- //===== END OF DEBUG =====
-
+ {
+ std::ofstream file(scribo::make::debug_filename("step2_bboxes_100p.txt").c_str());
+// std::ofstream file_50p(scribo::make::debug_filename("step2_bboxes_50p.txt").c_str());
- scribo::text::recognition(lines, "fra", argv[2]);
+ for_all_lines(l, lines)
+ if (lines(l).tag() != line::Merged
+ && lines(l).tag() != line::Ignored
+ && lines(l).tag() != line::Pathological)
+ {
+ file << lines(l).bbox().pmin().row() << " "
+ << lines(l).bbox().pmin().col() << " "
+ << lines(l).bbox().pmax().row() << " "
+ << lines(l).bbox().pmax().col() << " "
+ << lines(l).card() << " "
+ << lines(l).baseline() << " "
+ << lines(l).x_height() << " "
+ << lines(l).meanline() << " "
+ << lines(l).d_height() << " "
+ << lines(l).a_height() << " "
+ << lines(l).char_space() << " "
+ << lines(l).char_width() << std::endl;
+// file_50p << lines(l).bbox().pmin().row() / 2 << " "
+// << lines(l).bbox().pmin().col() / 2 << " "
+// << lines(l).bbox().pmax().row() / 2 << " "
+// << lines(l).bbox().pmax().col() / 2 << std::endl;
+ }
-// // Display median character space.
-// {
-// image2d<value::rgb8> output = data::convert(value::rgb8(), input);
-// typedef mln::value::int_u<8> median_t;
-// typedef mln::accu::stat::median_h<median_t> accu_t;
-// util::array<accu_t>
-// lspace_med(static_cast<unsigned>(grouped_objects.nlabels()) + 1);
-
-// for_all_components(i, filtered_objects.bboxes())
-// if (groups_packed(i) != 0)
-// {
-// if (hratio_filtered_links(i) != i)
-// {
-// unsigned
-// space = filtered_objects.bbox(i).pmin().col() - filtered_objects.bbox(hratio_filtered_links(i)).pmax().col();
+ file.close();
+// file_50p.close();
+ }
-// lspace_med(groups_packed(i)).take(space);
-// }
-// }
+ //===== END OF DEBUG =====
-// std::cout << "Drawing median character space" << std::endl;
-// for_all_components(i, filtered_objects.bboxes())
-// if (groups_packed(i) != 0 && lspace_med(groups_packed(i)).card() > 1)
-// {
-// unsigned med = lspace_med(groups_packed(i)).to_result();
-// mln::draw::box(output, grouped_objects.bbox(groups_packed(i)),
-// literal::purple);
+ scribo::io::xml::save_text_lines(argv[1], lines, "out.xml");
-// point2d
-// beg = filtered_objects.bbox(i).pmax(),
-// end = beg;
-// beg.row() = filtered_objects.bbox(i).pmin().row();
-// mln::draw::line(output, beg, end, literal::cyan);
-// beg.col() += med;
-// end.col() += med;
-// mln::draw::line(output, beg, end, literal::cyan);
-// }
-// io::ppm::save(output, "median_wspace.ppm");
+ scribo::text::recognition(lines, "fra", argv[2]);
-// }
trace::exiting("main");
}
diff --git a/scribo/subsampling/bilinear.hh b/scribo/subsampling/bilinear.hh
new file mode 100644
index 0000000..cb95a11
--- /dev/null
+++ b/scribo/subsampling/bilinear.hh
@@ -0,0 +1,114 @@
+// Copyright (C) 2010 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_SUBSAMPLING_BILINEAR_HH
+# define SCRIBO_SUBSAMPLING_BILINEAR_HH
+
+/// \file
+///
+/// Bilinear subsampling.
+
+# include <mln/core/concept/image.hh>
+# include <mln/opt/at.hh>
+
+
+namespace scribo
+{
+
+ namespace subsampling
+ {
+
+
+ template <typename I>
+ mln_concrete(I)
+ bilinear(const Image<I>& input_, int sub_ratio);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I>
+ mln_concrete(I)
+ bilinear(const Image<I>& input_, int sub_ratio)
+ {
+ trace::entering("scribo::subsampling::bilinear");
+
+ const I& input = exact(input_);
+ mln_precondition(input.is_valid());
+ mlc_is(mln_domain(I), box2d)::check();
+
+ mln_concrete(I) output(input.domain().nrows() / sub_ratio,
+ input.domain().ncols() / sub_ratio);
+
+ std::cout << "output domain = " << output.domain() << std::endl;
+
+ mln_piter(I) p(output.domain());
+ mln_value(I) pixels[4];
+
+ def::coord
+ x_offset = input.domain().pmin().col(),
+ y_offset = input.domain().pmin().row();
+
+ for_all(p)
+ {
+ int x = round(-0.5 + p.col() * sub_ratio);
+ int y = round(-0.5 + p.row() * sub_ratio);
+
+ if (x < 0)
+ x = 0;
+ else if (x >= geom::max_col(input))
+ x = input.ncols() - 1;
+
+ if (y < 0)
+ y = 0;
+ else if (y >= geom::max_row(input))
+ y = input.nrows() - 1;
+
+ double dx = (p.col() * sub_ratio) - x;
+ double dy = (p.row() * sub_ratio) - y;
+
+ pixels[0] = opt::at(input, y + y_offset, x + x_offset);
+ pixels[1] = opt::at(input, y + y_offset, x + x_offset + 1);
+ pixels[2] = opt::at(input, y + y_offset + 1, x + x_offset);
+ pixels[3] = opt::at(input, y + y_offset + 1, x + x_offset + 1);
+
+ output(p) = pixels[0] * (1 - dx) * (1 - dy) + pixels[1] * dx * (1 - dy) +
+ pixels[2] * (1 - dx) * dy + pixels[3] * dx * dy;
+
+ }
+
+ trace::exiting("scribo::subsampling::bilinear");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace subsampling
+
+} // end of namespace scribo
+
+
+#endif // SCRIBO_SUBSAMPLING_BILINEAR_HH
diff --git a/scribo/text/clean.hh b/scribo/text/clean.hh
index ba200fc..fa31ebe 100644
--- a/scribo/text/clean.hh
+++ b/scribo/text/clean.hh
@@ -64,8 +64,9 @@
#include <mln/value/rgb8.hh>
#include <mln/io/pgm/all.hh>
-#include <sandbox/inim/2009/ocr/resize.hh>
-#include <sandbox/fabien/mln/upsampling/hq2x.hh>
+#include <scribo/upsampling/bs2x.hh>
+#include <scribo/subsampling/bilinear.hh>
+
namespace scribo
{
@@ -80,69 +81,60 @@ namespace scribo
///
/// \param[in] input_ A binary image. Object are set to 'false'
/// and backgroud to 'true'.
- /// \param[in] dmap_win_ A weighted window.
///
/// \return An image. The text have better quality.
//
- template <typename I, typename W>
+ template <typename L, typename I>
mln_concrete(I)
- clean(const Image<I>& input_, const Weighted_Window<W>& dmap_win_);
+ clean(const line_info<L>& line, const Image<I>& input_);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W>
+ template <typename L, typename I>
mln_concrete(I)
- clean(const Image<I>& input_, const Weighted_Window<W>& dmap_win_)
+ clean(const line_info<L>& line, const Image<I>& input_)
{
trace::entering("scribo::text::clean");
const I& input = exact(input_);
- const W& dmap_win = exact(dmap_win_);
mlc_bool(mln_site_(I)::dim == 2)::check();
mlc_equal(mln_value(I),bool)::check();
mln_precondition(input.is_valid());
- mln_precondition(dmap_win.is_valid());
- (void) dmap_win;
-
-
- // Resize
- typedef image2d<value::rgb8> J;
- J tmp = data::convert(value::rgb8(), input);
- J clarge = tmp;//mln::upsampling::hq2x(tmp); (FIXME: re-enable)
-
- //FIXME: not generic!
-// if (input.domain().pmax()[0] - input.domain().pmin()[0] <= 10)
-// clarge = mln::upsampling::hq4x(clarge);
-
- I input_large = data::convert(bool(), clarge);
-
- // Blur
- image2d<value::int_u8>
- blur = linear::gaussian(data::convert(value::int_u8(), input_large), 2);
-
- // Skeleton constraint
- I K = topo::skeleton::crest(input_large, blur, c8());
-
- // Skeleton
- I skel_on_gaussian =
- morpho::skeleton_constrained(input_large, c8(),
- topo::skeleton::is_simple_point<I,neighb2d>,
- extend(K, false), arith::revert(blur));
-
- // Dilation
- win::octagon2d oct(7);
- I dilate_on_gaussian = morpho::dilation(skel_on_gaussian, oct);
-
-// io::pgm::save(arith::revert(blur), "blur_revert.pgm");
-// io::pgm::save(blur, "gaussian.pgm");
-// io::pbm::save(input_large, mln::debug::filename("input_large_4x.pbm"));
-// io::pbm::save(K, mln::debug::filename("K.pbm"));
-// io::pbm::save(skel_on_gaussian, mln::debug::filename("skeleton_on_gaussian.pbm"));
-// io::pbm::save(dilate_on_gaussian, mln::debug::filename("dilation_on_gaussian.pbm"));
+ mln_precondition(line.is_valid());
+
+ mln_concrete(I) output = duplicate(input);
+
+ if (line.x_height() < 5) // Non significative text/remaining lines...
+ return output;
+
+ float fact = line.x_height() / 40.0f;
+ std::cout << fact << " - " << output.domain() << std::endl;
+ if (fact < 1)
+ {
+ std::cout << "Upsampling..." << " - "
+ << std::ceil(fact) << std::endl;
+ while (fact < 1)
+ {
+ output = scribo::upsampling::bs2x(output); // 2x upsampling
+ fact *= 2.0f;
+// std::cout << "fact = " << fact
+// << " - output.domain = " << output.domain()
+// << std::endl;
+ }
+ }
+ else if (fact > 2.5f)
+ {
+ std::cout << "subsampling::bilinear" << " - "
+ << std::ceil(fact) << std::endl;
+ output = subsampling::bilinear(output, std::ceil(fact - 0.5)); // math::floor instead?
+
+ }
+ else
+ std::cout << "not cleaning text. Seems ok." << std::endl;
trace::exiting("scribo::text::clean");
- return dilate_on_gaussian;
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/text/extract_lines.hh b/scribo/text/extract_lines.hh
index 44dca50..c720d70 100644
--- a/scribo/text/extract_lines.hh
+++ b/scribo/text/extract_lines.hh
@@ -47,7 +47,7 @@
# include <mln/util/graph.hh>
# include <mln/value/label_16.hh>
-# include <scribo/primitive/extract/objects.hh>
+# include <scribo/primitive/extract/components.hh>
# include <scribo/primitive/group/apply.hh>
# include <scribo/primitive/link/with_several_left_links.hh>
# include <scribo/primitive/link/with_several_right_links.hh>
@@ -75,7 +75,7 @@ namespace scribo
** \param[in,out] nbboxes Will hold the number of bounding boxes
** at the end of the routine.
**
- ** \return An object image with grouped potential text objects.
+ ** \return An object image with grouped potential text components.
*/
template <typename I, typename N, typename V>
object_image(mln_ch_value(I,V))
@@ -103,7 +103,7 @@ namespace scribo
typedef mln_ch_value(I,V) L;
typedef object_image(L) text_t;
- text_t text = scribo::primitive::extract::objects(input, nbh, nbboxes);
+ text_t text = scribo::primitive::extract::components(input, nbh, nbboxes);
# ifndef SCRIBO_NDEBUG
debug::save_bboxes_image(input, text.bboxes(), literal::red,
diff --git a/scribo/text/merging.hh b/scribo/text/merging.hh
index e509475..b29e63f 100644
--- a/scribo/text/merging.hh
+++ b/scribo/text/merging.hh
@@ -800,21 +800,21 @@ namespace scribo
(void) ith_pass;
- if (ith_pass == 1)
- {
- mln::io::pgm::save(log, "log_1.pgm");
- mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_1e.pgm");
- }
- else if (ith_pass == 2)
- {
- mln::io::pgm::save(log, "log_2.pgm");
- mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_2e.pgm");
- }
- else if (ith_pass == 3)
- {
- mln::io::pgm::save(log, "log_3.pgm");
- mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_3e.pgm");
- }
+// if (ith_pass == 1)
+// {
+// mln::io::pgm::save(log, "log_1.pgm");
+// mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_1e.pgm");
+// }
+// else if (ith_pass == 2)
+// {
+// mln::io::pgm::save(log, "log_2.pgm");
+// mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_2e.pgm");
+// }
+// else if (ith_pass == 3)
+// {
+// mln::io::pgm::save(log, "log_3.pgm");
+// mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_3e.pgm");
+// }
}
diff --git a/scribo/text/recognition.hh b/scribo/text/recognition.hh
index 5927d44..72df1e2 100644
--- a/scribo/text/recognition.hh
+++ b/scribo/text/recognition.hh
@@ -128,11 +128,12 @@ namespace scribo
/// Use text bboxes with Tesseract
for_all_lines(i, lines)
{
- if (! lines(i).is_valid())
+ if (! lines(i).is_valid() || lines(i).tag() != line::None || lines(i).type() != line::Text)
continue;
std::cout << "Text recognition... ("
<< i << "/" << lines.nelements() << ")" << std::endl;
+ std::cout << "x_height = " << lines(i).x_height() << std::endl;
mln_domain(I) box = lines(i).bbox();
// Make sure characters are isolated from the borders.
@@ -157,7 +158,7 @@ namespace scribo
/// Improve text quality.
/// text_ima_cleaned domain is larger than text_ima's.
- I text_ima_cleaned = text::clean(text_ima, dmap_win);
+ I text_ima_cleaned = text::clean(lines(i), text_ima);
mln::io::pbm::save(text_ima_cleaned, mln::debug::filename("line.pbm", debug_id++));
// Setting objects to 'True'
diff --git a/scribo/upsampling/bs2x.hh b/scribo/upsampling/bs2x.hh
new file mode 100644
index 0000000..6ff8546
--- /dev/null
+++ b/scribo/upsampling/bs2x.hh
@@ -0,0 +1,147 @@
+// Copyright (C) 2010 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_UPSAMPLING_BS2X_HH
+# define SCRIBO_UPSAMPLING_BS2X_HH
+
+/// \file
+///
+/// Scale 2x algorithm for binary images.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/alias/box2d.hh>
+# include <mln/opt/at.hh>
+# include <mln/geom/all.hh>
+
+
+
+namespace scribo
+{
+
+ namespace upsampling
+ {
+ using namespace mln;
+
+
+ /// \brief Scale 2x algorithm for binary images.
+ ///
+ //
+ template <typename I>
+ mln_concrete(I)
+ bs2x(const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I>
+ mln_concrete(I)
+ bs2x(const mln::Image<I>& input_)
+ {
+ trace::entering("scribo::upsampling::bs2x");
+
+ const I& input = exact(input_);
+
+ mlc_is(mln_domain(I), mln::box2d)::check();
+ mlc_is(mln_value(I), bool)::check();
+
+ mln_precondition(input.is_valid());
+
+ typedef mln_value(I) V;
+
+ def::coord
+ mrow = geom::min_row(input),
+ mcol = geom::min_col(input);
+
+
+ mln_piter(I) p(input.domain());
+ mln_concrete(I) output(mln::make::box2d(mrow, mcol,
+ mrow + 2 * input.nrows() - 1,
+ mcol + 2 * input.ncols() - 1));
+ for_all(p)
+ {
+ def::coord
+ row = mrow + 2 * (p.row() - mrow),
+ col = mcol + 2 * (p.col() - mcol);
+
+ if(p.row() == geom::min_row(input)
+ || p.col() == geom::min_col(input)
+ || p.row() == geom::max_row(input)
+ || p.col() == geom::max_col(input))
+ {
+ mln::box2d b = mln::make::box2d(row, col,
+ row + 1, col + 1);
+ V value = opt::at(input, p.row(), p.col());
+
+ data::fill((output | b).rw(), value);
+ }
+ else
+ {
+ // nw n ne
+ //
+ // w value e
+ //
+ // sw s se
+
+ V n = input(p + mln::up),
+ s = input(p + mln::down),
+ e = input(p + mln::right),
+ w = input(p + mln::left),
+ nw = input(p + mln::up_left),
+ ne = input(p + mln::up_right),
+ sw = input(p + mln::down_left),
+ se = input(p + mln::down_right),
+ value = input(p);
+
+ if(e != w && n != s)
+ {
+ opt::at(output, row, col) = (w == n &&((se != nw) || !value)) ? w : value;
+ opt::at(output, row, col + 1) = (e == n &&((sw != ne) || !value)) ? e : value;
+ opt::at(output, row + 1, col) = (w == s &&((ne != sw) || !value)) ? w : value;
+ opt::at(output, row + 1, col + 1) = (e == s &&((nw != se) || !value)) ? e : value;
+ }
+ else
+ {
+ mln::box2d b = mln::make::box2d(row, col,
+ row + 1, col + 1);
+ data::fill((output | b).rw(), value);
+ }
+ }
+ }
+
+ trace::exiting("scribo::upsampling::bs2x");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace upsampling
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_UPSAMPLING_BS2X_HH
--
1.5.6.5
1
0
03 Jun '10
* scribo/src/Makefile.am: Add a new target.
* scribo/src/text_in_article_preprocess.cc: New.
* scribo/src/text_in_article_pbm.cc: Add optional cropping and
makes the debug optionnal.
* scribo/text/clean.hh: Improve cleanup.
* scribo/text/recognition.hh: Remove last '\n' in Tesseract's
output.
---
scribo/ChangeLog | 16 ++
scribo/src/Makefile.am | 9 +
scribo/src/text_in_article_pbm.cc | 162 +++++++++++++-------
...sauvola_ms.cc => text_in_article_preprocess.cc} | 90 +++++-------
scribo/text/clean.hh | 13 +-
scribo/text/recognition.hh | 14 ++-
6 files changed, 184 insertions(+), 120 deletions(-)
copy scribo/src/{binarization/fg_sauvola_ms.cc => text_in_article_preprocess.cc} (53%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f2850e0..59f9e67 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,19 @@
+2010-05-04 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Prepare DIA tools for Nuxeo/XWiki.
+
+ * scribo/src/Makefile.am: Add a new target.
+
+ * scribo/src/text_in_article_preprocess.cc: New.
+
+ * scribo/src/text_in_article_pbm.cc: Add optional cropping and
+ makes the debug optionnal.
+
+ * scribo/text/clean.hh: Improve cleanup.
+
+ * scribo/text/recognition.hh: Remove last '\n' in Tesseract's
+ output.
+
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
Improve OCR recognition.
diff --git a/scribo/src/Makefile.am b/scribo/src/Makefile.am
index 80dc782..08b4bd9 100644
--- a/scribo/src/Makefile.am
+++ b/scribo/src/Makefile.am
@@ -82,6 +82,15 @@ if HAVE_TIFF
text_in_article_pbm_SOURCES = text_in_article_pbm.cc
+ bin_PROGRAMS += text_in_article_preprocess
+ text_in_article_preprocess_CPPFLAGS = $(AM_CPPFLAGS) \
+ `Magick++-config --cppflags`
+ text_in_article_preprocess_LDFLAGS = $(AM_LDFLAGS) \
+ -lpthread `Magick++-config --libs`
+ text_in_article_preprocess_SOURCES = text_in_article_preprocess.cc
+
+
+
bin_PROGRAMS += text_in_photo_fast
text_in_photo_fast_SOURCES = text_in_photo_fast.cc
text_in_photo_fast_CPPFLAGS = $(AM_CPPFLAGS) \
diff --git a/scribo/src/text_in_article_pbm.cc b/scribo/src/text_in_article_pbm.cc
index e71d21b..20a18e9 100644
--- a/scribo/src/text_in_article_pbm.cc
+++ b/scribo/src/text_in_article_pbm.cc
@@ -40,6 +40,8 @@
#include <mln/value/rgb8.hh>
#include <mln/value/label_16.hh>
+#include <mln/data/paste_without_localization.hh>
+
#include <scribo/core/line_set.hh>
#include <scribo/primitive/extract/components.hh>
@@ -85,6 +87,10 @@ const char *args_desc[][2] =
for the background." },
{ "out.txt", "Text output" },
{ "denoise", "1 enables denoising, 0 disables it. (enabled by default)" },
+ { "pmin_row", "Row index of the top left corner of the Region of interest." },
+ { "pmin_col", "Col index of the top left corner of the Region of interest." },
+ { "pmax_row", "Row index of the bottom right corner of the Region of interest." },
+ { "pmax_col", "Col index of the bottom right corner of the Region of interest." },
{ "debug_dir", "Output directory for debug image" },
{0, 0}
};
@@ -95,14 +101,20 @@ int main(int argc, char* argv[])
using namespace scribo;
using namespace mln;
- if (argc != 3 && argc != 4 && argc != 5)
+ if (argc != 3 && argc != 4 && argc != 5 && argc != 8 && argc != 9)
return scribo::debug::usage(argv,
"Find text lines using left/right validation and display x-height in a binarized article.",
- "input.pbm out.txt <denoise: 0|1> <debug_dir>",
+ "input.pbm out.txt <denoise: 0|1> [<pmin_row> <pmin_col> <pmax_row> <pmax_col>] <debug_dir>",
args_desc);
- if (argc == 5)
- scribo::make::internal::debug_filename_prefix = argv[4];
+ bool debug = false;
+
+ // Enable debug output.
+ if (argc == 5 || argc == 9)
+ {
+ scribo::make::internal::debug_filename_prefix = argv[argc - 1];
+ debug = true;
+ }
trace::entering("main");
@@ -110,6 +122,27 @@ int main(int argc, char* argv[])
image2d<bool> input;
mln::io::pbm::load(input, argv[1]);
+
+ // Optional Cropping
+ if (argc >= 8)
+ {
+ def::coord
+ minr = atoi(argv[4]),
+ minc = atoi(argv[5]),
+ maxr = atoi(argv[6]),
+ maxc = atoi(argv[7]);
+
+ box2d roi = mln::make::box2d(minr, minc, maxr, maxc);
+ image2d<bool> tmp(maxr - minr + 1, maxc - minc + 1);
+ data::paste_without_localization(input | roi, tmp);
+ input = tmp;
+
+ if (debug)
+ mln::io::pbm::save(input,
+ scribo::make::debug_filename("input_cropped.pbm"));
+ }
+
+
typedef value::label_16 V;
typedef image2d<V> L;
@@ -129,7 +162,9 @@ int main(int argc, char* argv[])
// whitespaces += separators;
- mln::io::pbm::save(separators, "vseparators.pbm");
+ if (debug)
+ mln::io::pbm::save(separators,
+ scribo::make::debug_filename("vseparators.pbm"));
// mln::io::pbm::save(whitespaces, "separators.pbm");
// mln::io::pbm::save(input_cleaned, "input_no_separators.pbm");
@@ -214,18 +249,20 @@ int main(int argc, char* argv[])
//===== DEBUG =====
- // Bboxes image.
- scribo::debug::save_bboxes_image(input, lines,
- scribo::make::debug_filename("step1_bboxes.ppm"));
+ if (debug)
+ {
- // Bboxes enlarged
- mln::io::ppm::save(scribo::debug::bboxes_enlarged_image(input, lines),
- scribo::make::debug_filename("step1_bboxes_enlarged.ppm"));
+ // Bboxes image.
+ scribo::debug::save_bboxes_image(input, lines,
+ scribo::make::debug_filename("step1_bboxes.ppm"));
- // Looks like a text line
- mln::io::ppm::save(scribo::debug::looks_like_a_text_line_image(input, lines),
- scribo::make::debug_filename("step1_looks_like_a_text_line.ppm"));
+ // Bboxes enlarged
+ mln::io::ppm::save(scribo::debug::bboxes_enlarged_image(input, lines),
+ scribo::make::debug_filename("step1_bboxes_enlarged.ppm"));
+ // Looks like a text line
+ mln::io::ppm::save(scribo::debug::looks_like_a_text_line_image(input, lines),
+ scribo::make::debug_filename("step1_looks_like_a_text_line.ppm"));
// // Bboxes + line infos
// {
@@ -261,10 +298,11 @@ int main(int argc, char* argv[])
// }
- // mean and base lines.
- mln::io::ppm::save(scribo::debug::mean_and_base_lines_image(input, lines),
- scribo::make::debug_filename("step1_x_height.ppm"));
+ // mean and base lines.
+ mln::io::ppm::save(scribo::debug::mean_and_base_lines_image(input, lines),
+ scribo::make::debug_filename("step1_x_height.ppm"));
+ }
//===== END OF DEBUG =====
@@ -277,56 +315,62 @@ int main(int argc, char* argv[])
//===== DEBUG =====
- // mean and base lines.
- mln::io::ppm::save(scribo::debug::mean_and_base_lines_image(input, lines),
- scribo::make::debug_filename("step2_x_height.ppm"));
+ if (debug)
+ {
- // Looks like a text line
- mln::io::ppm::save(scribo::debug::looks_like_a_text_line_image(input, lines),
- scribo::make::debug_filename("step2_looks_like_a_text_line.ppm"));
+ // mean and base lines.
+ mln::io::ppm::save(scribo::debug::mean_and_base_lines_image(input, lines),
+ scribo::make::debug_filename("step2_x_height.ppm"));
- // Bboxes image.
- scribo::debug::save_bboxes_image(input, lines,
- scribo::make::debug_filename("step2_bboxes.ppm"));
+ // Looks like a text line
+ mln::io::ppm::save(scribo::debug::looks_like_a_text_line_image(input, lines),
+ scribo::make::debug_filename("step2_looks_like_a_text_line.ppm"));
+ // Bboxes image.
+ scribo::debug::save_bboxes_image(input, lines,
+ scribo::make::debug_filename("step2_bboxes.ppm"));
- {
- std::ofstream file(scribo::make::debug_filename("step2_bboxes_100p.txt").c_str());
-// std::ofstream file_50p(scribo::make::debug_filename("step2_bboxes_50p.txt").c_str());
-
- for_all_lines(l, lines)
- if (lines(l).tag() != line::Merged
- && lines(l).tag() != line::Ignored
- && lines(l).tag() != line::Pathological)
- {
- file << lines(l).bbox().pmin().row() << " "
- << lines(l).bbox().pmin().col() << " "
- << lines(l).bbox().pmax().row() << " "
- << lines(l).bbox().pmax().col() << " "
- << lines(l).card() << " "
- << lines(l).baseline() << " "
- << lines(l).x_height() << " "
- << lines(l).meanline() << " "
- << lines(l).d_height() << " "
- << lines(l).a_height() << " "
- << lines(l).char_space() << " "
- << lines(l).char_width() << std::endl;
-
-// file_50p << lines(l).bbox().pmin().row() / 2 << " "
-// << lines(l).bbox().pmin().col() / 2 << " "
-// << lines(l).bbox().pmax().row() / 2 << " "
-// << lines(l).bbox().pmax().col() / 2 << std::endl;
- }
-
- file.close();
-// file_50p.close();
- }
+ }
- //===== END OF DEBUG =====
+
+// {
+// std::ofstream file(scribo::make::debug_filename("step2_bboxes_100p.txt").c_str());
+// // std::ofstream file_50p(scribo::make::debug_filename("step2_bboxes_50p.txt").c_str());
+
+// for_all_lines(l, lines)
+// if (lines(l).tag() != line::Merged
+// && lines(l).tag() != line::Ignored
+// && lines(l).tag() != line::Pathological)
+// {
+// file << lines(l).bbox().pmin().row() << " "
+// << lines(l).bbox().pmin().col() << " "
+// << lines(l).bbox().pmax().row() << " "
+// << lines(l).bbox().pmax().col() << " "
+// << lines(l).card() << " "
+// << lines(l).baseline() << " "
+// << lines(l).x_height() << " "
+// << lines(l).meanline() << " "
+// << lines(l).d_height() << " "
+// << lines(l).a_height() << " "
+// << lines(l).char_space() << " "
+// << lines(l).char_width() << std::endl;
+
+// // file_50p << lines(l).bbox().pmin().row() / 2 << " "
+// // << lines(l).bbox().pmin().col() / 2 << " "
+// // << lines(l).bbox().pmax().row() / 2 << " "
+// // << lines(l).bbox().pmax().col() / 2 << std::endl;
+// }
+
+// file.close();
+// // file_50p.close();
+// }
+
+
+ //===== END OF DEBUG =====
- scribo::io::xml::save_text_lines(argv[1], lines, "out.xml");
+ scribo::io::xml::save_text_lines(argv[1], lines, "out.xml");
diff --git a/scribo/src/binarization/fg_sauvola_ms.cc b/scribo/src/text_in_article_preprocess.cc
similarity index 53%
copy from scribo/src/binarization/fg_sauvola_ms.cc
copy to scribo/src/text_in_article_preprocess.cc
index 9c606d6..8cfa82f 100644
--- a/scribo/src/binarization/fg_sauvola_ms.cc
+++ b/scribo/src/text_in_article_preprocess.cc
@@ -1,5 +1,4 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -24,82 +23,69 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
+
+#include <libgen.h>
+#include <iostream>
+
#include <mln/core/image/image2d.hh>
-#include <mln/value/rgb8.hh>
+
#include <mln/io/magick/load.hh>
#include <mln/io/pbm/save.hh>
-#include <scribo/binarization/sauvola_ms.hh>
-#include <scribo/preprocessing/split_bg_fg.hh>
-#include <scribo/debug/usage.hh>
+#include <mln/value/rgb8.hh>
-bool check_args(int argc, char * argv[])
-{
- if (argc != 7)
- return false;
+#include <mln/logical/not.hh>
- int s = atoi(argv[4]);
+#include <scribo/binarization/sauvola_ms.hh>
- if (s < 2 || s > 3)
- {
- std::cout << "s must be set to 2 or 3."
- << std::endl;
- return false;
- }
+#include <scribo/debug/usage.hh>
+
+#include <scribo/preprocessing/split_bg_fg.hh>
- return true;
-}
const char *args_desc[][2] =
{
{ "input.*", "An image." },
- { "output.pbm", "A binary image." },
- { "lambda", "Lambda used to split bg/fg." },
- { "w", "Window size at scale 1. (Common value: 101)" },
- { "s", "First subsampling ratio (Common value: 3)." },
- { "min_area", "Minimum object area at scale 1 (Common value: 67)" },
+ { "output.pbm", "A text file with all the recognized text" },
+ { "enable fg/bg", "If set to 1 enables foreground extraction. (disabled by default)" },
+ { "lambda", "Lambda used in remove fg/bg (Automaticaly deduced by default)." },
{0, 0}
};
-
-
-int main(int argc, char *argv[])
+int main(int argc, char* argv[])
{
- using namespace mln;
using namespace scribo;
+ using namespace mln;
- if (!check_args(argc, argv))
+ if (argc != 3 && argc != 4 && argc != 5)
return scribo::debug::usage(argv,
- "Multi-Scale Binarization based on Sauvola's algorithm. Performs a binarization on each component of the color image and merges the results.",
- "input.* output.pbm w s area_threshold",
+ "Find text in a color document.",
+ "input.* output.pbm <enable fg/bg> <lambda>",
args_desc);
- trace::entering("main");
-
- unsigned lambda = atoi(argv[2]);
+ image2d<value::rgb8> input_rgb;
+ io::magick::load(input_rgb, argv[1]);
- // Window size
- unsigned w_1 = atoi(argv[3]); // Scale 1
+ unsigned lambda;
+ if (argc == 5)
+ lambda = atoi(argv[4]);
+ else
+ lambda = 1.2 * (input_rgb.nrows() + input_rgb.ncols());
- // First subsampling scale.
- unsigned s = atoi(argv[4]);
-
- // Lambda value
- unsigned lambda_min_1 = atoi(argv[5]);
-
-
- image2d<value::rgb8> input_1;
- io::magick::load(input_1, argv[1]);
+ // Extract foreground
+ if (argc == 4 && atoi(argv[3]) == 1)
+ {
+ std::cout << "Extracting foreground..." << std::endl;
+ input_rgb = preprocessing::split_bg_fg(input_rgb, lambda, 32).second();
+ }
- image2d<value::rgb8>
- fg = scribo::preprocessing::split_bg_fg(input_1, lambda, 32).first();
+ // Binarize foreground to use it in the processing chain.
+ std::cout << "Binarizing foreground..." << std::endl;
+ image2d<bool> input = scribo::binarization::sauvola_ms(input_rgb, 101, 3);
- image2d<bool>
- output = scribo::binarization::sauvola_ms(fg, w_1, s, lambda_min_1, SCRIBO_DEFAULT_SAUVOLA_K);
+ logical::not_inplace(input);
- io::pbm::save(output, argv[6]);
+ mln::io::pbm::save(input, argv[2]);
}
-
-
diff --git a/scribo/text/clean.hh b/scribo/text/clean.hh
index fa31ebe..f93bc6f 100644
--- a/scribo/text/clean.hh
+++ b/scribo/text/clean.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -113,14 +114,14 @@ namespace scribo
if (fact < 1)
{
std::cout << "Upsampling..." << " - "
- << std::ceil(fact) << std::endl;
- while (fact < 1)
+ << fact << std::endl;
+ while (fact < 0.90)
{
output = scribo::upsampling::bs2x(output); // 2x upsampling
fact *= 2.0f;
-// std::cout << "fact = " << fact
-// << " - output.domain = " << output.domain()
-// << std::endl;
+// std::cout << "fact = " << fact
+// << " - output.domain = " << output.domain()
+// << std::endl;
}
}
else if (fact > 2.5f)
diff --git a/scribo/text/recognition.hh b/scribo/text/recognition.hh
index 72df1e2..6f9dac7 100644
--- a/scribo/text/recognition.hh
+++ b/scribo/text/recognition.hh
@@ -159,7 +159,7 @@ namespace scribo
/// text_ima_cleaned domain is larger than text_ima's.
I text_ima_cleaned = text::clean(lines(i), text_ima);
- mln::io::pbm::save(text_ima_cleaned, mln::debug::filename("line.pbm", debug_id++));
+// mln::io::pbm::save(text_ima_cleaned, mln::debug::filename("line.pbm", debug_id++));
// Setting objects to 'True'
logical::not_inplace(text_ima_cleaned);
@@ -182,7 +182,11 @@ namespace scribo
{
std::cerr << s << std::endl;
if (output_file != 0)
- file << lines(i).bbox() << " " << s << std::endl;
+ {
+ std::string str(s);
+ str = str.substr(0, str.length() - 1);
+ file << lines(i).bbox() << " " << str;
+ }
}
// The string has been allocated by Tesseract. We must free it.
@@ -241,7 +245,11 @@ namespace scribo
{
std::cout << s << std::endl;
if (output_file != 0)
- file << line.domain() << " " << s << std::endl;
+ {
+ std::string str(s);
+ str = str.substr(0, str.length() - 1);
+ file << line.domain() << " " << str;
+ }
}
// The string has been allocated by Tesseract. We must free it.
--
1.5.6.5
1
0
03 Jun '10
---
scribo/ChangeLog | 17 ++++++++++-------
scribo/text/merging.hh | 2 +-
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 59f9e67..67159ad 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,18 +1,21 @@
2010-05-04 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * text/merging.hh: Disable some debug.
+
+2010-05-04 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Prepare DIA tools for Nuxeo/XWiki.
- * scribo/src/Makefile.am: Add a new target.
+ * src/Makefile.am: Add a new target.
- * scribo/src/text_in_article_preprocess.cc: New.
+ * src/text_in_article_preprocess.cc: New.
- * scribo/src/text_in_article_pbm.cc: Add optional cropping and
- makes the debug optionnal.
+ * src/text_in_article_pbm.cc: Add optional cropping and makes the
+ debug optionnal.
- * scribo/text/clean.hh: Improve cleanup.
+ * text/clean.hh: Improve cleanup.
- * scribo/text/recognition.hh: Remove last '\n' in Tesseract's
- output.
+ * text/recognition.hh: Remove last '\n' in Tesseract's output.
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/text/merging.hh b/scribo/text/merging.hh
index b29e63f..5309b10 100644
--- a/scribo/text/merging.hh
+++ b/scribo/text/merging.hh
@@ -606,7 +606,7 @@ namespace scribo
if (lines(mc).type() == line::Text) // included in a text line => weird
{
++count_txtline_IN_txtline;
- std::cout << "weird: inclusion of a txt_line in a txt_line!" << std::endl;
+// std::cout << "weird: inclusion of a txt_line in a txt_line!" << std::endl;
/// Merge is perform if the current line is a
/// petouille considered as a line.
--
1.5.6.5
1
0
last-svn-commit-100-gd10f1a6 Add new Sauvola overloads and update examples.
by Guillaume Lazzara 03 Jun '10
by Guillaume Lazzara 03 Jun '10
03 Jun '10
* scribo/binarization/internal/first_pass_functor.hh,
* scribo/binarization/local_threshold.hh,
* scribo/binarization/sauvola.hh,
* scribo/binarization/sauvola_ms.hh,
* scribo/binarization/sauvola_ms_split.hh,
* scribo/binarization/sauvola_threshold_image.hh,
* scribo/canvas/integral_browsing.hh: Add more parameters to
Sauvola routines.
* scribo/binarization/sauvola_threshold_image_debug.hh: New. New
overload providing debug outputs.
* scribo/debug/usage.hh: Remove a parameter.
* scribo/src/binarization/Makefile.am,
* scribo/src/binarization/pgm_global_threshold_auto.cc,
* scribo/src/binarization/pgm_sauvola.cc,
* scribo/src/binarization/pgm_sauvola_ms.cc,
* scribo/src/binarization/ppm_fg_sauvola_ms.cc,
* scribo/src/binarization/ppm_sauvola.cc,
* scribo/src/binarization/ppm_sauvola_ms.cc,
* scribo/src/binarization/ppm_sauvola_ms_split.cc: Add new
program arguments.
* scribo/src/binarization/fg_sauvola_ms.cc,
* scribo/src/binarization/sauvola.cc,
* scribo/src/binarization/sauvola_ms.cc,
* scribo/src/binarization/sauvola_ms_split.cc,
* scribo/src/binarization/sauvola_debug.cc: New.
---
scribo/ChangeLog | 34 +++
scribo/binarization/internal/first_pass_functor.hh | 22 +-
scribo/binarization/local_threshold.hh | 3 -
scribo/binarization/sauvola.hh | 61 ++++-
scribo/binarization/sauvola_ms.hh | 132 +++++----
scribo/binarization/sauvola_ms_split.hh | 29 ++-
scribo/binarization/sauvola_threshold_image.hh | 128 +++++----
...d_image.hh => sauvola_threshold_image_debug.hh} | 309 ++++++++------------
scribo/canvas/integral_browsing.hh | 13 -
scribo/debug/usage.hh | 13 +-
.../{ppm_fg_sauvola_ms.cc => fg_sauvola_ms.cc} | 15 +-
.../src/binarization/pgm_global_threshold_auto.cc | 3 +-
scribo/src/binarization/pgm_sauvola.cc | 28 ++-
scribo/src/binarization/pgm_sauvola_ms.cc | 53 +++-
scribo/src/binarization/ppm_fg_sauvola_ms.cc | 58 +++--
scribo/src/binarization/ppm_sauvola.cc | 38 ++-
scribo/src/binarization/ppm_sauvola_ms.cc | 57 +++--
scribo/src/binarization/ppm_sauvola_ms_split.cc | 65 +++--
.../binarization/{pgm_sauvola.cc => sauvola.cc} | 39 ++-
scribo/src/binarization/sauvola_debug.cc | 105 +++++++
.../{ppm_sauvola_ms.cc => sauvola_ms.cc} | 64 +++--
...ppm_sauvola_ms_split.cc => sauvola_ms_split.cc} | 71 ++++--
scribo/src/preprocessing/to_pgm.cc | 46 +++
23 files changed, 863 insertions(+), 523 deletions(-)
copy scribo/binarization/{sauvola_threshold_image.hh => sauvola_threshold_image_debug.hh} (55%)
copy scribo/src/binarization/{ppm_fg_sauvola_ms.cc => fg_sauvola_ms.cc} (87%)
copy scribo/src/binarization/{pgm_sauvola.cc => sauvola.cc} (68%)
create mode 100644 scribo/src/binarization/sauvola_debug.cc
copy scribo/src/binarization/{ppm_sauvola_ms.cc => sauvola_ms.cc} (61%)
copy scribo/src/binarization/{ppm_sauvola_ms_split.cc => sauvola_ms_split.cc} (64%)
create mode 100644 scribo/src/preprocessing/to_pgm.cc
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 50f9d86..34a258f 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,37 @@
+2010-04-13 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add new Sauvola overloads and update examples.
+
+ * scribo/binarization/internal/first_pass_functor.hh,
+ * scribo/binarization/local_threshold.hh,
+ * scribo/binarization/sauvola.hh,
+ * scribo/binarization/sauvola_ms.hh,
+ * scribo/binarization/sauvola_ms_split.hh,
+ * scribo/binarization/sauvola_threshold_image.hh,
+ * scribo/canvas/integral_browsing.hh: Add more parameters to
+ Sauvola routines.
+
+ * scribo/binarization/sauvola_threshold_image_debug.hh: New. New
+ overload providing debug outputs.
+
+ * scribo/debug/usage.hh: Remove a parameter.
+
+ * scribo/src/binarization/Makefile.am,
+ * scribo/src/binarization/pgm_global_threshold_auto.cc,
+ * scribo/src/binarization/pgm_sauvola.cc,
+ * scribo/src/binarization/pgm_sauvola_ms.cc,
+ * scribo/src/binarization/ppm_fg_sauvola_ms.cc,
+ * scribo/src/binarization/ppm_sauvola.cc,
+ * scribo/src/binarization/ppm_sauvola_ms.cc,
+ * scribo/src/binarization/ppm_sauvola_ms_split.cc: Add new
+ program arguments.
+
+ * scribo/src/binarization/fg_sauvola_ms.cc,
+ * scribo/src/binarization/sauvola.cc,
+ * scribo/src/binarization/sauvola_ms.cc,
+ * scribo/src/binarization/sauvola_ms_split.cc,
+ * scribo/src/binarization/sauvola_debug.cc: New.
+
2010-03-29 Guillaume Lazzara <z(a)lrde.epita.fr>
Add support for various image types in text_in_photo_fast.
diff --git a/scribo/binarization/internal/first_pass_functor.hh b/scribo/binarization/internal/first_pass_functor.hh
index df4c025..3455060 100644
--- a/scribo/binarization/internal/first_pass_functor.hh
+++ b/scribo/binarization/internal/first_pass_functor.hh
@@ -68,12 +68,12 @@ namespace scribo
unsigned n_nbhs;
util::array<int> dp;
- static const double one_k = 1 - 0.34;
- static const double k_R = 0.34 / 128.0;
+ double K_;
- first_pass_functor(const I& input)
+ first_pass_functor(const I& input, double K)
: input(input),
- pxl(input)
+ pxl(input),
+ K_(K)
{
res = 0;
pxl.start();
@@ -96,17 +96,9 @@ namespace scribo
unsigned p = pxl.offset();
- // Use an inlined and developed version of sauvola's
- // threshold formula.
-// value::int_u8 t_p = mean * (one_k + k_R * stddev);
-
-// std::cout << t_p << ", ";
-
-// std::cout << input.element(p) << " - " << t_p << std::endl;
- value::int_u8 t_p = sauvola_threshold_formula(mean, stddev);
-
-// std::cout << input.point_at_index(p)
-// << " - " << sauvola_threshold_formula(mean, stddev);
+ value::int_u8 t_p = sauvola_threshold_formula(mean, stddev,
+ K_,
+ SCRIBO_DEFAULT_SAUVOLA_R);
msk.element(p) = input.element(p) < t_p;
diff --git a/scribo/binarization/local_threshold.hh b/scribo/binarization/local_threshold.hh
index ea5b34e..aa53664 100644
--- a/scribo/binarization/local_threshold.hh
+++ b/scribo/binarization/local_threshold.hh
@@ -200,9 +200,6 @@ namespace scribo
internal::local_threshold_tests(input, threshold);
-
-
-
mln_ch_value(I, bool)
output = internal::local_threshold_dispatch(input, threshold);
diff --git a/scribo/binarization/sauvola.hh b/scribo/binarization/sauvola.hh
index c3a0cce..6dd812b 100644
--- a/scribo/binarization/sauvola.hh
+++ b/scribo/binarization/sauvola.hh
@@ -55,6 +55,23 @@ namespace scribo
\input[in] input An image.
\input[in] window_size The window size.
+ \input[in] K Sauvola's formulae constant.
+
+ \return A binary image.
+
+ */
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola(const Image<I>& input, unsigned window_size, double K);
+
+
+
+ /*! \brief Convert an image into a binary image.
+
+ Sauvola's formulae constant K is set to 0.34.
+
+ \input[in] input An image.
+ \input[in] window_size The window size.
\return A binary image.
@@ -84,7 +101,7 @@ namespace scribo
template <typename I>
mln_ch_value(I, bool)
- sauvola(const Image<I>& input, unsigned window_size)
+ sauvola(const Image<I>& input, unsigned window_size, double K)
{
trace::entering("scribo::binarization::impl::generic::sauvola");
mln_precondition(exact(input).is_valid());
@@ -92,7 +109,8 @@ namespace scribo
mln_ch_value(I, bool)
output = local_threshold(input,
binarization::sauvola_threshold_image(input,
- window_size));
+ window_size,
+ K));
trace::exiting("scribo::binarization::impl::generic::sauvola");
return output;
@@ -103,7 +121,7 @@ namespace scribo
template <typename I>
mln_ch_value(I, bool)
- sauvola_rgb8(const Image<I>& input, unsigned window_size)
+ sauvola_rgb8(const Image<I>& input, unsigned window_size, double K)
{
trace::entering("scribo::binarization::impl::generic::sauvola");
mln_precondition(exact(input).is_valid());
@@ -114,7 +132,8 @@ namespace scribo
mln_ch_value(I, bool)
output = local_threshold(gima,
binarization::sauvola_threshold_image(gima,
- window_size));
+ window_size,
+ K));
trace::exiting("scribo::binarization::impl::generic::sauvola");
return output;
@@ -132,26 +151,29 @@ namespace scribo
template <typename I>
mln_ch_value(I, bool)
sauvola_dispatch(const mln_value(I)&,
- const Image<I>& input, unsigned window_size)
+ const Image<I>& input, unsigned window_size,
+ double K)
{
- return impl::generic::sauvola(input, window_size);
+ return impl::generic::sauvola(input, window_size, K);
}
template <typename I>
mln_ch_value(I, bool)
sauvola_dispatch(const value::rgb8&,
- const Image<I>& input, unsigned window_size)
+ const Image<I>& input, unsigned window_size,
+ double K)
{
- return impl::sauvola_rgb8(input, window_size);
+ return impl::sauvola_rgb8(input, window_size, K);
}
template <typename I>
mln_ch_value(I, bool)
- sauvola_dispatch(const Image<I>& input, unsigned window_size)
+ sauvola_dispatch(const Image<I>& input, unsigned window_size,
+ double K)
{
typedef mln_value(I) V;
- return sauvola_dispatch(V(), input, window_size);
+ return sauvola_dispatch(V(), input, window_size, K);
}
} // end of namespace scribo::binarization::internal
@@ -162,6 +184,22 @@ namespace scribo
template <typename I>
mln_ch_value(I, bool)
+ sauvola(const Image<I>& input, unsigned window_size, double K)
+ {
+ trace::entering("scribo::binarization::sauvola");
+
+ mln_precondition(exact(input).is_valid());
+
+ mln_ch_value(I, bool)
+ output = internal::sauvola_dispatch(input, window_size, K);
+
+ trace::exiting("scribo::binarization::sauvola");
+ return output;
+ }
+
+
+ template <typename I>
+ mln_ch_value(I, bool)
sauvola(const Image<I>& input, unsigned window_size)
{
trace::entering("scribo::binarization::sauvola");
@@ -169,7 +207,8 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_ch_value(I, bool)
- output = internal::sauvola_dispatch(input, window_size);
+ output = internal::sauvola_dispatch(input, window_size,
+ SCRIBO_DEFAULT_SAUVOLA_K);
trace::exiting("scribo::binarization::sauvola");
return output;
diff --git a/scribo/binarization/sauvola_ms.hh b/scribo/binarization/sauvola_ms.hh
index 2717770..6e70e04 100644
--- a/scribo/binarization/sauvola_ms.hh
+++ b/scribo/binarization/sauvola_ms.hh
@@ -54,6 +54,9 @@
# include <mln/extension/adjust.hh>
+// FIXME: to be removed later...
+# include <mln/io/pgm/save.hh>
+
# include <scribo/subsampling/integral_single_image.hh>
# include <scribo/core/macros.hh>
@@ -81,6 +84,7 @@ namespace scribo
\param[in] w_1 The window size used to compute stats.
\param[in] s The scale factor used for the first subscaling.
\param[in] lambda_min_1 Size of the objects kept at scale 1.
+ \param[in] K Sauvola's formulae parameter.
\p w_1 and \p lambda_min_1 are expressed according to the image
@@ -90,6 +94,14 @@ namespace scribo
*/
template <typename I>
mln_ch_value(I,bool)
+ sauvola_ms(const Image<I>& input_1_, unsigned w_1,
+ unsigned s, unsigned lambda_min_1, double K);
+
+ /// \overload
+ /// K is set to 0.34.
+ //
+ template <typename I>
+ mln_ch_value(I,bool)
sauvola_ms(const Image<I>& input_1, unsigned w_1,
unsigned s, unsigned lambda_min_1);
@@ -105,6 +117,11 @@ namespace scribo
using namespace mln;
+
+ // FIXME: to be removed later...
+ char* scale_image_output = 0;
+
+
template <typename V>
V my_find_root(image2d<V>& parent, const V& x)
{
@@ -120,7 +137,8 @@ namespace scribo
unsigned lambda_min, unsigned lambda_max,
unsigned s,
unsigned q, unsigned i, unsigned w,
- const image2d<util::couple<double,double> >& integral_sum_sum_2)
+ const image2d<util::couple<double,double> >& integral_sum_sum_2,
+ double K)
{
typedef image2d<int_u8> I;
typedef point2d P;
@@ -133,15 +151,30 @@ namespace scribo
w_local_h = w_local,
w_local_w = w_local;
+ // Make sure the window fits in the image domain.
+ if (w >= static_cast<const unsigned>(integral_sum_sum_2.ncols()))
+ {
+ w_local_w = std::min(integral_sum_sum_2.ncols(), integral_sum_sum_2.nrows()) - integral_sum_sum_2.border();
+ w_local_h = w_local_w;
+ trace::warning("integral_browsing - Adjusting window width since it was larger than image width.");
+ }
+ if (w_local_h >= static_cast<const unsigned>(integral_sum_sum_2.nrows()))
+ {
+ w_local_h = std::min(integral_sum_sum_2.nrows(), integral_sum_sum_2.ncols()) - integral_sum_sum_2.border();
+ w_local_w = w_local_h;
+ trace::warning("integral_browsing - Adjusting window height since it was larger than image height.");
+ }
+
if (! (w_local % 2))
{
--w_local_w;
++w_local_h;
}
+
// 1st pass
scribo::binarization::internal::first_pass_functor< image2d<int_u8> >
- f(sub);
+ f(sub, K);
scribo::canvas::integral_browsing(integral_sum_sum_2,
ratio,
w_local_w, w_local_h,
@@ -757,7 +790,7 @@ namespace scribo
template <typename I>
mln_ch_value(I,bool)
sauvola_ms(const Image<I>& input_1_, unsigned w_1,
- unsigned s, unsigned lambda_min_1)
+ unsigned s, double K)
{
trace::entering("scribo::binarization::sauvola_ms");
@@ -768,6 +801,8 @@ namespace scribo
dpoint2d none(0, 0);
+ unsigned lambda_min_1 = w_1 / 2;
+
// Number of subscales.
unsigned nb_subscale = 3;
@@ -820,7 +855,7 @@ namespace scribo
// Subsampling to scale 3 and 4.
for (unsigned i = 3; i <= nb_subscale + 1; ++i)
- sub_ima.append(mln::subsampling::antialiased(sub_ima[i - 1], q, none,
+ sub_ima.append(mln::subsampling::antialiased(sub_ima[i - 1], q,
sub_domains[i].first(),
sub_domains[i].second()));
@@ -840,7 +875,8 @@ namespace scribo
mln_max(unsigned),
s,
q, i, w_work,
- integral_sum_sum_2);
+ integral_sum_sum_2,
+ K);
}
// Other scales -> maximum and minimum component size.
@@ -854,7 +890,8 @@ namespace scribo
lambda_max_2 / ratio,
s,
q, i, w_work,
- integral_sum_sum_2);
+ integral_sum_sum_2,
+ K);
}
}
@@ -863,13 +900,17 @@ namespace scribo
t_ima[2] = internal::compute_t_n_and_e_2(sub_ima[2], e_2, 0,
lambda_max_2,
s, 1, 2, w_work,
- integral_sum_sum_2);
+ integral_sum_sum_2,
+ K);
}
// Propagate scale values.
e_2 = transform::influence_zone_geodesic(e_2, c8());
+ // FIXME: Remove or make it better...
+ if (internal::scale_image_output)
+ io::pgm::save(e_2, internal::scale_image_output);
// Binarize
image2d<bool>
@@ -885,7 +926,7 @@ namespace scribo
template <typename I>
mln_ch_value(I,bool)
sauvola_ms_rgb8(const Image<I>& input_1_, unsigned w_1,
- unsigned s, unsigned lambda_min_1)
+ unsigned s, double K)
{
const I& input_1 = exact(input_1_);
@@ -893,54 +934,7 @@ namespace scribo
gima = data::transform(input_1, mln::fun::v2v::rgb_to_int_u<8>());
mln_ch_value(I, bool)
- output = generic::sauvola_ms(gima, w_1, s, lambda_min_1);
-
-
-// typedef mln_ch_value(I,bool) bin_t;
-
-
-// mln_ch_value(I, value::int_u8) r_i, g_i, b_i;
-
-// // Split the rgb8 image into 3 intensity images.
-// mln::data::split(input_1, r_i, g_i, b_i);
-
-// bin_t r_b, g_b, b_b;
-
-// r_b = generic::sauvola_ms(r_i, w_1, s, lambda_min_1);
-// g_b = generic::sauvola_ms(g_i, w_1, s, lambda_min_1);
-// b_b = generic::sauvola_ms(b_i, w_1, s, lambda_min_1);
-
-// border::resize(r_b, input_1.border());
-// border::resize(g_b, input_1.border());
-// border::resize(b_b, input_1.border());
-
-// bin_t output;
-// initialize(output, input_1);
-
-// typedef bool * b_ptr_t;
-// b_ptr_t
-// out_ptr = output.buffer(),
-// r_ptr = r_b.buffer(),
-// g_ptr = g_b.buffer(),
-// b_ptr = b_b.buffer();
-
-// unsigned ntrue;
-// for (unsigned n = 0; n < output.nelements(); ++n)
-// {
-// ntrue = 0;
-// if (*r_ptr)
-// ++ntrue;
-// if (*g_ptr)
-// ++ntrue;
-// if (*b_ptr)
-// ++ntrue;
-
-// *out_ptr++ = ntrue > 1;;
-
-// ++r_ptr;
-// ++g_ptr;
-// ++b_ptr;
-// }
+ output = generic::sauvola_ms(gima, w_1, s, K);
return output;
}
@@ -959,9 +953,9 @@ namespace scribo
mln_ch_value(I,bool)
sauvola_ms_dispatch(const mln_value(I)&,
const Image<I>& input_1, unsigned w_1,
- unsigned s, unsigned lambda_min_1)
+ unsigned s, double K)
{
- return impl::generic::sauvola_ms(input_1, w_1, s, lambda_min_1);
+ return impl::generic::sauvola_ms(input_1, w_1, s, K);
}
@@ -970,19 +964,19 @@ namespace scribo
mln_ch_value(I,bool)
sauvola_ms_dispatch(const value::rgb8&,
const Image<I>& input_1, unsigned w_1,
- unsigned s, unsigned lambda_min_1)
+ unsigned s, double K)
{
- return impl::sauvola_ms_rgb8(input_1, w_1, s, lambda_min_1);
+ return impl::sauvola_ms_rgb8(input_1, w_1, s, K);
}
template <typename I>
mln_ch_value(I,bool)
sauvola_ms_dispatch(const Image<I>& input_1, unsigned w_1,
- unsigned s, unsigned lambda_min_1)
+ unsigned s, double K)
{
typedef mln_value(I) V;
- return sauvola_ms_dispatch(V(), input_1, w_1, s, lambda_min_1);
+ return sauvola_ms_dispatch(V(), input_1, w_1, s, K);
}
@@ -995,20 +989,28 @@ namespace scribo
template <typename I>
mln_ch_value(I,bool)
sauvola_ms(const Image<I>& input_1_, unsigned w_1,
- unsigned s, unsigned lambda_min_1)
+ unsigned s, double K)
{
trace::entering("scribo::binarization::sauvola_ms");
- mln_precondition(input_1.is_valid());
+ mln_precondition(exact(input_1_).is_valid());
mln_ch_value(I,bool)
- output = internal::sauvola_ms_dispatch(input_1_, w_1, s, lambda_min_1);
+ output = internal::sauvola_ms_dispatch(input_1_, w_1, s, K);
trace::exiting("scribo::binarization::sauvola_ms");
return output;
}
+ template <typename I>
+ mln_ch_value(I,bool)
+ sauvola_ms(const Image<I>& input_1, unsigned w_1, unsigned s)
+ {
+ return sauvola_ms(input_1, w_1, s, SCRIBO_DEFAULT_SAUVOLA_K);
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/binarization/sauvola_ms_split.hh b/scribo/binarization/sauvola_ms_split.hh
index cba5d94..de8517c 100644
--- a/scribo/binarization/sauvola_ms_split.hh
+++ b/scribo/binarization/sauvola_ms_split.hh
@@ -61,6 +61,7 @@ namespace scribo
\param[in] min_ntrue A site is set to 'True' in the output if it
is set to 'True' at least \p min_ntrue
components. Possible values: 1, 2, 3.
+ \param[in] K Sauvola's formula parameter.
\p w_1 and \p lambda_min_1 are expressed according to the image
at scale 0, i.e. the original size.
@@ -70,16 +71,27 @@ namespace scribo
template <typename I>
mln_ch_value(I, bool)
sauvola_ms_split(const Image<I>& input_1_, unsigned w_1,
+ unsigned s, unsigned lambda_min_1, unsigned min_ntrue,
+ double K);
+
+
+ /// \overload
+ /// K is set to 0.34.
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola_ms_split(const Image<I>& input_1_, unsigned w_1,
unsigned s, unsigned lambda_min_1, unsigned min_ntrue);
+
# ifndef MLN_INCLUDE_ONLY
template <typename I>
mln_ch_value(I, bool)
sauvola_ms_split(const Image<I>& input_1_, unsigned w_1,
- unsigned s, unsigned lambda_min_1, unsigned min_ntrue)
+ unsigned s, unsigned lambda_min_1, unsigned min_ntrue,
+ double K)
{
trace::entering("scribo::binarization::sauvola_ms_split");
@@ -97,9 +109,9 @@ namespace scribo
bin_t r_b, g_b, b_b;
- r_b = impl::generic::sauvola_ms(r_i, w_1, s, lambda_min_1);
- g_b = impl::generic::sauvola_ms(g_i, w_1, s, lambda_min_1);
- b_b = impl::generic::sauvola_ms(b_i, w_1, s, lambda_min_1);
+ r_b = impl::generic::sauvola_ms(r_i, w_1, s, lambda_min_1, K);
+ g_b = impl::generic::sauvola_ms(g_i, w_1, s, lambda_min_1, K);
+ b_b = impl::generic::sauvola_ms(b_i, w_1, s, lambda_min_1, K);
border::resize(r_b, input_1.border());
border::resize(g_b, input_1.border());
@@ -138,6 +150,15 @@ namespace scribo
}
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola_ms_split(const Image<I>& input_1, unsigned w_1,
+ unsigned s, unsigned lambda_min_1, unsigned min_ntrue)
+ {
+ return sauvola_ms_split(input_1, w_1, s, lambda_min_1, min_ntrue,
+ SCRIBO_DEFAULT_SAUVOLA_K);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::binarization
diff --git a/scribo/binarization/sauvola_threshold_image.hh b/scribo/binarization/sauvola_threshold_image.hh
index b5bc72d..88b3842 100644
--- a/scribo/binarization/sauvola_threshold_image.hh
+++ b/scribo/binarization/sauvola_threshold_image.hh
@@ -47,10 +47,24 @@
# include <mln/fun/v2v/rgb_to_int_u.hh>
-# include <mln/debug/println.hh>
-
# include <scribo/core/init_integral_image.hh>
+
+
+// Setup default Sauvola's formulae parameters values.
+// These macros may be used in other variant of Sauvola's algorithm.
+//
+// Values are set according to the following reference: "Automatic
+// Evaluation of Document Binarization Results", Badekas and al, 2005
+//
+// Badekas et al. said 0.34 was best.
+# define SCRIBO_DEFAULT_SAUVOLA_K 0.34
+//
+// 128 is best for grayscale documents.
+# define SCRIBO_DEFAULT_SAUVOLA_R 128
+
+
+
namespace scribo
{
@@ -73,11 +87,18 @@ namespace scribo
template <typename I, typename J>
mln_ch_value(I, value::int_u8)
sauvola_threshold_image(const Image<I>& input, unsigned window_size,
+ double K,
Image<J>& simple,
Image<J>& squared);
+ /// \overload
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold_image(const Image<I>& input, unsigned window_size,
+ double K);
/// \overload
+ /// K is set to 0.34
template <typename I>
mln_ch_value(I, value::int_u8)
sauvola_threshold_image(const Image<I>& input, unsigned window_size);
@@ -113,9 +134,9 @@ namespace scribo
inline
double
sauvola_threshold_formula(const double m_x_y, const double s_x_y,
- const double k, const double R)
+ const double K, const double R)
{
- return m_x_y * (1.0 + k * ((s_x_y / R) - 1.0));
+ return m_x_y * (1.0 + K * ((s_x_y / R) - 1.0));
}
@@ -125,13 +146,9 @@ namespace scribo
double
sauvola_threshold_formula(double m_x_y, double s_x_y)
{
- // Badekas et al. said 0.34 was best.
- const double k = 0.34;
-
- // 128 is best for grayscale documents.
- const double R = 128;
-
- return sauvola_threshold_formula(m_x_y, s_x_y, k, R);
+ return sauvola_threshold_formula(m_x_y, s_x_y,
+ SCRIBO_DEFAULT_SAUVOLA_K,
+ SCRIBO_DEFAULT_SAUVOLA_R);
}
@@ -155,7 +172,7 @@ namespace scribo
compute_sauvola_threshold(const P& p,
const J& simple,
const J& squared,
- int win_width, double k, double R)
+ int win_width, double K, double R)
{
mln_precondition(simple.nrows() == squared.nrows());
mln_precondition(simple.ncols() == squared.ncols());
@@ -191,7 +208,7 @@ namespace scribo
double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
// Thresholding.
- double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, k, R);
+ double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R);
return t_x_y;
}
@@ -201,7 +218,8 @@ namespace scribo
double
compute_sauvola_threshold_single_image(const P& p,
const J& integral,
- int win_width)
+ int win_width,
+ double K, double R)
{
// Window half width.
int w_2 = win_width >> 1;
@@ -234,7 +252,7 @@ namespace scribo
double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
// Thresholding.
- double t_x_y = m_x_y * (1.0 + 0.34 * ((s_x_y / 128) - 1.0));
+ double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R);
return t_x_y;
}
@@ -248,13 +266,9 @@ namespace scribo
const J& squared,
int win_width)
{
- // Badekas et al. said 0.34 was best.
- const double k = 0.34;
-
- // 128 is best for grayscale documents.
- const double R = 128;
-
- return compute_sauvola_threshold(p, simple, squared, win_width, k, R);
+ return compute_sauvola_threshold(p, simple, squared, win_width,
+ SCRIBO_DEFAULT_SAUVOLA_K,
+ SCRIBO_DEFAULT_SAUVOLA_R);
}
@@ -285,6 +299,7 @@ namespace scribo
inline
mln_concrete(I)
sauvola_threshold_image(const Image<I>& input_, unsigned window_size,
+ double K,
Image<J>& simple_,
Image<J>& squared_)
{
@@ -313,7 +328,9 @@ namespace scribo
for(def::coord col = 0; col < ncols; ++col)
output.at_(row, col)
= internal::compute_sauvola_threshold(P(row, col), simple,
- squared, window_size);
+ squared, window_size,
+ K,
+ SCRIBO_DEFAULT_SAUVOLA_R);
trace::exiting("scribo::binarization::impl::generic::sauvola_threshold");
return output;
@@ -327,10 +344,11 @@ namespace scribo
inline
mln_concrete(I)
sauvola_threshold_image_gl(const I& input, unsigned window_size,
- Image<J>& simple,
- Image<J>& squared)
+ double K,
+ Image<J>& simple,
+ Image<J>& squared)
{
- return impl::generic::sauvola_threshold_image(input, window_size,
+ return impl::generic::sauvola_threshold_image(input, window_size, K,
simple, squared);
}
@@ -339,6 +357,7 @@ namespace scribo
inline
mln_ch_value(I, value::int_u8)
sauvola_threshold_image_rgb8(const I& input, unsigned window_size,
+ double K,
Image<J>& simple,
Image<J>& squared)
{
@@ -350,6 +369,7 @@ namespace scribo
mln_ch_value(I, value::int_u8)
output = impl::generic::sauvola_threshold_image(gima, window_size,
+ K,
simple, squared);
trace::exiting("scribo::binarization::impl::sauvola_threshold_image_rgb8");
@@ -372,10 +392,12 @@ namespace scribo
mln_ch_value(I, value::int_u<n>)
sauvola_threshold_image_dispatch(const value::int_u<n>&, const I& input,
unsigned window_size,
+ double K,
J& simple,
J& squared)
{
- return impl::sauvola_threshold_image_gl(input, window_size, simple, squared);
+ return impl::sauvola_threshold_image_gl(input, window_size, K,
+ simple, squared);
}
template <typename I, typename J>
@@ -383,11 +405,12 @@ namespace scribo
mln_ch_value(I, value::int_u8)
sauvola_threshold_image_dispatch(const value::rgb8&, const I& input,
unsigned window_size,
+ double K,
J& simple,
J& squared)
{
return impl::sauvola_threshold_image_rgb8(input, window_size,
- simple, squared);
+ K, simple, squared);
}
template <typename I, typename J>
@@ -395,6 +418,7 @@ namespace scribo
mln_ch_value(I, value::int_u8)
sauvola_threshold_image_dispatch(const mln_value(I)&, const I& input,
unsigned window_size,
+ double K,
J& simple,
J& squared)
{
@@ -413,37 +437,21 @@ namespace scribo
template <typename I, typename J>
mln_ch_value(I, value::int_u8)
sauvola_threshold_image(const Image<I>& input, unsigned window_size,
- Image<J>& simple,
- Image<J>& squared)
+ double K,
+ Image<J>& simple,
+ Image<J>& squared)
{
trace::entering("scribo::binarization::sauvola_threshold_image");
mln_precondition(mln_site_(I)::dim == 2);
mln_precondition(exact(input).is_valid());
-
-// {
-// J& simple_ = exact(simple);
-// J& squared_ = exact(squared);
-// mln_piter(J) p(simple_.domain());
-// for_all(p)
-// {
-// std::cout << simple_(p) << ", ";
-// }
-// std::cout << std::endl << " ------- " << std::endl;
-// for_all(p)
-// {
-// std::cout << squared_(p) << ", ";
-// }
-// std::cout << std::endl << " ------- " << std::endl;
-// }
-
-
-
typedef mln_value(I) value_t;
mln_ch_value(I, value::int_u8)
- output = internal::sauvola_threshold_image_dispatch(value_t(), exact(input),
+ output = internal::sauvola_threshold_image_dispatch(value_t(),
+ exact(input),
window_size,
+ K,
exact(simple),
exact(squared));
@@ -455,19 +463,25 @@ namespace scribo
template <typename I>
inline
mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size)
+ sauvola_threshold_image(const Image<I>& input, unsigned window_size,
+ double K)
{
mln_ch_value(I, double)
simple = init_integral_image(input, scribo::internal::identity_),
squared = init_integral_image(input, scribo::internal::square_);
-// debug::println(input);
-// std::cout << "============" << std::endl;
-// // debug::println(simple);
-// // std::cout << "============" << std::endl;
-// // debug::println(squared);
+ return sauvola_threshold_image(input, window_size,
+ K, simple, squared);
+ }
+
- return sauvola_threshold_image(input, window_size, simple, squared);
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold_image(const Image<I>& input, unsigned window_size)
+ {
+ return sauvola_threshold_image(input, window_size,
+ SCRIBO_DEFAULT_SAUVOLA_K);
}
diff --git a/scribo/binarization/sauvola_threshold_image.hh b/scribo/binarization/sauvola_threshold_image_debug.hh
similarity index 55%
copy from scribo/binarization/sauvola_threshold_image.hh
copy to scribo/binarization/sauvola_threshold_image_debug.hh
index b5bc72d..18216a6 100644
--- a/scribo/binarization/sauvola_threshold_image.hh
+++ b/scribo/binarization/sauvola_threshold_image_debug.hh
@@ -24,8 +24,8 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_HH
-# define SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_HH
+#ifndef SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_DEBUG_HH
+# define SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_DEBUG_HH
/// \file
///
@@ -47,9 +47,23 @@
# include <mln/fun/v2v/rgb_to_int_u.hh>
-# include <mln/debug/println.hh>
-
# include <scribo/core/init_integral_image.hh>
+# include <scribo/binarization/sauvola_threshold_image.hh>
+
+
+// Setup default Sauvola's formulae parameters values.
+// These macros may be used in other variant of Sauvola's algorithm.
+//
+// Values are set according to the following reference: "Automatic
+// Evaluation of Document Binarization Results", Badekas and al, 2005
+//
+// Badekas et al. said 0.34 was best.
+# define SCRIBO_DEFAULT_SAUVOLA_K 0.34
+//
+// 128 is best for grayscale documents.
+# define SCRIBO_DEFAULT_SAUVOLA_R 128
+
+
namespace scribo
{
@@ -72,23 +86,16 @@ namespace scribo
*/
template <typename I, typename J>
mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size,
- Image<J>& simple,
- Image<J>& squared);
-
+ sauvola_threshold_image_debug(const Image<I>& input, unsigned window_size,
+ double K,
+ Image<J>& simple,
+ Image<J>& squared);
/// \overload
template <typename I>
mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size);
-
-
- /// \overload
- /// The window size is set to 11.
- //
- template <typename I>
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input);
+ sauvola_threshold_image_debug(const Image<I>& input, unsigned window_size,
+ double K);
@@ -98,42 +105,8 @@ namespace scribo
namespace internal
{
- /*! \brief compute Sauvola's threshold applying directly the formula.
-
- \param[in] m_x_y Mean value.
- \param[in] s_x_y Standard deviation.
- \param[in] k Control the threshold value in the local
- window. The higher, the lower the threshold
- form the local mean m(x, y).
- \param[in] R Maximum value of the standard deviation (128
- for grayscale documents).
-
- \return A threshold.
- */
- inline
- double
- sauvola_threshold_formula(const double m_x_y, const double s_x_y,
- const double k, const double R)
- {
- return m_x_y * (1.0 + k * ((s_x_y / R) - 1.0));
- }
-
-
- /// \overload
- //
- inline
- double
- sauvola_threshold_formula(double m_x_y, double s_x_y)
- {
- // Badekas et al. said 0.34 was best.
- const double k = 0.34;
-
- // 128 is best for grayscale documents.
- const double R = 128;
-
- return sauvola_threshold_formula(m_x_y, s_x_y, k, R);
- }
-
+ unsigned mean_debug_factor = 1;
+ unsigned stddev_debug_factor = 10;
/*! \brief Compute a point wise threshold according Sauvola's
binarization.
@@ -150,12 +123,13 @@ namespace scribo
\return A threshold.
*/
- template <typename P, typename J>
+ template <typename P, typename I, typename J>
double
compute_sauvola_threshold(const P& p,
+ I& mean, I& stddev,
const J& simple,
const J& squared,
- int win_width, double k, double R)
+ int win_width, double K, double R)
{
mln_precondition(simple.nrows() == squared.nrows());
mln_precondition(simple.ncols() == squared.ncols());
@@ -182,6 +156,8 @@ namespace scribo
double m_x_y = m_x_y_tmp / wh;
+ mean(p) = m_x_y * mean_debug_factor;
+
// Standard deviation.
double s_x_y_tmp = (squared.at_(row_max, col_max)
+ squared.at_(row_min, col_min)
@@ -190,74 +166,15 @@ namespace scribo
double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
- // Thresholding.
- double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, k, R);
-
- return t_x_y;
- }
-
-
- template <typename P, typename J>
- double
- compute_sauvola_threshold_single_image(const P& p,
- const J& integral,
- int win_width)
- {
- // Window half width.
- int w_2 = win_width >> 1;
-
- int row_min = std::max(0, p.row() - w_2);
- int col_min = std::max(0, p.col() - w_2);
-
- int row_max = std::min(static_cast<int>(integral.nrows()) - 1,
- p.row() + w_2);
- int col_max = std::min(static_cast<int>(integral.ncols()) - 1,
- p.col() + w_2);
-
-
- double wh = (row_max - row_min + 1) * (col_max - col_min + 1);
-
- // Mean.
- double m_x_y_tmp = (integral.at_(row_max, col_max).first()
- + integral.at_(row_min, col_min).first()
- - integral.at_(row_max, col_min).first()
- - integral.at_(row_min, col_max).first());
-
- double m_x_y = m_x_y_tmp / wh;
-
- // Standard deviation.
- double s_x_y_tmp = (integral.at_(row_max, col_max).second()
- + integral.at_(row_min, col_min).second()
- - integral.at_(row_max, col_min).second()
- - integral.at_(row_min, col_max).second());
-
- double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
+ stddev(p) = s_x_y * stddev_debug_factor;
// Thresholding.
- double t_x_y = m_x_y * (1.0 + 0.34 * ((s_x_y / 128) - 1.0));
+ double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R);
return t_x_y;
}
-
- template <typename P, typename J>
- double
- compute_sauvola_threshold(const P& p,
- const J& simple,
- const J& squared,
- int win_width)
- {
- // Badekas et al. said 0.34 was best.
- const double k = 0.34;
-
- // 128 is best for grayscale documents.
- const double R = 128;
-
- return compute_sauvola_threshold(p, simple, squared, win_width, k, R);
- }
-
-
} // end of namespace scribo::binarization::internal
} // end of namespace scribo::binarization
@@ -284,13 +201,18 @@ namespace scribo
template <typename I, typename J>
inline
mln_concrete(I)
- sauvola_threshold_image(const Image<I>& input_, unsigned window_size,
- Image<J>& simple_,
- Image<J>& squared_)
+ sauvola_threshold_image_debug(const Image<I>& input_,
+ unsigned window_size,
+ double K,
+ Image<I>& mean_, Image<I>& stddev_,
+ Image<J>& simple_,
+ Image<J>& squared_)
{
- trace::entering("scribo::binarization::impl::generic::sauvola_threshold_image");
+ trace::entering("scribo::binarization::impl::generic::sauvola_threshold_image_debug");
const I& input = exact(input_);
+ I& mean = exact(mean_);
+ I& stddev = exact(stddev_);
J& simple = exact(simple_);
J& squared = exact(squared_);
@@ -312,8 +234,11 @@ namespace scribo
for(def::coord row = 0; row < nrows; ++row)
for(def::coord col = 0; col < ncols; ++col)
output.at_(row, col)
- = internal::compute_sauvola_threshold(P(row, col), simple,
- squared, window_size);
+ = internal::compute_sauvola_threshold(P(row, col),
+ mean, stddev,
+ simple, squared,
+ window_size, K,
+ SCRIBO_DEFAULT_SAUVOLA_R);
trace::exiting("scribo::binarization::impl::generic::sauvola_threshold");
return output;
@@ -326,33 +251,43 @@ namespace scribo
template <typename I, typename J>
inline
mln_concrete(I)
- sauvola_threshold_image_gl(const I& input, unsigned window_size,
- Image<J>& simple,
- Image<J>& squared)
+ sauvola_threshold_image_debug_gl(const Image<I>& input,
+ unsigned window_size,
+ double K,
+ Image<I>& mean, Image<I>& stddev,
+ Image<J>& simple,
+ Image<J>& squared)
{
- return impl::generic::sauvola_threshold_image(input, window_size,
- simple, squared);
+ return impl::generic::sauvola_threshold_image_debug(input, window_size,
+ K,
+ mean, stddev,
+ simple, squared);
}
template <typename I, typename J>
inline
mln_ch_value(I, value::int_u8)
- sauvola_threshold_image_rgb8(const I& input, unsigned window_size,
- Image<J>& simple,
- Image<J>& squared)
+ sauvola_threshold_image_debug_rgb8(const Image<I>& input,
+ unsigned window_size,
+ double K,
+ Image<I>& mean, Image<I>& stddev,
+ Image<J>& simple,
+ Image<J>& squared)
{
- trace::entering("scribo::binarization::impl::sauvola_threshold_image_rgb8");
+ trace::entering("scribo::binarization::impl::sauvola_threshold_image_debug_rgb8");
mln_ch_value(I, value::int_u8) gima;
gima = data::transform(input,
mln::fun::v2v::rgb_to_int_u<8>());
mln_ch_value(I, value::int_u8)
- output = impl::generic::sauvola_threshold_image(gima, window_size,
- simple, squared);
+ output = impl::generic::sauvola_threshold_image_debug(gima, window_size,
+ K,
+ mean, stddev,
+ simple, squared);
- trace::exiting("scribo::binarization::impl::sauvola_threshold_image_rgb8");
+ trace::exiting("scribo::binarization::impl::sauvola_threshold_image_debug_rgb8");
return output;
}
@@ -370,33 +305,43 @@ namespace scribo
template <unsigned n, typename I, typename J>
inline
mln_ch_value(I, value::int_u<n>)
- sauvola_threshold_image_dispatch(const value::int_u<n>&, const I& input,
- unsigned window_size,
- J& simple,
- J& squared)
+ sauvola_threshold_image_debug_dispatch(const value::int_u<n>&,
+ const I& input,
+ unsigned window_size,
+ double K,
+ I& mean, I& stddev,
+ J& simple,
+ J& squared)
{
- return impl::sauvola_threshold_image_gl(input, window_size, simple, squared);
+ return impl::sauvola_threshold_image_debug_gl(input, window_size, K,
+ mean, stddev,
+ simple, squared);
}
template <typename I, typename J>
inline
mln_ch_value(I, value::int_u8)
- sauvola_threshold_image_dispatch(const value::rgb8&, const I& input,
- unsigned window_size,
- J& simple,
- J& squared)
+ sauvola_threshold_image_debug_dispatch(const value::rgb8&, const I& input,
+ unsigned window_size,
+ double K,
+ I& mean, I& stddev,
+ J& simple,
+ J& squared)
{
- return impl::sauvola_threshold_image_rgb8(input, window_size,
- simple, squared);
+ return impl::sauvola_threshold_image_debug_rgb8(input, window_size,
+ K, mean, stddev,
+ simple, squared);
}
template <typename I, typename J>
inline
mln_ch_value(I, value::int_u8)
- sauvola_threshold_image_dispatch(const mln_value(I)&, const I& input,
- unsigned window_size,
- J& simple,
- J& squared)
+ sauvola_threshold_image_debug_dispatch(const mln_value(I)&, const I& input,
+ I& mean, I& stddev,
+ unsigned window_size,
+ double K,
+ J& simple,
+ J& squared)
{
// No dispatch for this kind of value type.
mlc_abort(I)::check();
@@ -412,40 +357,27 @@ namespace scribo
template <typename I, typename J>
mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size,
- Image<J>& simple,
- Image<J>& squared)
+ sauvola_threshold_image_debug(const Image<I>& input, unsigned window_size,
+ double K,
+ Image<I>& mean, Image<I>& stddev,
+ Image<J>& simple,
+ Image<J>& squared)
{
- trace::entering("scribo::binarization::sauvola_threshold_image");
+ trace::entering("scribo::binarization::sauvola_threshold_image_debug");
mln_precondition(mln_site_(I)::dim == 2);
mln_precondition(exact(input).is_valid());
-
-// {
-// J& simple_ = exact(simple);
-// J& squared_ = exact(squared);
-// mln_piter(J) p(simple_.domain());
-// for_all(p)
-// {
-// std::cout << simple_(p) << ", ";
-// }
-// std::cout << std::endl << " ------- " << std::endl;
-// for_all(p)
-// {
-// std::cout << squared_(p) << ", ";
-// }
-// std::cout << std::endl << " ------- " << std::endl;
-// }
-
-
-
typedef mln_value(I) value_t;
mln_ch_value(I, value::int_u8)
- output = internal::sauvola_threshold_image_dispatch(value_t(), exact(input),
- window_size,
- exact(simple),
- exact(squared));
+ output = internal::sauvola_threshold_image_debug_dispatch(value_t(),
+ exact(input),
+ window_size,
+ K,
+ exact(mean),
+ exact(stddev),
+ exact(simple),
+ exact(squared));
trace::exiting("scribo::text::ppm2pbm");
return output;
@@ -455,28 +387,17 @@ namespace scribo
template <typename I>
inline
mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size)
+ sauvola_threshold_image_debug(const Image<I>& input, unsigned window_size,
+ double K,
+ Image<I>& mean, Image<I>& stddev)
{
mln_ch_value(I, double)
simple = init_integral_image(input, scribo::internal::identity_),
squared = init_integral_image(input, scribo::internal::square_);
-// debug::println(input);
-// std::cout << "============" << std::endl;
-// // debug::println(simple);
-// // std::cout << "============" << std::endl;
-// // debug::println(squared);
-
- return sauvola_threshold_image(input, window_size, simple, squared);
- }
-
-
- template <typename I>
- inline
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input)
- {
- return sauvola_threshold_image(input, 11);
+ return sauvola_threshold_image_debug(input, window_size, K,
+ mean, stddev,
+ simple, squared);
}
@@ -487,4 +408,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_HH
+#endif // ! SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_DEBUG_HH
diff --git a/scribo/canvas/integral_browsing.hh b/scribo/canvas/integral_browsing.hh
index 45ff38d..4e55109 100644
--- a/scribo/canvas/integral_browsing.hh
+++ b/scribo/canvas/integral_browsing.hh
@@ -127,19 +127,6 @@ namespace scribo
unsigned s_2 = s * s;
- // Make sure the window fits in the image domain.
- if (w >= static_cast<const unsigned>(ncols))
- {
- w = ncols - 1;
- trace::warning("integral_browsing - Adjusting window width since it was larger than image width.");
- }
- if (h >= static_cast<const unsigned>(nrows))
- {
- h = nrows - 1;
- trace::warning("integral_browsing - Adjusting window height since it was larger than image height.");
- }
-
-
// -------------------------------
// T (top)
// -------------------------------
diff --git a/scribo/debug/usage.hh b/scribo/debug/usage.hh
index 6b6c9b7..2c6fa48 100644
--- a/scribo/debug/usage.hh
+++ b/scribo/debug/usage.hh
@@ -26,6 +26,7 @@
#ifndef SCRIBO_DEBUG_USAGE_HH
# define SCRIBO_DEBUG_USAGE_HH
+#include <libgen.h>
#include <iostream>
namespace scribo
@@ -45,7 +46,7 @@ namespace scribo
/// \return Return 1.
//
int usage(char* argv[], const char *desc, const char* args,
- const char*args_desc[][2], const char *out_desc);
+ const char*args_desc[][2]);
# ifndef MLN_INCLUDE_ONLY
@@ -53,21 +54,21 @@ namespace scribo
inline
int
usage(char* argv[], const char *desc, const char* args,
- const char*args_desc[][2], const char *out_desc = 0)
+ const char*args_desc[][2])
{
- std::cout << "Usage: " << argv[0] << " " << args
+ std::cout << "Usage: " << basename(argv[0]) << " " << args
<< std::endl
<< std::endl;
std::cout << "-----------" << std::endl;
std::cout << desc << std::endl
- << std::endl;
+ << std::endl;
for (unsigned i = 0; args_desc[i][0] != 0; ++i)
std::cout << " " << args_desc[i][0] << ": " << args_desc[i][1]
<< std::endl;
- if (out_desc)
- std::cout << std::endl << "Output: " << out_desc << std::endl;
+// if (out_desc)
+// std::cout << std::endl << "Output: " << out_desc << std::endl;
std::cout << "-----------" << std::endl;
std::cout << "EPITA/LRDE - Scribo 2009" << std::endl;
diff --git a/scribo/src/binarization/ppm_fg_sauvola_ms.cc b/scribo/src/binarization/fg_sauvola_ms.cc
similarity index 87%
copy from scribo/src/binarization/ppm_fg_sauvola_ms.cc
copy to scribo/src/binarization/fg_sauvola_ms.cc
index 5f45470..9c606d6 100644
--- a/scribo/src/binarization/ppm_fg_sauvola_ms.cc
+++ b/scribo/src/binarization/fg_sauvola_ms.cc
@@ -26,7 +26,7 @@
#include <mln/core/image/image2d.hh>
#include <mln/value/rgb8.hh>
-#include <mln/io/ppm/load.hh>
+#include <mln/io/magick/load.hh>
#include <mln/io/pbm/save.hh>
#include <scribo/binarization/sauvola_ms.hh>
@@ -53,7 +53,8 @@ bool check_args(int argc, char * argv[])
const char *args_desc[][2] =
{
- { "input.ppm", "A color image." },
+ { "input.*", "An image." },
+ { "output.pbm", "A binary image." },
{ "lambda", "Lambda used to split bg/fg." },
{ "w", "Window size at scale 1. (Common value: 101)" },
{ "s", "First subsampling ratio (Common value: 3)." },
@@ -71,9 +72,9 @@ int main(int argc, char *argv[])
if (!check_args(argc, argv))
return scribo::debug::usage(argv,
- "Multi-Scale Binarization of a color image based on Sauvola's algorithm. Performs a binarization on each component of the color image and merges the results.",
- "input.ppm w s area_threshold output.pbm",
- args_desc, "A binary image.");
+ "Multi-Scale Binarization based on Sauvola's algorithm. Performs a binarization on each component of the color image and merges the results.",
+ "input.* output.pbm w s area_threshold",
+ args_desc);
trace::entering("main");
@@ -90,13 +91,13 @@ int main(int argc, char *argv[])
image2d<value::rgb8> input_1;
- io::ppm::load(input_1, argv[1]);
+ io::magick::load(input_1, argv[1]);
image2d<value::rgb8>
fg = scribo::preprocessing::split_bg_fg(input_1, lambda, 32).first();
image2d<bool>
- output = scribo::binarization::sauvola_ms(fg, w_1, s, lambda_min_1);
+ output = scribo::binarization::sauvola_ms(fg, w_1, s, lambda_min_1, SCRIBO_DEFAULT_SAUVOLA_K);
io::pbm::save(output, argv[6]);
}
diff --git a/scribo/src/binarization/pgm_global_threshold_auto.cc b/scribo/src/binarization/pgm_global_threshold_auto.cc
index 7f1dacf..568eba2 100644
--- a/scribo/src/binarization/pgm_global_threshold_auto.cc
+++ b/scribo/src/binarization/pgm_global_threshold_auto.cc
@@ -33,6 +33,7 @@
const char *args_desc[][2] =
{
{ "input.pgm", "A gray level image." },
+ { "output.pbm", "A binary image." },
{0, 0}
};
@@ -46,7 +47,7 @@ int main(int argc, char *argv[])
return scribo::debug::usage(argv,
"Binarization of a gray-level image using an automatic global threshold.",
"input.pgm output.pbm",
- args_desc, "A binary image.");
+ args_desc);
trace::entering("main");
diff --git a/scribo/src/binarization/pgm_sauvola.cc b/scribo/src/binarization/pgm_sauvola.cc
index 843c355..c6ba643 100644
--- a/scribo/src/binarization/pgm_sauvola.cc
+++ b/scribo/src/binarization/pgm_sauvola.cc
@@ -33,7 +33,9 @@
const char *args_desc[][2] =
{
{ "input.pgm", "A gray level image." },
- { "w", "Window size." },
+ { "output.pbm", "A binary image." },
+ { "w", "Window size (default 51)." },
+ { "k", "Sauvola's formulae parameter (default 0.34)." },
{0, 0}
};
@@ -43,23 +45,35 @@ int main(int argc, char *argv[])
using namespace mln;
using value::int_u8;
- if (argc != 4)
+ if (argc != 5 && argc != 4 && argc != 3)
return scribo::debug::usage(argv,
"Binarization of a gray level image based on Sauvola's algorithm.",
- "input.pgm w output.pbm",
- args_desc, "A binary image.");
+ "input.pgm output.pbm <w> <k>",
+ args_desc);
trace::entering("main");
- unsigned w = atoi(argv[2]);
+ unsigned w;
+ if (argc == 4)
+ w = atoi(argv[3]);
+ else
+ w = 51;
+
+ double k;
+ if (argc == 5)
+ k = atof(argv[4]);
+ else
+ k = 0.34f;
+
+ std::cout << "Using w=" << w << " and k=" << k << std::endl;
image2d<int_u8> input;
io::pgm::load(input, argv[1]);
- image2d<bool> out = scribo::binarization::sauvola(input, w);
+ image2d<bool> out = scribo::binarization::sauvola(input, w, k);
- io::pbm::save(out, argv[3]);
+ io::pbm::save(out, argv[2]);
trace::exiting("main");
diff --git a/scribo/src/binarization/pgm_sauvola_ms.cc b/scribo/src/binarization/pgm_sauvola_ms.cc
index d446c3e..fefdd6a 100644
--- a/scribo/src/binarization/pgm_sauvola_ms.cc
+++ b/scribo/src/binarization/pgm_sauvola_ms.cc
@@ -34,16 +34,19 @@
bool check_args(int argc, char * argv[])
{
- if (argc < 5 || argc > 6)
+ if (argc < 3 || argc > 6)
return false;
- int s = atoi(argv[3]);
-
- if (s < 1 || s > 3)
+ if (argc >= 5)
{
- std::cout << "s must be set to 2 or 3."
- << std::endl;
- return false;
+ int s = atoi(argv[4]);
+
+ if (s < 1 || s > 3)
+ {
+ std::cout << "s must be set to 2 or 3."
+ << std::endl;
+ return false;
+ }
}
return true;
@@ -53,9 +56,10 @@ bool check_args(int argc, char * argv[])
const char *args_desc[][2] =
{
{ "input.pgm", "A graylevel image." },
- { "w", "Window size at scale 1. (Common value: 101)" },
- { "s", "First subsampling ratio (Common value: 3)." },
- { "min_area", "Minimum object area at scale 1 (Common value: 67)" },
+ { "out.pbm", "A binary image." },
+ { "w", "Window size at scale 1. (default: 101)" },
+ { "s", "First subsampling ratio (default: 3)." },
+ { "k", "Sauvola's formuale parameter (default: 0.34)" },
{0, 0}
};
@@ -70,28 +74,43 @@ int main(int argc, char *argv[])
if (!check_args(argc, argv))
return scribo::debug::usage(argv,
"Multi-Scale Binarization of a color image based on Sauvola's algorithm.",
- "input.pgm w s area_threshold output.pbm",
- args_desc, "A binary image.");
+ "input.pgm output.pbm <w> <s> <k>",
+ args_desc);
trace::entering("main");
// Window size
- unsigned w_1 = atoi(argv[2]); // Scale 1
+ unsigned w_1;
+ if (argc >= 4)
+ w_1 = atoi(argv[3]); // Scale 1
+ else
+ w_1 = 101u;
// First subsampling scale.
- unsigned s = atoi(argv[3]);
+ unsigned s;
+ if (argc >= 5)
+ s = atoi(argv[4]);
+ else
+ s = 3u;
// Lambda value
- unsigned lambda_min_1 = atoi(argv[4]);
+ unsigned lambda_min_1 = 67; // FIXME: should be adapted to the
+ // window size.
+ double k;
+ if (argc >= 6)
+ k = atof(argv[5]);
+ else
+ k = 0.34f;
image2d<value::int_u8> input_1;
io::pgm::load(input_1, argv[1]);
image2d<bool>
- output = scribo::binarization::sauvola_ms(input_1, w_1, s, lambda_min_1);
+ output = scribo::binarization::sauvola_ms(input_1, w_1, s,
+ lambda_min_1, k);
- io::pbm::save(output, argv[5]);
+ io::pbm::save(output, argv[2]);
}
diff --git a/scribo/src/binarization/ppm_fg_sauvola_ms.cc b/scribo/src/binarization/ppm_fg_sauvola_ms.cc
index 5f45470..65e8621 100644
--- a/scribo/src/binarization/ppm_fg_sauvola_ms.cc
+++ b/scribo/src/binarization/ppm_fg_sauvola_ms.cc
@@ -35,16 +35,19 @@
bool check_args(int argc, char * argv[])
{
- if (argc != 7)
+ if (argc < 3 || argc > 7)
return false;
- int s = atoi(argv[4]);
-
- if (s < 2 || s > 3)
+ if (argc >= 6)
{
- std::cout << "s must be set to 2 or 3."
- << std::endl;
- return false;
+ int s = atoi(argv[5]);
+
+ if (s < 2 || s > 3)
+ {
+ std::cout << "s must be set to 2 or 3."
+ << std::endl;
+ return false;
+ }
}
return true;
@@ -54,10 +57,11 @@ bool check_args(int argc, char * argv[])
const char *args_desc[][2] =
{
{ "input.ppm", "A color image." },
+ { "output.pbm", "A binary image." },
{ "lambda", "Lambda used to split bg/fg." },
- { "w", "Window size at scale 1. (Common value: 101)" },
- { "s", "First subsampling ratio (Common value: 3)." },
- { "min_area", "Minimum object area at scale 1 (Common value: 67)" },
+ { "w", "Window size at scale 1. (default: 101)" },
+ { "s", "First subsampling ratio. (default: 3)" },
+ { "k", "Sauvola's formula parameter. (default: 0.34)" },
{0, 0}
};
@@ -72,33 +76,49 @@ int main(int argc, char *argv[])
if (!check_args(argc, argv))
return scribo::debug::usage(argv,
"Multi-Scale Binarization of a color image based on Sauvola's algorithm. Performs a binarization on each component of the color image and merges the results.",
- "input.ppm w s area_threshold output.pbm",
- args_desc, "A binary image.");
+ "input.ppm output.pbm lambda <w> <s> <k>",
+ args_desc);
trace::entering("main");
- unsigned lambda = atoi(argv[2]);
+ unsigned lambda = atoi(argv[3]);
// Window size
- unsigned w_1 = atoi(argv[3]); // Scale 1
+ unsigned w_1;
+ if (argc >= 5)
+ w_1 = atoi(argv[4]); // Scale 1
+ else
+ w_1 = 101u;
// First subsampling scale.
- unsigned s = atoi(argv[4]);
+ unsigned s;
+ if (argc >= 6)
+ s = atoi(argv[5]);
+ else
+ s = 3u;
// Lambda value
- unsigned lambda_min_1 = atoi(argv[5]);
+ unsigned lambda_min_1 = 67; // FIXME: should be adapted to the
+ // window size.
+
+ double k;
+ if (argc >= 7)
+ k = atof(argv[6]);
+ else
+ k = 0.34f;
+
image2d<value::rgb8> input_1;
io::ppm::load(input_1, argv[1]);
image2d<value::rgb8>
- fg = scribo::preprocessing::split_bg_fg(input_1, lambda, 32).first();
+ fg = scribo::preprocessing::split_bg_fg(input_1, lambda, 32).second();
image2d<bool>
- output = scribo::binarization::sauvola_ms(fg, w_1, s, lambda_min_1);
+ output = scribo::binarization::sauvola_ms(fg, w_1, s, lambda_min_1, k);
- io::pbm::save(output, argv[6]);
+ io::pbm::save(output, argv[2]);
}
diff --git a/scribo/src/binarization/ppm_sauvola.cc b/scribo/src/binarization/ppm_sauvola.cc
index c3ce28a..0b798ae 100644
--- a/scribo/src/binarization/ppm_sauvola.cc
+++ b/scribo/src/binarization/ppm_sauvola.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -25,7 +26,6 @@
#include <mln/io/ppm/load.hh>
#include <mln/io/pbm/save.hh>
-#include <mln/value/rgb8.hh>
#include <scribo/binarization/sauvola.hh>
#include <scribo/debug/usage.hh>
@@ -33,7 +33,9 @@
const char *args_desc[][2] =
{
{ "input.ppm", "A color image." },
- { "wsize", "Window size (Common value: 51)." },
+ { "output.pbm", "A binary image." },
+ { "w", "Window size (default 51)." },
+ { "k", "Sauvola's formulae parameter (default 0.34)." },
{0, 0}
};
@@ -41,20 +43,36 @@ const char *args_desc[][2] =
int main(int argc, char *argv[])
{
using namespace mln;
- using value::rgb8;
- if (argc != 4)
+ if (argc != 5 && argc != 4 && argc != 3)
return scribo::debug::usage(argv,
- "Binarization of a color image based on Sauvola's algorithm. First convert the color image to an intensity image and then run Sauvola.",
- "input.ppm wsize output.pbm",
- args_desc, "A binary image.");
+ "Binarization of a gray level image based on Sauvola's algorithm.",
+ "input.ppm output.pbm <w> <k>",
+ args_desc);
trace::entering("main");
- image2d<rgb8> input;
+ unsigned w;
+ if (argc == 4)
+ w = atoi(argv[3]);
+ else
+ w = 51;
+
+ double k;
+ if (argc == 5)
+ k = atof(argv[4]);
+ else
+ k = 0.34f;
+
+ std::cout << "Using w=" << w << " and k=" << k << std::endl;
+
+ image2d<value::rgb8> input;
io::ppm::load(input, argv[1]);
- io::pbm::save(scribo::binarization::sauvola(input, atoi(argv[2])), argv[3]);
+ image2d<bool> out = scribo::binarization::sauvola(input, w, k);
+
+
+ io::pbm::save(out, argv[2]);
trace::exiting("main");
diff --git a/scribo/src/binarization/ppm_sauvola_ms.cc b/scribo/src/binarization/ppm_sauvola_ms.cc
index d8c1c9c..f2cbb6f 100644
--- a/scribo/src/binarization/ppm_sauvola_ms.cc
+++ b/scribo/src/binarization/ppm_sauvola_ms.cc
@@ -25,7 +25,7 @@
// executable file might be covered by the GNU General Public License.
#include <mln/core/image/image2d.hh>
-#include <mln/value/rgb8.hh>
+#include <mln/value/int_u8.hh>
#include <mln/io/ppm/load.hh>
#include <mln/io/pbm/save.hh>
@@ -34,16 +34,19 @@
bool check_args(int argc, char * argv[])
{
- if (argc < 5 || argc > 6)
+ if (argc < 3 || argc > 6)
return false;
- int s = atoi(argv[3]);
-
- if (s < 2 || s > 3)
+ if (argc >= 5)
{
- std::cout << "s must be set to 2 or 3."
- << std::endl;
- return false;
+ int s = atoi(argv[4]);
+
+ if (s < 1 || s > 3)
+ {
+ std::cout << "s must be set to 2 or 3."
+ << std::endl;
+ return false;
+ }
}
return true;
@@ -53,9 +56,10 @@ bool check_args(int argc, char * argv[])
const char *args_desc[][2] =
{
{ "input.ppm", "A color image." },
- { "w", "Window size at scale 1. (Common value: 101)" },
- { "s", "First subsampling ratio (Common value: 3)." },
- { "min_area", "Minimum object area at scale 1 (Common value: 67)" },
+ { "out.pbm", "A binary image." },
+ { "w", "Window size at scale 1. (default: 101)" },
+ { "s", "First subsampling ratio (default: 3)." },
+ { "k", "Sauvola's formuale parameter (default: 0.34)" },
{0, 0}
};
@@ -69,29 +73,44 @@ int main(int argc, char *argv[])
if (!check_args(argc, argv))
return scribo::debug::usage(argv,
- "Multi-Scale Binarization of a color image based on Sauvola's algorithm. Performs a binarization on each component of the color image and merges the results.",
- "input.ppm w s area_threshold output.pbm",
- args_desc, "A binary image.");
+ "Multi-Scale Binarization of a color image based on Sauvola's algorithm.",
+ "input.ppm output.pbm <w> <s> <k>",
+ args_desc);
trace::entering("main");
// Window size
- unsigned w_1 = atoi(argv[2]); // Scale 1
+ unsigned w_1;
+ if (argc >= 4)
+ w_1 = atoi(argv[3]); // Scale 1
+ else
+ w_1 = 101u;
// First subsampling scale.
- unsigned s = atoi(argv[3]);
+ unsigned s;
+ if (argc >= 5)
+ s = atoi(argv[4]);
+ else
+ s = 3u;
// Lambda value
- unsigned lambda_min_1 = atoi(argv[4]);
+ unsigned lambda_min_1 = 67; // FIXME: should be adapted to the
+ // window size.
+ double k;
+ if (argc >= 6)
+ k = atof(argv[5]);
+ else
+ k = 0.34f;
image2d<value::rgb8> input_1;
io::ppm::load(input_1, argv[1]);
image2d<bool>
- output = scribo::binarization::sauvola_ms(input_1, w_1, s, lambda_min_1);
+ output = scribo::binarization::sauvola_ms(input_1, w_1, s,
+ lambda_min_1, k);
- io::pbm::save(output, argv[5]);
+ io::pbm::save(output, argv[2]);
}
diff --git a/scribo/src/binarization/ppm_sauvola_ms_split.cc b/scribo/src/binarization/ppm_sauvola_ms_split.cc
index 3f721db..b1f10ea 100644
--- a/scribo/src/binarization/ppm_sauvola_ms_split.cc
+++ b/scribo/src/binarization/ppm_sauvola_ms_split.cc
@@ -34,16 +34,19 @@
bool check_args(int argc, char * argv[])
{
- if (argc != 7)
+ if (argc < 3 || argc > 7)
return false;
- int s = atoi(argv[3]);
-
- if (s < 1 || s > 3)
+ if (argc >= 5)
{
- std::cout << "s must be set to 2 or 3."
- << std::endl;
- return false;
+ int s = atoi(argv[4]);
+
+ if (s < 1 || s > 3)
+ {
+ std::cout << "s must be set to 2 or 3."
+ << std::endl;
+ return false;
+ }
}
return true;
@@ -53,10 +56,11 @@ bool check_args(int argc, char * argv[])
const char *args_desc[][2] =
{
{ "input.ppm", "A color image." },
- { "w", "Window size at scale 1. (Common value: 101)" },
- { "s", "First subsampling ratio (Common value: 3)." },
- { "min_area", "Minimum object area at scale 1 (Common value: 67)" },
- { "min_ntrue", "The number of components in which a site must be set to 'True' in order to be set to 'True' in the output (Possible values: 1, 2, 3). (Common value: 2)" },
+ { "output.pbm", "A binary image." },
+ { "w", "Window size at scale 1. (default: 101)" },
+ { "s", "First subsampling ratio (default: 3)." },
+ { "min_ntrue", "The number of components in which a site must be set to 'True' in order to be set to 'True' in the output (Possible values: 1, 2, 3). (default: 2)" },
+ { "K", "Sauvola's formula parameter (default: 0.34)." },
{0, 0}
};
@@ -71,28 +75,53 @@ int main(int argc, char *argv[])
if (!check_args(argc, argv))
return scribo::debug::usage(argv,
"Multi-Scale Binarization of a color image based on Sauvola's algorithm. Performs a binarization on each component of the color image and merges the results.",
- "input.ppm w s area_threshold output.pbm",
- args_desc, "A binary image.");
+ "input.ppm output.pbm <w> <s> <min_ntrue> <K>",
+ args_desc);
trace::entering("main");
// Window size
- unsigned w_1 = atoi(argv[2]); // Scale 1
+ unsigned w_1;
+ if (argc >= 4)
+ w_1 = atoi(argv[3]); // Scale 1
+ else
+ w_1 = 101u;
// First subsampling scale.
- unsigned s = atoi(argv[3]);
+ unsigned s;
+ if (argc >= 5)
+ s = atoi(argv[4]);
+ else
+ s = 3u;
+
+ // min_ntrue
+ unsigned min_ntrue;
+ if (argc >= 6)
+ min_ntrue = atoi(argv[5]);
+ else
+ min_ntrue = 2;
// Lambda value
- unsigned lambda_min_1 = atoi(argv[4]);
+ unsigned lambda_min_1 = 67; // FIXME: should be adapted to the
+ // window size.
+
+ double k;
+ if (argc >= 7)
+ k = atof(argv[6]);
+ else
+ k = 0.34f;
+
image2d<value::rgb8> input_1;
io::ppm::load(input_1, argv[1]);
+ std::cout << "Using w=" << w_1 << " - s=" << s << " - min_ntrue=" << min_ntrue << " - k=" << k << std::endl;
+
image2d<bool>
- output = scribo::binarization::sauvola_ms_split(input_1, w_1, s, lambda_min_1, atoi(argv[5]));
+ output = scribo::binarization::sauvola_ms_split(input_1, w_1, s, lambda_min_1, min_ntrue, k);
- io::pbm::save(output, argv[6]);
+ io::pbm::save(output, argv[2]);
}
diff --git a/scribo/src/binarization/pgm_sauvola.cc b/scribo/src/binarization/sauvola.cc
similarity index 68%
copy from scribo/src/binarization/pgm_sauvola.cc
copy to scribo/src/binarization/sauvola.cc
index 843c355..fb07b0d 100644
--- a/scribo/src/binarization/pgm_sauvola.cc
+++ b/scribo/src/binarization/sauvola.cc
@@ -24,7 +24,7 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#include <mln/io/pgm/load.hh>
+#include <mln/io/magick/load.hh>
#include <mln/io/pbm/save.hh>
#include <scribo/binarization/sauvola.hh>
@@ -32,8 +32,10 @@
const char *args_desc[][2] =
{
- { "input.pgm", "A gray level image." },
- { "w", "Window size." },
+ { "input.*", "An image." },
+ { "output.pbm", "A binary image." },
+ { "w", "Window size (default 51)." },
+ { "k", "Sauvola's formulae parameter (default 0.34)." },
{0, 0}
};
@@ -41,25 +43,36 @@ const char *args_desc[][2] =
int main(int argc, char *argv[])
{
using namespace mln;
- using value::int_u8;
- if (argc != 4)
+ if (argc != 5 && argc != 4 && argc != 3)
return scribo::debug::usage(argv,
- "Binarization of a gray level image based on Sauvola's algorithm.",
- "input.pgm w output.pbm",
- args_desc, "A binary image.");
+ "Binarization based on Sauvola's algorithm.",
+ "input.* output.pbm <w> <k>",
+ args_desc);
trace::entering("main");
- unsigned w = atoi(argv[2]);
+ unsigned w;
+ if (argc >= 4)
+ w = atoi(argv[3]);
+ else
+ w = 51;
- image2d<int_u8> input;
- io::pgm::load(input, argv[1]);
+ double k;
+ if (argc >= 5)
+ k = atof(argv[4]);
+ else
+ k = 0.34f;
- image2d<bool> out = scribo::binarization::sauvola(input, w);
+ std::cout << "Using w=" << w << " and k=" << k << std::endl;
+ image2d<value::rgb8> input;
+ io::magick::load(input, argv[1]);
- io::pbm::save(out, argv[3]);
+ image2d<bool> out = scribo::binarization::sauvola(input, w, k);
+
+
+ io::pbm::save(out, argv[2]);
trace::exiting("main");
diff --git a/scribo/src/binarization/sauvola_debug.cc b/scribo/src/binarization/sauvola_debug.cc
new file mode 100644
index 0000000..8bbc19c
--- /dev/null
+++ b/scribo/src/binarization/sauvola_debug.cc
@@ -0,0 +1,105 @@
+// Copyright (C) 2009, 2010 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.
+
+#include <mln/io/magick/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <scribo/binarization/local_threshold.hh>
+#include <scribo/binarization/sauvola_threshold_image_debug.hh>
+#include <scribo/debug/usage.hh>
+
+const char *args_desc[][2] =
+{
+ { "input.*", "An image." },
+ { "output.pbm", "A binary image." },
+ { "mean.pgm", "The local mean image." },
+ { "stddev.pgm", "The local standard deviation image." },
+ { "mean_factor", "Mean value factor (default 1)." },
+ { "stddev_factor", "Standard deviation value factor (default 10)." },
+ { "w", "Window size (default 51)." },
+ { "k", "Sauvola's formulae parameter (default 0.34)." },
+ {0, 0}
+};
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace scribo::binarization;
+
+ if (argc < 5 || argc >= 9)
+ return scribo::debug::usage(argv,
+ "Binarization based on Sauvola's algorithm.",
+ "input.* output.pbm mean.pgm stddev.pgm <mean_factor> <stddev_factor> <w> <k>",
+ args_desc);
+
+ trace::entering("main");
+
+ unsigned w;
+ if (argc >= 8)
+ w = atoi(argv[7]);
+ else
+ w = 51;
+
+ double k;
+ if (argc >= 9)
+ k = atof(argv[8]);
+ else
+ k = 0.34f;
+
+ std::cout << "Using w=" << w << " and k=" << k << std::endl;
+
+ if (argc >= 6)
+ scribo::binarization::internal::mean_debug_factor = atoi(argv[5]);
+ if (argc >= 7)
+ scribo::binarization::internal::stddev_debug_factor = atoi(argv[6]);
+
+ image2d<value::rgb8> input;
+ io::magick::load(input, argv[1]);
+
+
+ image2d<value::int_u8> mean, stddev;
+ initialize(mean, input);
+ initialize(stddev, input);
+
+ image2d<value::int_u8>
+ gima = data::transform(input,
+ mln::fun::v2v::rgb_to_int_u<8>());
+
+
+ image2d<bool>
+ out = local_threshold(gima,
+ sauvola_threshold_image_debug(gima, w, k,
+ mean, stddev));
+
+
+ io::pbm::save(out, argv[2]);
+ io::pgm::save(mean, argv[3]);
+ io::pgm::save(stddev, argv[4]);
+
+ trace::exiting("main");
+}
diff --git a/scribo/src/binarization/ppm_sauvola_ms.cc b/scribo/src/binarization/sauvola_ms.cc
similarity index 61%
copy from scribo/src/binarization/ppm_sauvola_ms.cc
copy to scribo/src/binarization/sauvola_ms.cc
index d8c1c9c..3983793 100644
--- a/scribo/src/binarization/ppm_sauvola_ms.cc
+++ b/scribo/src/binarization/sauvola_ms.cc
@@ -25,8 +25,8 @@
// executable file might be covered by the GNU General Public License.
#include <mln/core/image/image2d.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/io/ppm/load.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/magick/load.hh>
#include <mln/io/pbm/save.hh>
#include <scribo/binarization/sauvola_ms.hh>
@@ -34,16 +34,19 @@
bool check_args(int argc, char * argv[])
{
- if (argc < 5 || argc > 6)
+ if (argc < 3 || argc > 7)
return false;
- int s = atoi(argv[3]);
-
- if (s < 2 || s > 3)
+ if (argc >= 5)
{
- std::cout << "s must be set to 2 or 3."
- << std::endl;
- return false;
+ int s = atoi(argv[4]);
+
+ if (s < 1 || s > 3)
+ {
+ std::cout << "s must be set to 2 or 3."
+ << std::endl;
+ return false;
+ }
}
return true;
@@ -52,10 +55,12 @@ bool check_args(int argc, char * argv[])
const char *args_desc[][2] =
{
- { "input.ppm", "A color image." },
- { "w", "Window size at scale 1. (Common value: 101)" },
- { "s", "First subsampling ratio (Common value: 3)." },
- { "min_area", "Minimum object area at scale 1 (Common value: 67)" },
+ { "input.*", "An image." },
+ { "out.pbm", "A binary image." },
+ { "w", "Window size at scale 1. (default: 101)" },
+ { "s", "First subsampling ratio (default: 3)." },
+ { "k", "Sauvola's formuale parameter (default: 0.34)" },
+ { "scale.pgm", "Image of scales used for binarization." },
{0, 0}
};
@@ -69,29 +74,42 @@ int main(int argc, char *argv[])
if (!check_args(argc, argv))
return scribo::debug::usage(argv,
- "Multi-Scale Binarization of a color image based on Sauvola's algorithm. Performs a binarization on each component of the color image and merges the results.",
- "input.ppm w s area_threshold output.pbm",
- args_desc, "A binary image.");
+ "Multi-Scale Binarization based on Sauvola's algorithm.",
+ "input.* output.pbm <w> <s> <k> <scale.pgm>",
+ args_desc);
trace::entering("main");
// Window size
- unsigned w_1 = atoi(argv[2]); // Scale 1
+ unsigned w_1;
+ if (argc >= 4)
+ w_1 = atoi(argv[3]); // Scale 1
+ else
+ w_1 = 101u;
// First subsampling scale.
- unsigned s = atoi(argv[3]);
+ unsigned s;
+ if (argc >= 5)
+ s = atoi(argv[4]);
+ else
+ s = 3u;
- // Lambda value
- unsigned lambda_min_1 = atoi(argv[4]);
+ double k;
+ if (argc >= 6)
+ k = atof(argv[5]);
+ else
+ k = 0.34f;
+ if (argc >= 7)
+ scribo::binarization::internal::scale_image_output = argv[6];
image2d<value::rgb8> input_1;
- io::ppm::load(input_1, argv[1]);
+ io::magick::load(input_1, argv[1]);
image2d<bool>
- output = scribo::binarization::sauvola_ms(input_1, w_1, s, lambda_min_1);
+ output = scribo::binarization::sauvola_ms(input_1, w_1, s, k);
- io::pbm::save(output, argv[5]);
+ io::pbm::save(output, argv[2]);
}
diff --git a/scribo/src/binarization/ppm_sauvola_ms_split.cc b/scribo/src/binarization/sauvola_ms_split.cc
similarity index 64%
copy from scribo/src/binarization/ppm_sauvola_ms_split.cc
copy to scribo/src/binarization/sauvola_ms_split.cc
index 3f721db..af8b604 100644
--- a/scribo/src/binarization/ppm_sauvola_ms_split.cc
+++ b/scribo/src/binarization/sauvola_ms_split.cc
@@ -26,7 +26,7 @@
#include <mln/core/image/image2d.hh>
#include <mln/value/rgb8.hh>
-#include <mln/io/ppm/load.hh>
+#include <mln/io/magick/load.hh>
#include <mln/io/pbm/save.hh>
#include <scribo/binarization/sauvola_ms_split.hh>
@@ -34,16 +34,19 @@
bool check_args(int argc, char * argv[])
{
- if (argc != 7)
+ if (argc < 3 || argc > 7)
return false;
- int s = atoi(argv[3]);
-
- if (s < 1 || s > 3)
+ if (argc >= 5)
{
- std::cout << "s must be set to 2 or 3."
- << std::endl;
- return false;
+ int s = atoi(argv[4]);
+
+ if (s < 1 || s > 3)
+ {
+ std::cout << "s must be set to 2 or 3."
+ << std::endl;
+ return false;
+ }
}
return true;
@@ -52,11 +55,12 @@ bool check_args(int argc, char * argv[])
const char *args_desc[][2] =
{
- { "input.ppm", "A color image." },
- { "w", "Window size at scale 1. (Common value: 101)" },
- { "s", "First subsampling ratio (Common value: 3)." },
- { "min_area", "Minimum object area at scale 1 (Common value: 67)" },
- { "min_ntrue", "The number of components in which a site must be set to 'True' in order to be set to 'True' in the output (Possible values: 1, 2, 3). (Common value: 2)" },
+ { "input.*", "An image." },
+ { "output.pbm", "A binary image." },
+ { "w", "Window size at scale 1. (default: 101)" },
+ { "s", "First subsampling ratio (default: 3)." },
+ { "min_ntrue", "The number of components in which a site must be set to 'True' in order to be set to 'True' in the output (Possible values: 1, 2, 3). (default: 2)" },
+ { "K", "Sauvola's formula parameter (default: 0.34)." },
{0, 0}
};
@@ -71,28 +75,53 @@ int main(int argc, char *argv[])
if (!check_args(argc, argv))
return scribo::debug::usage(argv,
"Multi-Scale Binarization of a color image based on Sauvola's algorithm. Performs a binarization on each component of the color image and merges the results.",
- "input.ppm w s area_threshold output.pbm",
- args_desc, "A binary image.");
+ "input.* output.pbm <w> <s> <min_ntrue> <K>",
+ args_desc);
trace::entering("main");
// Window size
- unsigned w_1 = atoi(argv[2]); // Scale 1
+ unsigned w_1;
+ if (argc >= 4)
+ w_1 = atoi(argv[3]); // Scale 1
+ else
+ w_1 = 101u;
// First subsampling scale.
- unsigned s = atoi(argv[3]);
+ unsigned s;
+ if (argc >= 5)
+ s = atoi(argv[4]);
+ else
+ s = 3u;
+
+ // min_ntrue
+ unsigned min_ntrue;
+ if (argc >= 6)
+ min_ntrue = atoi(argv[5]);
+ else
+ min_ntrue = 2;
// Lambda value
- unsigned lambda_min_1 = atoi(argv[4]);
+ unsigned lambda_min_1 = 67; // FIXME: should be adapted to the
+ // window size.
+
+ double k;
+ if (argc >= 7)
+ k = atof(argv[6]);
+ else
+ k = 0.34f;
+
image2d<value::rgb8> input_1;
- io::ppm::load(input_1, argv[1]);
+ io::magick::load(input_1, argv[1]);
+
+ std::cout << "Using w=" << w_1 << " - s=" << s << " - min_ntrue=" << min_ntrue << " - k=" << k << std::endl;
image2d<bool>
- output = scribo::binarization::sauvola_ms_split(input_1, w_1, s, lambda_min_1, atoi(argv[5]));
+ output = scribo::binarization::sauvola_ms_split(input_1, w_1, s, lambda_min_1, min_ntrue, k);
- io::pbm::save(output, argv[6]);
+ io::pbm::save(output, argv[2]);
}
diff --git a/scribo/src/preprocessing/to_pgm.cc b/scribo/src/preprocessing/to_pgm.cc
new file mode 100644
index 0000000..974e03f
--- /dev/null
+++ b/scribo/src/preprocessing/to_pgm.cc
@@ -0,0 +1,46 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/io/magick/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <scribo/debug/usage.hh>
+
+
+const char *args_desc[][2] =
+{
+ { "input.*", "A color image." },
+ { "output.pgm", "A graylevel image." },
+ {0, 0}
+};
+
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc != 3)
+ return scribo::debug::usage(argv,
+ "Convert a color image using the minimum RGB component value as intensity.",
+ "input.* output.pgm",
+ args_desc);
+
+
+ typedef image2d<value::rgb8> I;
+ I ima;
+ io::magick::load(ima, argv[1]);
+
+ image2d<value::int_u8> out;
+ initialize(out, ima);
+
+ value::rgb8 v;
+ mln_piter_(I) p(ima.domain());
+ for_all(p)
+ {
+ v = ima(p);
+ out(p) = std::min(v.red(), std::min(v.green(), v.blue()));
+ }
+
+ io::pgm::save(out, argv[2]);
+}
--
1.5.6.5
1
0
last-svn-commit-101-g4dad6c9 scribo/src/text_in_photo_fast.cc: Group routine parameters in a global structure.
by Guillaume Lazzara 03 Jun '10
by Guillaume Lazzara 03 Jun '10
03 Jun '10
---
scribo/ChangeLog | 5 ++
scribo/src/text_in_photo_fast.cc | 79 ++++++++++++++++++++++++++++---------
2 files changed, 65 insertions(+), 19 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 34a258f..ffd4a39 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,10 @@
2010-04-13 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * scribo/src/text_in_photo_fast.cc: Group routine parameters in a
+ global structure.
+
+2010-04-13 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new Sauvola overloads and update examples.
* scribo/binarization/internal/first_pass_functor.hh,
diff --git a/scribo/src/text_in_photo_fast.cc b/scribo/src/text_in_photo_fast.cc
index 68b2014..d61cc6f 100644
--- a/scribo/src/text_in_photo_fast.cc
+++ b/scribo/src/text_in_photo_fast.cc
@@ -57,8 +57,6 @@
#include <mln/subsampling/antialiased.hh>
-#include <mln/subsampling/antialiased_rgb.hh>
-
#include <scribo/draw/bounding_boxes.hh>
#include <scribo/draw/groups_bboxes.hh>
@@ -112,6 +110,7 @@
const char *args_desc[][2] =
{
{ "input.ppm", "A color image." },
+ { "ouput.ppm", "A color image where the text is highlighted." },
{ "debug_output_dir", "Directory were debug images will be saved" },
{ "lambda", "Lambda value used for foreground extraction" },
{0, 0}
@@ -121,6 +120,38 @@ const char *args_desc[][2] =
namespace mln
{
+
+ struct config
+ {
+ config()
+ {
+ sauvola_s = 3u;
+ sauvola_min_w = 51u;
+
+ // Group Filtering
+ bbox_h_ratio = 1.50f;
+ bbox_overlap = 0.80f;
+ small_groups = 3;
+ v_thickness = 8;
+ regroup_dmax = 30;
+ group_min_holes = 3;
+ }
+
+
+ // Sauvola ms
+ unsigned sauvola_s;
+ unsigned sauvola_min_w;
+
+ // Group Filtering
+ float bbox_h_ratio;
+ float bbox_overlap;
+ unsigned small_groups;
+ unsigned v_thickness;
+ unsigned regroup_dmax;
+ unsigned group_min_holes;
+ };
+
+
struct mask_non_text : Function_v2v<mask_non_text>
{
typedef value::rgb8 result;
@@ -239,10 +270,9 @@ int main(int argc, char* argv[])
if (argc < 3 || argc > 10)
return scribo::debug::usage(argv,
"Find text in a photo.\n\n\
-Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
+Common usage: ./text_in_photo_fast input.ppm output.ppm 1 1 1 1 1",
"input.ppm output.ppm <bg/fg enabled> <sauvola_ms enabled> <Bg comp filter enabled> <small group filter enabled> <thin group filter enabled> [debug_output_dir] [lambda]",
- args_desc,
- "A color image where the text is highlighted.");
+ args_desc);
std::string out_base_dir;
bool debug = false;
@@ -255,6 +285,8 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
trace::entering("main");
+ config conf;
+
image2d<value::rgb8> input_rgb;
io::magick::load(input_rgb, argv[1]);
@@ -264,7 +296,7 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
std::cout << "Original domain: " << input_rgb.domain() << std::endl;
- input_rgb = mln::subsampling::impl::antialiased_2d_rgb(input_rgb, factor);
+ input_rgb = mln::subsampling::antialiased(input_rgb, factor);
std::cout << "Resized domain: " << input_rgb.domain() << std::endl;
@@ -318,11 +350,11 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
unsigned w = std::min(intensity_ima.nrows() / 3, intensity_ima.ncols() / 3);
if (! w % 2)
++w;
- w = std::min(w, 51u);
+ w = std::min(w, conf.sauvola_min_w);
if (argc > 4 && atoi(argv[4]) != 0)
{
std::cout << "** Using sauvola_ms with w_1 = " << w << std::endl;
- input = scribo::binarization::sauvola_ms(intensity_ima, w, 3, 67);
+ input = scribo::binarization::sauvola_ms(intensity_ima, w, conf.sauvola_s);
}
else
{
@@ -420,7 +452,7 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
timer_.restart();
object_links<L>
hratio_filtered_links = filter::object_links_bbox_h_ratio(merged_links,
- 1.50f);
+ conf.bbox_h_ratio);
@@ -431,7 +463,8 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
image2d<value::rgb8>
hratio_decision_image = scribo::debug::decision_image(input,
merged_links,
- hratio_filtered_links);
+ hratio_filtered_links,
+ anchor::MassCenter);
io::ppm::save(hratio_decision_image,
scribo::make::debug_filename("hratio_links_decision_image.ppm"));
}
@@ -442,7 +475,8 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
//Remove links if bboxes overlap too much.
object_links<L> overlap_filtered_links
- = filter::object_links_bbox_overlap(hratio_filtered_links, 0.80f);
+ = filter::object_links_bbox_overlap(hratio_filtered_links,
+ conf.bbox_overlap);
@@ -453,7 +487,8 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
image2d<value::rgb8> overlap_decision_image
= scribo::debug::decision_image(input,
hratio_filtered_links,
- overlap_filtered_links);
+ overlap_filtered_links,
+ anchor::MassCenter);
io::ppm::save(overlap_decision_image,
scribo::make::debug_filename("overlap_links_decision_image.ppm"));
}
@@ -514,7 +549,8 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
if (argc > 6 && atoi(argv[6]) != 0)
{
std::cout << "** Using group too small" << std::endl;
- filtered_small_groups = filter::object_groups_small(groups, 3);
+ filtered_small_groups = filter::object_groups_small(groups,
+ conf.small_groups);
}
else
filtered_small_groups = groups;
@@ -532,7 +568,7 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
scribo::draw::groups_bboxes(decision_image, groups, literal::red);
scribo::draw::groups_bboxes(decision_image, filtered_small_groups,
- literal::blue);
+ literal::green);
io::ppm::save(decision_image,
@@ -549,7 +585,8 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
{
std::cout << "** Using group too thin" << std::endl;
filtered_thin_groups
- = filter::object_groups_v_thickness(filtered_small_groups, 8);
+ = filter::object_groups_v_thickness(filtered_small_groups,
+ conf.v_thickness);
}
else
filtered_thin_groups = filtered_small_groups;
@@ -565,7 +602,7 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
scribo::draw::groups_bboxes(decision_image, filtered_small_groups,
literal::red);
scribo::draw::groups_bboxes(decision_image, filtered_thin_groups,
- literal::blue);
+ literal::green);
io::ppm::save(decision_image,
scribo::make::debug_filename("thin_groups_filter.ppm"));
@@ -578,7 +615,8 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
g_timer.restart();
// Grouping groups together if possible.
- groups = primitive::regroup::from_single_left_link(filtered_thin_groups, 30);
+ groups = primitive::regroup::from_single_left_link(filtered_thin_groups,
+ conf.regroup_dmax);
// component_set<L>
@@ -607,7 +645,8 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
{
std::cout << "** Using objects_with_two_holes" << std::endl;
- groups = scribo::filter::object_groups_with_holes(groups, 5);
+ groups = scribo::filter::object_groups_with_holes(groups,
+ conf.group_min_holes);
t_ = g_timer;
std::cout << "Objects_with_holes " << t_ << std::endl;
@@ -626,7 +665,9 @@ Common usage: ./ppm_text_in_photo input.ppm output.ppm 1 1 1 1 1",
{
decision_image = data::convert(value::rgb8(), input);
- scribo::draw::groups_bboxes(decision_image, groups, literal::blue);
+ scribo::draw::groups_bboxes(decision_image, filtered_thin_groups,
+ literal::red);
+ scribo::draw::groups_bboxes(decision_image, groups, literal::green);
io::ppm::save(decision_image, scribo::make::debug_filename("group_with_holes_filter.ppm"));
}
--
1.5.6.5
1
0
last-svn-commit-102-g2c6947d Add init() member to object_links structure.
by Guillaume Lazzara 03 Jun '10
by Guillaume Lazzara 03 Jun '10
03 Jun '10
* core/object_links.hh: New init() member.
* filter/object_groups_v_thickness.hh,
* filter/object_groups_with_holes.hh,
* primitive/group/from_double_link.hh,
* primitive/link/internal/link_functor_base.hh,
* primitive/link/merge_double_link.hh,
* src/afp/link.hh,
* src/afp/regroup.hh: Call init() on object_links instances.
* primitive/internal/init_link_array.hh: Remove.
---
scribo/ChangeLog | 78 ++++++++++++--------
scribo/core/object_links.hh | 35 +++++++++-
scribo/filter/object_groups_v_thickness.hh | 5 +-
scribo/filter/object_groups_with_holes.hh | 24 +-----
scribo/primitive/group/from_double_link.hh | 3 +-
scribo/primitive/internal/init_link_array.hh | 78 --------------------
.../primitive/link/internal/link_functor_base.hh | 5 +-
scribo/primitive/link/merge_double_link.hh | 1 -
scribo/src/afp/link.hh | 13 +--
scribo/src/afp/regroup.hh | 1 -
10 files changed, 95 insertions(+), 148 deletions(-)
delete mode 100644 scribo/primitive/internal/init_link_array.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index ffd4a39..a7134fa 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,41 +1,57 @@
2010-04-13 Guillaume Lazzara <z(a)lrde.epita.fr>
- * scribo/src/text_in_photo_fast.cc: Group routine parameters in a
- global structure.
+ Add init() member to object_links structure.
+
+ * core/object_links.hh: New init() member.
+
+ * filter/object_groups_v_thickness.hh,
+ * filter/object_groups_with_holes.hh,
+ * primitive/group/from_double_link.hh,
+ * primitive/link/internal/link_functor_base.hh,
+ * primitive/link/merge_double_link.hh,
+ * src/afp/link.hh,
+ * src/afp/regroup.hh: Call init() on object_links instances.
+
+ * primitive/internal/init_link_array.hh: Remove.
+
+2010-04-13 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * src/text_in_photo_fast.cc: Group routine parameters in a global
+ structure.
2010-04-13 Guillaume Lazzara <z(a)lrde.epita.fr>
Add new Sauvola overloads and update examples.
- * scribo/binarization/internal/first_pass_functor.hh,
- * scribo/binarization/local_threshold.hh,
- * scribo/binarization/sauvola.hh,
- * scribo/binarization/sauvola_ms.hh,
- * scribo/binarization/sauvola_ms_split.hh,
- * scribo/binarization/sauvola_threshold_image.hh,
- * scribo/canvas/integral_browsing.hh: Add more parameters to
- Sauvola routines.
-
- * scribo/binarization/sauvola_threshold_image_debug.hh: New. New
- overload providing debug outputs.
-
- * scribo/debug/usage.hh: Remove a parameter.
-
- * scribo/src/binarization/Makefile.am,
- * scribo/src/binarization/pgm_global_threshold_auto.cc,
- * scribo/src/binarization/pgm_sauvola.cc,
- * scribo/src/binarization/pgm_sauvola_ms.cc,
- * scribo/src/binarization/ppm_fg_sauvola_ms.cc,
- * scribo/src/binarization/ppm_sauvola.cc,
- * scribo/src/binarization/ppm_sauvola_ms.cc,
- * scribo/src/binarization/ppm_sauvola_ms_split.cc: Add new
- program arguments.
-
- * scribo/src/binarization/fg_sauvola_ms.cc,
- * scribo/src/binarization/sauvola.cc,
- * scribo/src/binarization/sauvola_ms.cc,
- * scribo/src/binarization/sauvola_ms_split.cc,
- * scribo/src/binarization/sauvola_debug.cc: New.
+ * binarization/internal/first_pass_functor.hh,
+ * binarization/local_threshold.hh,
+ * binarization/sauvola.hh,
+ * binarization/sauvola_ms.hh,
+ * binarization/sauvola_ms_split.hh,
+ * binarization/sauvola_threshold_image.hh,
+ * canvas/integral_browsing.hh: Add more parameters to Sauvola
+ routines.
+
+ * binarization/sauvola_threshold_image_debug.hh: New. New overload
+ providing debug outputs.
+
+ * debug/usage.hh: Remove a parameter.
+
+ * src/binarization/Makefile.am,
+ * src/binarization/pgm_global_threshold_auto.cc,
+ * src/binarization/pgm_sauvola.cc,
+ * src/binarization/pgm_sauvola_ms.cc,
+ * src/binarization/ppm_fg_sauvola_ms.cc,
+ * src/binarization/ppm_sauvola.cc,
+ * src/binarization/ppm_sauvola_ms.cc,
+ * src/binarization/ppm_sauvola_ms_split.cc: Add new program
+ arguments.
+
+ * src/binarization/fg_sauvola_ms.cc,
+ * src/binarization/sauvola.cc,
+ * src/binarization/sauvola_ms.cc,
+ * src/binarization/sauvola_ms_split.cc,
+ * src/binarization/sauvola_debug.cc: New.
2010-03-29 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/core/object_links.hh b/scribo/core/object_links.hh
index 654cb75..c10cae6 100644
--- a/scribo/core/object_links.hh
+++ b/scribo/core/object_links.hh
@@ -90,12 +90,18 @@ namespace scribo
const mln::util::array<unsigned>& comp_to_link() const;
+ void init();
private:
mln::util::tracked_ptr<data_t> data_;
};
+ template <typename L>
+ std::ostream&
+ operator<<(std::ostream& ostr, const object_links<L>& links);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -174,7 +180,7 @@ namespace scribo
unsigned
object_links<L>::nelements() const
{
- return data_->comp_to_link_.nelements() ;
+ return data_->comp_to_link_.nelements();
}
@@ -202,6 +208,33 @@ namespace scribo
}
+ template <typename L>
+ void
+ object_links<L>::init()
+ {
+ for (unsigned i = 0; i < nelements(); ++i)
+ if (data_->components_(i).tag() == component::Ignored)
+ data_->comp_to_link_(i) = 0;
+ else
+ data_->comp_to_link_(i) = i;
+ }
+
+
+ template <typename L>
+ std::ostream&
+ operator<<(std::ostream& ostr, const object_links<L>& links)
+ {
+ ostr << "object_links[";
+
+ for_all_links(l, links)
+ ostr << l << "->" << links.comp_to_link()[l] << ", ";
+
+ ostr << "]";
+
+ return ostr;
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/filter/object_groups_v_thickness.hh b/scribo/filter/object_groups_v_thickness.hh
index caac765..717b372 100644
--- a/scribo/filter/object_groups_v_thickness.hh
+++ b/scribo/filter/object_groups_v_thickness.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -75,7 +76,7 @@ namespace scribo
mln::util::array<float>
group_thickness = estim::object_groups_v_thickness(groups);
- object_groups<L> output(groups);
+ object_groups<L> output = groups.duplicate();
output(0) = 0;
for (unsigned i = 1; i < output.nelements(); ++i)
if (groups.components()(i).is_valid()
diff --git a/scribo/filter/object_groups_with_holes.hh b/scribo/filter/object_groups_with_holes.hh
index 1f31c01..570ae6a 100644
--- a/scribo/filter/object_groups_with_holes.hh
+++ b/scribo/filter/object_groups_with_holes.hh
@@ -42,33 +42,13 @@
# include <mln/draw/box_plain.hh>
# include <mln/util/array.hh>
-# include <mln/labeling/blobs_and_compute.hh>
-
# include <mln/accu/math/count.hh>
# include <mln/fun/i2v/array.hh>
-# include <mln/io/pbm/save.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/data/convert.hh>
-
-# include <mln/labeling/background.hh>
-
# include <scribo/core/macros.hh>
# include <scribo/core/component_set.hh>
-# include <scribo/filter/internal/compute.hh>
-
-# include <mln/data/fill.hh>
-# include <mln/data/paste.hh>
-
-# include <mln/util/timer.hh>
-
-# include <mln/value/label_16.hh>
-# include <mln/core/var.hh>
-
-#include <mln/debug/filename.hh>
namespace scribo
{
@@ -195,6 +175,9 @@ namespace scribo
data::fill(card, 1);
border::fill(card, 1);
+ // We want to label background components only in the
+ // group bounding boxes. Thus, this image is a labeling
+ // constraint.
bboxes_ima = internal::compute_bboxes_image(components);
to_keep(0) = true;
@@ -285,7 +268,6 @@ namespace scribo
if (! to_keep(groups(c)))
output(c) = 0;
-// output.update_tags(to_keep, component::Ignored);
trace::exiting("scribo::filter::impl::generic::object_groups_with_holes");
return output;
diff --git a/scribo/primitive/group/from_double_link.hh b/scribo/primitive/group/from_double_link.hh
index a1e8479..14c5972 100644
--- a/scribo/primitive/group/from_double_link.hh
+++ b/scribo/primitive/group/from_double_link.hh
@@ -46,7 +46,6 @@
# include <scribo/core/component_set.hh>
# include <scribo/primitive/internal/find_root.hh>
# include <scribo/primitive/internal/is_link_valid.hh>
-# include <scribo/primitive/internal/init_link_array.hh>
namespace scribo
@@ -94,7 +93,7 @@ namespace scribo
mln_precondition(right_link.components_id_() == components.id_());
object_groups<L> parent(components, left_link.nelements());
- internal::init_link_array(parent);
+ parent.init();
for_all_ncomponents(i, components.nlabels())
{
mln::util::couple<bool, unsigned>
diff --git a/scribo/primitive/internal/init_link_array.hh b/scribo/primitive/internal/init_link_array.hh
deleted file mode 100644
index 2b46ad5..0000000
--- a/scribo/primitive/internal/init_link_array.hh
+++ /dev/null
@@ -1,78 +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_PRIMITIVE_INTERNAL_INIT_LINK_ARRAY_HH
-# define SCRIBO_PRIMITIVE_INTERNAL_INIT_LINK_ARRAY_HH
-
-/// \file
-///
-/// Initialize a link array.
-
-
-# include <scribo/core/object_links.hh>
-# include <scribo/core/component_set.hh>
-
-
-namespace scribo
-{
-
- using namespace mln;
-
- namespace primitive
- {
-
- namespace internal
- {
-
- /// Initialize a link array.
- template <typename L>
- void
- init_link_array(object_links<L>& link_array);
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename L>
- inline
- void
- init_link_array(object_links<L>& link_array)
- {
- const component_set<L>& comp_set = link_array.components();
- for (unsigned i = 0; i < link_array.nelements(); ++i)
- if (comp_set(i).tag() == component::Ignored)
- link_array(i) = 0;
- else
- link_array(i) = i;
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace scribo::primitive::internal
-
- } // end of namespace scribo::primitive
-
-} // end of namespace scribo
-
-
-#endif // ! SCRIBO_PRIMITIVE_INTERNAL_INIT_LINK_ARRAY_HH
diff --git a/scribo/primitive/link/internal/link_functor_base.hh b/scribo/primitive/link/internal/link_functor_base.hh
index 5e4af46..f2641ad 100644
--- a/scribo/primitive/link/internal/link_functor_base.hh
+++ b/scribo/primitive/link/internal/link_functor_base.hh
@@ -45,7 +45,6 @@
# include <scribo/core/object_links.hh>
# include <scribo/core/concept/link_functor.hh>
# include <scribo/primitive/link/internal/compute_anchor.hh>
-# include <scribo/primitive/internal/init_link_array.hh>
# define scribo_support(T) typename T::support
# define scribo_support_(T) T::support
@@ -194,7 +193,7 @@ namespace scribo
labeled_image_(this->components_.labeled_image()),
nanchors_(nanchors)
{
- primitive::internal::init_link_array(links_);
+ links_.init();
}
@@ -207,7 +206,7 @@ namespace scribo
labeled_image_(this->components_.labeled_image()),
nanchors_(1)
{
- primitive::internal::init_link_array(links_);
+ links_.init();
}
diff --git a/scribo/primitive/link/merge_double_link.hh b/scribo/primitive/link/merge_double_link.hh
index 704c103..94a44ef 100644
--- a/scribo/primitive/link/merge_double_link.hh
+++ b/scribo/primitive/link/merge_double_link.hh
@@ -48,7 +48,6 @@
# include <scribo/core/component_set.hh>
# include <scribo/primitive/internal/find_root.hh>
# include <scribo/primitive/internal/is_link_valid.hh>
-# include <scribo/primitive/internal/init_link_array.hh>
namespace scribo
diff --git a/scribo/src/afp/link.hh b/scribo/src/afp/link.hh
index b6ef1f9..fc23991 100644
--- a/scribo/src/afp/link.hh
+++ b/scribo/src/afp/link.hh
@@ -3,7 +3,6 @@
#include <mln/util/couple.hh>
#include <scribo/core/component_set.hh>
#include <scribo/core/macros.hh>
-#include <scribo/primitive/internal/init_link_array.hh>
namespace scribo
{
@@ -21,21 +20,19 @@ namespace scribo
{
object_links<L>
right(components, static_cast<unsigned>(components.nelements()) + 1);
- primitive::internal::init_link_array(right);
+ right.init();
object_links<L>
left(components, static_cast<unsigned>(components.nelements()) + 1);
- primitive::internal::init_link_array(left);
+ left.init();
const L& lbl_ima = components.labeled_image();
for_all_comps(i, components)
{
float
- w = (components(i).bbox().pmax().col()
- - components(i).bbox().pmin().col()),
- h = (components(i).bbox().pmax().row()
- - components(i).bbox().pmin().row());
+ w = components(i).bbox().width(),
+ h = components(i).bbox().height();
unsigned dmax = (w / 2.0f) + (3 * math::max(w, h));
@@ -98,7 +95,7 @@ namespace scribo
{
object_links<L>
left(components, static_cast<unsigned>(components.nelements()) + 1);
- primitive::internal::init_link_array(left);
+ left.init();
const L& lbl_ima = components.labeled_image();
diff --git a/scribo/src/afp/regroup.hh b/scribo/src/afp/regroup.hh
index 3fcfcaa..44b5438 100644
--- a/scribo/src/afp/regroup.hh
+++ b/scribo/src/afp/regroup.hh
@@ -3,7 +3,6 @@
#include <mln/util/couple.hh>
#include <scribo/core/component_set.hh>
#include <scribo/core/macros.hh>
-#include <scribo/primitive/internal/init_link_array.hh>
namespace scribo
{
--
1.5.6.5
1
0
03 Jun '10
* core/object_groups.hh: Add more preconditions.
* filter/object_groups_small.hh: Call duplicate().
---
scribo/ChangeLog | 8 ++++++++
scribo/core/object_groups.hh | 2 ++
scribo/filter/object_groups_small.hh | 5 +++--
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index a7134fa..da11249 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,13 @@
2010-04-13 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Small fixes related to object_groups.
+
+ * core/object_groups.hh: Add more preconditions.
+
+ * filter/object_groups_small.hh: Call duplicate().
+
+2010-04-13 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add init() member to object_links structure.
* core/object_links.hh: New init() member.
diff --git a/scribo/core/object_groups.hh b/scribo/core/object_groups.hh
index be97c06..97334f2 100644
--- a/scribo/core/object_groups.hh
+++ b/scribo/core/object_groups.hh
@@ -165,6 +165,7 @@ namespace scribo
const object_links<L>&
object_groups<L>::links() const
{
+ mln_assertion(data_ != 0);
return data_->links_;
}
@@ -172,6 +173,7 @@ namespace scribo
void
object_groups<L>::init_(const object_links<L>& links)
{
+ mln_assertion(data_ != 0);
data_->comp_to_group_ = links.comp_to_link();
}
diff --git a/scribo/filter/object_groups_small.hh b/scribo/filter/object_groups_small.hh
index 60f8753..f736a50 100644
--- a/scribo/filter/object_groups_small.hh
+++ b/scribo/filter/object_groups_small.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -77,7 +78,7 @@ namespace scribo
for_all_groups(i, group_size)
++group_size[groups(i)];
- object_groups<L> output(groups);
+ object_groups<L> output = groups.duplicate();
output(0) = 0;
for_all_groups(i, output)
if (group_size[groups(i)] < n_links
--
1.5.6.5
1
0