* preprocessing/denoise.hh,
* preprocessing/denoise_bg.hh,
* preprocessing/denoise_fg.hh,
* preprocessing/homogeneous_contrast.hh,
* preprocessing/rotate_90.hh: New routines.
* fun/v2b/label_to_bool.hh: New function.
* tests/preprocessing/Makefile.am,
* tests/preprocessing/rotate_90.cc: New test.
---
scribo/ChangeLog | 15 ++
.../n2v/all.hh => scribo/fun/v2b/label_to_bool.hh | 43 ++++--
scribo/preprocessing/denoise.hh | 106 +++++++++++++
scribo/preprocessing/denoise_bg.hh | 156 +++++++++++++++++++
scribo/preprocessing/denoise_fg.hh | 131 ++++++++++++++++
scribo/preprocessing/homogeneous_contrast.hh | 119 +++++++++++++++
scribo/preprocessing/rotate_90.hh | 159 ++++++++++++++++++++
scribo/tests/preprocessing/Makefile.am | 4 +-
.../preprocessing/{unskew.cc => rotate_90.cc} | 29 +++-
9 files changed, 740 insertions(+), 22 deletions(-)
copy milena/mln/fun/n2v/all.hh => scribo/fun/v2b/label_to_bool.hh (66%)
create mode 100644 scribo/preprocessing/denoise.hh
create mode 100644 scribo/preprocessing/denoise_bg.hh
create mode 100644 scribo/preprocessing/denoise_fg.hh
create mode 100644 scribo/preprocessing/homogeneous_contrast.hh
create mode 100644 scribo/preprocessing/rotate_90.hh
copy scribo/tests/preprocessing/{unskew.cc => rotate_90.cc} (72%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 74cef68..8b4c4d7 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,20 @@
2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add new preprocessing routines.
+
+ * preprocessing/denoise.hh,
+ * preprocessing/denoise_bg.hh,
+ * preprocessing/denoise_fg.hh,
+ * preprocessing/homogeneous_contrast.hh,
+ * preprocessing/rotate_90.hh: New routines.
+
+ * fun/v2b/label_to_bool.hh: New function.
+
+ * tests/preprocessing/Makefile.am,
+ * tests/preprocessing/rotate_90.cc: New test.
+
+2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Update code according to last changes in Scribo core classes.
* draw/bounding_box_links.hh,
diff --git a/milena/mln/fun/n2v/all.hh b/scribo/fun/v2b/label_to_bool.hh
similarity index 66%
copy from milena/mln/fun/n2v/all.hh
copy to scribo/fun/v2b/label_to_bool.hh
index 0e0e55c..3d65401 100644
--- a/milena/mln/fun/n2v/all.hh
+++ b/scribo/fun/v2b/label_to_bool.hh
@@ -23,29 +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_FUN_N2V_ALL_HH
-# define MLN_FUN_N2V_ALL_HH
+#ifndef SCRIBO_FUN_V2B_LABEL_TO_BOOL_HH
+# define SCRIBO_FUN_V2B_LABEL_TO_BOOL_HH
-/// \file
-///
-/// File that includes all functions from nil to value.
+# include <mln/core/concept/function.hh>
+# include <mln/fun/i2v/array.hh>
-namespace mln
+namespace scribo
{
namespace fun
{
- /// \brief Namespace of functions from nil to value.
- ///
- /// \ingroup modfun
- namespace n2v {}
+ namespace v2b
+ {
- }
-}
+ template <typename L>
+ struct label_to_bool : mln::Function_v2b<label_to_bool<L> >
+ {
+ typedef bool result;
+ label_to_bool(const mln::fun::i2v::array<bool>& f)
+ : f_(f)
+ {}
-# include <mln/fun/n2v/white_gaussian.hh>
+ bool operator()(const L& v) const
+ {
+ return f_(v);
+ }
-#endif // ! MLN_FUN_N2V_ALL_HH
+ mln::fun::i2v::array<bool> f_;
+ };
+
+ } // end of namespace scribo::fun::v2b
+
+ } // end of namespace scribo::fun
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FUN_V2B_LABEL_TO_BOOL_HH
diff --git a/scribo/preprocessing/denoise.hh b/scribo/preprocessing/denoise.hh
new file mode 100644
index 0000000..1877c06
--- /dev/null
+++ b/scribo/preprocessing/denoise.hh
@@ -0,0 +1,106 @@
+// 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_PREPROCESSING_DENOISE_HH
+# define SCRIBO_PREPROCESSING_DENOISE_HH
+
+/// \file
+///
+/// Denoise an image.
+
+# include <scribo/preprocessing/denoise_fg.hh>
+# include <scribo/preprocessing/denoise_bg.hh>
+
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ using namespace mln;
+
+ /// \brief Denoise an image.
+ /// Denoising is performed both on the foreground and the background.
+ ///
+ /// \param[in] input A binary image. True for objects, False for
+ /// background.
+ /// \param[in] nbh Neighborhood to use for denoising.
+ /// \param[in] min_card Minimum component cardinality to not be
+ /// considered as noise.
+ ///
+ /// \output A binary image with the same domain as \p input. All
+ /// small components have been removed.
+ //
+ template <typename I, typename N>
+ mln_concrete(I)
+ denoise(const Image<I>& input, const Neighborhood<N>& nbh,
+ unsigned fg_min_card, unsigned bg_min_card);
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ denoise(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ unsigned fg_min_card, unsigned bg_min_card)
+ {
+ trace::entering("scribo::preprocessing::denoise");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ mlc_equal(mln_value(I), bool)::check();
+ mln_precondition(input.is_valid());
+
+ mln_concrete(I) output;
+
+ output = denoise_fg(input, nbh, fg_min_card);
+ output = denoise_bg(output, nbh, bg_min_card);
+
+ trace::exiting("scribo::preprocessing::denoise");
+ return output;
+ }
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+# endif // SCRIBO_PREPROCESSING_DENOISE_HH
diff --git a/scribo/preprocessing/denoise_bg.hh b/scribo/preprocessing/denoise_bg.hh
new file mode 100644
index 0000000..9242f36
--- /dev/null
+++ b/scribo/preprocessing/denoise_bg.hh
@@ -0,0 +1,156 @@
+// 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_PREPROCESSING_DENOISE_BG_HH
+# define SCRIBO_PREPROCESSING_DENOISE_BG_HH
+
+/// \file
+///
+/// Denoise image background.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/data/transform.hh>
+
+# include <mln/accu/math/count.hh>
+
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/util/array.hh>
+# include <mln/fun/i2v/array.hh>
+
+# include <mln/labeling/compute.hh>
+# include <mln/labeling/background.hh>
+
+# include <scribo/fun/v2b/label_to_bool.hh>
+
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ using namespace mln;
+
+ /// Denoise image background.
+ ///
+ /// \param[in] input A binary image. True for objects, False for
+ /// background.
+ /// \param[in] nbh Neighborhood to use for denoising.
+ /// \param[in] min_card Minimum component cardinality to not be
+ /// considered as noise.
+ ///
+ /// \output A binary image with the same domain as \p input. All
+ /// small components have been removed and merged with the
+ /// background.
+ //
+ template <typename I, typename N>
+ mln_concrete(I)
+ denoise_bg(const Image<I>& input, const Neighborhood<N>& nbh,
+ unsigned min_card);
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+namespace mln
+{
+
+
+ template <typename L>
+ struct label_to_bool : Function_v2b<label_to_bool<L> >
+ {
+ typedef bool result;
+
+ label_to_bool(const fun::i2v::array<bool>& f)
+ : f_(f)
+ {}
+
+ bool operator()(const L& v) const
+ {
+ return f_(v);
+ }
+
+ fun::i2v::array<bool> f_;
+ };
+
+
+} // end of namespace mln
+
+
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ denoise_bg(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ unsigned min_card)
+ {
+ trace::entering("scribo::preprocessing::denoise_bg");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ mlc_equal(mln_value(I), bool)::check();
+ mln_precondition(input.is_valid());
+
+ unsigned nlabels;
+ image2d<unsigned> lbl = labeling::background(input, nbh, nlabels);
+
+ util::array<unsigned>
+ result = labeling::compute(accu::meta::math::count(), lbl, nlabels);
+
+ mln::fun::i2v::array<bool> f(nlabels + 1, true);
+ f(0) = false;
+ for (unsigned i = 1; i <= nlabels; ++i)
+ if (result(i) < min_card)
+ f(i) = false;
+
+ scribo::fun::v2b::label_to_bool<unsigned> relabel_f(f);
+ mln_concrete(I)
+ output = data::transform(lbl, relabel_f);
+
+ trace::exiting("scribo::preprocessing::denoise_bg");
+ return output;
+ }
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+# endif // SCRIBO_PREPROCESSING_DENOISE_BG_HH
diff --git a/scribo/preprocessing/denoise_fg.hh b/scribo/preprocessing/denoise_fg.hh
new file mode 100644
index 0000000..5909164
--- /dev/null
+++ b/scribo/preprocessing/denoise_fg.hh
@@ -0,0 +1,131 @@
+// 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_PREPROCESSING_DENOISE_FG_HH
+# define SCRIBO_PREPROCESSING_DENOISE_FG_HH
+
+/// \file
+///
+/// Denoise image foreground.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/data/transform.hh>
+
+# include <mln/accu/math/count.hh>
+
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/util/array.hh>
+# include <mln/fun/i2v/array.hh>
+
+# include <mln/labeling/foreground.hh>
+# include <mln/labeling/compute.hh>
+
+# include <scribo/fun/v2b/label_to_bool.hh>
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ using namespace mln;
+
+ /// Denoise image foreground.
+ ///
+ /// \param[in] input A binary image. True for objects, False for
+ /// background.
+ /// \param[in] nbh Neighborhood to use for denoising.
+ /// \param[in] min_card Minimum component cardinality to not be
+ /// considered as noise.
+ ///
+ /// \output A binary image with the same domain as \p input. All
+ /// small components have been removed and merged with the
+ /// background.
+ //
+ template <typename I, typename N>
+ mln_concrete(I)
+ denoise_fg(const Image<I>& input, const Neighborhood<N>& nbh,
+ unsigned min_card);
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ denoise_fg(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ unsigned min_card)
+ {
+ trace::entering("scribo::preprocessing::denoise_fg");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ mlc_equal(mln_value(I), bool)::check();
+ mln_precondition(input.is_valid());
+
+ // FIXME:
+ unsigned nlabels;
+ image2d<unsigned> lbl = labeling::foreground(input, nbh, nlabels);
+
+ mln::util::array<unsigned>
+ result = labeling::compute(accu::meta::math::count(), lbl, nlabels);
+
+ mln::fun::i2v::array<bool> f(nlabels + 1, true);
+ f(0) = false;
+ for (unsigned i = 1; i <= nlabels; ++i)
+ if (result(i) < min_card)
+ f(i) = false;
+
+ scribo::fun::v2b::label_to_bool<unsigned> relabel_f(f);
+ mln_concrete(I)
+ output = data::transform(lbl, relabel_f);
+
+ trace::exiting("scribo::preprocessing::denoise_fg");
+ return output;
+ }
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+# endif // SCRIBO_PREPROCESSING_DENOISE_FG_HH
diff --git a/scribo/preprocessing/homogeneous_contrast.hh
b/scribo/preprocessing/homogeneous_contrast.hh
new file mode 100644
index 0000000..82b2ac6
--- /dev/null
+++ b/scribo/preprocessing/homogeneous_contrast.hh
@@ -0,0 +1,119 @@
+// 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_PREPROCESSING_HOMOGENEOUS_CONTRAST_HH
+# define SCRIBO_PREPROCESSING_HOMOGENEOUS_CONTRAST_HH
+
+/// \file
+///
+/// Improve contrast homogeneity in an image.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/morpho/attribute/height.hh>
+#include <mln/morpho/closing/leveling.hh>
+
+#include <mln/arith/minus.hh>
+
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+
+ using namespace mln;
+
+ /// \brief Improve contrast homogeneity in an image.
+ ///
+ /// \param[in] input A gray-level image.
+ /// \param[in] h Height attribute value for leveling closing.
+ ///
+ /// \output A gray-level image with better contrast homogeneity.
+ //
+ template <typename I>
+ mln_concrete(I)
+ homogeneous_contrast(const Image<I>& input, unsigned h);
+
+
+ /// \overload.
+ /// Default height attribute value is set to 75.
+ //
+ template <typename I>
+ mln_concrete(I)
+ homogeneous_contrast(const Image<I>& input);
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+
+ template <typename I>
+ mln_concrete(I)
+ homogeneous_contrast(const Image<I>& input_, unsigned h)
+ {
+ trace::entering("scribo::preprocessing::homogeneous_contrast");
+
+ const I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ morpho::attribute::height<I> acc;
+ mln_concrete(I)
+ output = morpho::closing::leveling(input, c4(), acc, h);
+ arith::minus_inplace(output, input);
+
+ trace::exiting("scribo::preprocessing::homogeneous_contrast");
+ return output;
+ }
+
+
+ template <typename I>
+ mln_concrete(I)
+ homogeneous_contrast(const Image<I>& input)
+ {
+ return homogeneous_contrast(input, 75);
+ }
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+# endif // SCRIBO_PREPROCESSING_HOMOGENEOUS_CONTRAST_HH
diff --git a/scribo/preprocessing/rotate_90.hh b/scribo/preprocessing/rotate_90.hh
new file mode 100644
index 0000000..616c341
--- /dev/null
+++ b/scribo/preprocessing/rotate_90.hh
@@ -0,0 +1,159 @@
+// 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_PREPROCESSING_ROTATE_90_HH
+# define SCRIBO_PREPROCESSING_ROTATE_90_HH
+
+/// \file
+///
+/// Fast +90/-90 degrees rotation.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/geom/all.hh>
+
+// FIXME: not generic
+# include <mln/core/alias/dpoint2d.hh>
+
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ using namespace mln;
+
+ /*! \brief Perform a +90/-90 degrees rotation.
+
+ \param[in] input An image.
+ \param[in] positive If set to true, performs a +90° rotation,
+ -90° otherwise.
+
+ \return A rotated image.
+ */
+ template <typename I>
+ mln_concrete(I)
+ rotate_90(const Image<I>& input, bool positive);
+
+ /// \brief Performs a +90° rotation.
+ /// \overload
+ //
+ template <typename I>
+ mln_concrete(I)
+ rotate_90(const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I>
+ mln_concrete(I)
+ rotate_90(const Image<I>& input_, bool positive)
+ {
+ trace::entering("scribo::preprocessing::rotate_90");
+
+ const I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ // Works only on one block images.
+ mlc_is(mln_trait_image_value_access(I),
+ mln::trait::image::value_access::direct)::check();
+ mlc_is(mln_trait_image_value_storage(I),
+ mln::trait::image::value_storage::one_block)::check();
+
+ // Initialize output domain and make sure the border size is the
+ // same as input's.
+ mln_site(I) pmax(input.domain().pmax().col(),
+ input.domain().pmax().row());
+ mln_concrete(I) output(mln_domain(I)(input.domain().pmin(), pmax),
+ input.border());
+
+ const mln_value(I)* in_ptr = input.buffer();
+
+ unsigned in_ncols = geom::ncols(input) + 2 * input.border();
+ unsigned in_nrows = geom::nrows(input) + 2 * input.border();
+
+ unsigned out_ncols = geom::ncols(output);
+ unsigned out_nrows = geom::nrows(output);
+
+ unsigned
+ out_next_offset,
+ out_next_p_offset;
+
+ mln_value(I)* out_ptr = output.buffer();
+
+ if (positive) // +90 deg
+ {
+ dpoint2d dp(- out_nrows - 2 * output.border(), - 1);
+ out_next_offset = output.delta_index(dp);
+
+ out_next_p_offset = output.delta_index(dpoint2d(+1, 0));
+
+ out_ptr += 2 * output.border() + out_ncols - 1;
+ }
+ else // -90 deg
+ {
+ dpoint2d dp(out_nrows + 2 * output.border(), + 1);
+ out_next_offset = output.delta_index(dp);
+
+ out_next_p_offset = output.delta_index(dpoint2d(-1, 0));
+
+ out_ptr += output.delta_index(dpoint2d(out_nrows + 2 * output.border() - 1, 0));
+ }
+
+ for (unsigned row = 0; row < in_nrows; ++row)
+ {
+ for (unsigned col = 0; col < in_ncols;
+ ++col, ++in_ptr, out_ptr += out_next_p_offset)
+ *out_ptr = *in_ptr;
+
+ out_ptr += out_next_offset;
+ }
+
+ trace::exiting("scribo::preprocessing::rotate_90");
+ return output;
+ }
+
+
+ template <typename I>
+ mln_concrete(I)
+ rotate_90(const Image<I>& input)
+ {
+ return rotate_90(input, true);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace mln
+
+
+# endif // SCRIBO_PREPROCESSING_ROTATE_90_HH
+
diff --git a/scribo/tests/preprocessing/Makefile.am
b/scribo/tests/preprocessing/Makefile.am
index 4666033..4a6790c 100644
--- a/scribo/tests/preprocessing/Makefile.am
+++ b/scribo/tests/preprocessing/Makefile.am
@@ -20,8 +20,10 @@
include $(top_srcdir)/scribo/tests/tests.mk
check_PROGRAMS = \
- unskew
+ unskew \
+ rotate_90
unskew_SOURCES = unskew.cc
+rotate_90_SOURCES = rotate_90.cc
TESTS = $(check_PROGRAMS)
diff --git a/scribo/tests/preprocessing/unskew.cc
b/scribo/tests/preprocessing/rotate_90.cc
similarity index 72%
copy from scribo/tests/preprocessing/unskew.cc
copy to scribo/tests/preprocessing/rotate_90.cc
index 9c84951..0c2286a 100644
--- a/scribo/tests/preprocessing/unskew.cc
+++ b/scribo/tests/preprocessing/rotate_90.cc
@@ -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.
//
@@ -24,21 +24,36 @@
// executable file might be covered by the GNU General Public License.
#include <mln/core/image/image2d.hh>
+#include <mln/data/compare.hh>
#include <mln/io/pbm/load.hh>
-#include <mln/io/pbm/save.hh>
-
-#include <scribo/preprocessing/unskew.hh>
+#include <mln/make/image.hh>
+#include <scribo/preprocessing/rotate_90.hh>
#include <scribo/tests/data.hh>
+
int main(int argc, char *argv[])
{
(void) argc;
(void) argv;
using namespace mln;
- image2d<bool> ima;
- io::pbm::load(ima, SCRIBO_IMG_DIR "/text_to_group.pbm");
- io::pbm::save(scribo::preprocessing::unskew(ima).first(), "unskew.pbm");
+ bool data[][1] = { { 0 },
+ { 1 },
+ { 0 },
+ { 1 },
+ { 0 },
+ { 1 },
+ { 0 },
+ { 1 },
+ { 0 },
+ { 1 } };
+
+ image2d<bool> ima = make::image(data);
+
+ image2d<bool> tmp = scribo::preprocessing::rotate_90(ima, true);
+ tmp = scribo::preprocessing::rotate_90(tmp, false);
+
+ mln_assertion(tmp == ima);
}
--
1.5.6.5