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
September 2007
- 7 participants
- 135 discussions
11 Sep '07
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-11 Simon Nivault <simon.nivault(a)lrde.epita.fr>
Move fast erosion and add fast dilation with max accu
* mln/accu/max_h.hh: New. Max Accu.
* mln/level/ero.hh: Rename as...
* mln/morpho/erosion_fast.hh: ...this.
* mln/morpho/dilation_fast.hh: Fast dilation.
* tests/morpho_dilation_max_h.cc: New.
* tests/morpho_erosion_min_h.cc: Update.
---
mln/accu/max_h.hh | 241 +++++++++++++++++++++++++++++++++++++++++
mln/morpho/dilation_fast.hh | 188 +++++++++++++++++++++++++++++++
mln/morpho/erosion_fast.hh | 188 +++++++++++++++++++++++++++++++
tests/morpho_dilation_max_h.cc | 65 +++++++++++
tests/morpho_erosion_min_h.cc | 4
5 files changed, 684 insertions(+), 2 deletions(-)
Index: trunk/milena/tests/morpho_dilation_max_h.cc
===================================================================
--- trunk/milena/tests/morpho_dilation_max_h.cc (revision 0)
+++ trunk/milena/tests/morpho_dilation_max_h.cc (revision 1099)
@@ -0,0 +1,65 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/*! \file tests/morpho_erosion.cc
+ *
+ * \brief Test on mln::morpho::erosion.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/win/rectangle2d.hh>
+#include <mln/core/window2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/morpho/dilation_fast.hh>
+
+#include <mln/convert/to_vec_p.hh>
+#include <mln/convert/to_window.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ win::rectangle2d rec(21, 21);
+ border::thickness = 66;
+
+ image2d_b<int_u8> lena = io::pgm::load("../img/lena.pgm");
+
+ {
+ vec_p<point2d> vec = convert::to_vec_p(rec, point2d::zero);
+ window2d win = convert::to_window(vec);
+
+ image2d_b<int_u8> out(lena.domain());
+ morpho::dilation_fast(lena, win, out);
+ io::pgm::save(out, "out.pgm");
+ }
+}
Index: trunk/milena/tests/morpho_erosion_min_h.cc
===================================================================
--- trunk/milena/tests/morpho_erosion_min_h.cc (revision 1098)
+++ trunk/milena/tests/morpho_erosion_min_h.cc (revision 1099)
@@ -38,7 +38,7 @@
#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
-#include <mln/level/ero.hh>
+#include <mln/morpho/erosion_fast.hh>
#include <mln/convert/to_vec_p.hh>
#include <mln/convert/to_window.hh>
@@ -59,7 +59,7 @@
window2d win = convert::to_window(vec);
image2d_b<int_u8> out(lena.domain());
- level::ero(lena, win, out);
+ morpho::erosion_fast(lena, win, out);
io::pgm::save(out, "out.pgm");
}
}
Index: trunk/milena/mln/morpho/erosion_fast.hh
===================================================================
--- trunk/milena/mln/morpho/erosion_fast.hh (revision 0)
+++ trunk/milena/mln/morpho/erosion_fast.hh (revision 1099)
@@ -0,0 +1,188 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_MORPHO_EROSION_FAST_HH
+# define MLN_MORPHO_EROSION_FAST_HH
+
+/*! \file mln/morpho/erosion_fast.hh
+ *
+ * \brief Ero filtering of an image.
+ *
+ * \todo Add Fast_Image versions.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/window.hh>
+# include <mln/geom/shift.hh>
+# include <mln/set/diff.hh>
+
+# include <mln/canvas/browsing/snake_fwd.hh>
+# include <mln/accu/min_h.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Compute in \p output the ero filter of image \p input by
+ * the window \p win.
+ *
+ * \param[in] input The image to be filtered.
+ * \param[in] win The window.
+ * \param[out] output The output image.
+ *
+ * \pre \p input and \p output have to be initialized.
+ */
+ template <typename I, typename W, typename O>
+ void erosion_fast(const Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+
+ // Functors.
+
+
+ template <typename I, typename W, typename O>
+ struct erosion_fast_t
+ {
+ typedef mln_point(I) P;
+ typedef mln_dpoint(I) D;
+
+ // i/o
+
+ const I& input;
+ const W& win;
+ O& output;
+
+ // aux data
+
+ accu::min_h<mln_vset(I)> min;
+ P p;
+ window<D> win_fp, win_fm, win_bp, win_bm, win_dp, win_dm;
+ mln_qiter(W) q_fp, q_fm, q_bp, q_bm, q_dp, q_dm;
+
+ // ctor
+
+ erosion_fast_t(const I& input_, const W& win_, O& output_)
+ :
+ // i/o
+ input(exact(input_)),
+ win(exact(win_)),
+ output(exact(output_)),
+ // aux data
+ min(input.values()),
+ p(),
+ win_fp(set::diff(win, geom::shift(win, left))),
+ win_fm(set::diff(geom::shift(win, left), win)),
+ win_bp(set::diff(win, geom::shift(win, right))),
+ win_bm(set::diff(geom::shift(win, right), win)),
+ win_dp(set::diff(win, geom::shift(win, up))),
+ win_dm(set::diff(geom::shift(win, up), win)),
+ q_fp(win_fp, p), q_fm(win_fm, p),
+ q_bp(win_bp, p), q_bm(win_bm, p),
+ q_dp(win_dp, p), q_dm(win_dm, p)
+ {
+ }
+
+ // parts
+
+ void init()
+ {
+ min.init();
+ mln_qiter(W) q(win, p);
+ for_all(q) if (input.has(q))
+ min.take(input(q));
+ }
+
+ void down()
+ {
+ for_all(q_dm) if (input.has(q_dm))
+ min.untake(input(q_dm));
+ for_all(q_dp) if (input.has(q_dp))
+ min.take(input(q_dp));
+ output(p) = min.to_value();
+ }
+
+ void fwd()
+ {
+ for_all(q_fm) if (input.has(q_fm))
+ min.untake(input(q_fm));
+ for_all(q_fp) if (input.has(q_fp))
+ min.take(input(q_fp));
+ output(p) = min.to_value();
+ }
+
+ void bkd()
+ {
+ for_all(q_bm) if (input.has(q_bm))
+ min.untake(input(q_bm));
+ for_all(q_bp) if (input.has(q_bp))
+ min.take(input(q_bp));
+ output(p) = min.to_value();
+ }
+
+ }; // end of erosion_fast_t
+
+
+ template <typename I, typename W, typename O>
+ void erosion_fast_(const Image<I>& input, const Window<W>& win, O& output)
+ {
+ // FIXME: resize border!
+ erosion_fast_t<I,W,O> f(exact(input), exact(win), output);
+ canvas::browsing::snake_fwd(f);
+ }
+
+ } // end of namespace mln::morpho::impl
+
+
+ // Facades.
+
+ template <typename I, typename W, typename O>
+ void erosion_fast(const Image<I>& input, const Window<W>& win,
+ Image<O>& output)
+ {
+ mln_assertion(exact(output).domain() == exact(input).domain());
+ impl::erosion_fast_(exact(input), exact(win), exact(output));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_EROSION_FAST_HH
Index: trunk/milena/mln/morpho/dilation_fast.hh
===================================================================
--- trunk/milena/mln/morpho/dilation_fast.hh (revision 0)
+++ trunk/milena/mln/morpho/dilation_fast.hh (revision 1099)
@@ -0,0 +1,188 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_MORPHO_DILATION_FAST_HH
+# define MLN_MORPHO_DILATION_FAST_HH
+
+/*! \file mln/morpho/dilation_fast.hh
+ *
+ * \brief Ero filtering of an image.
+ *
+ * \todo Add Fast_Image versions.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/window.hh>
+# include <mln/geom/shift.hh>
+# include <mln/set/diff.hh>
+
+# include <mln/canvas/browsing/snake_fwd.hh>
+# include <mln/accu/max_h.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ /*! Compute in \p output the dilation filter of image \p input by
+ * the window \p win.
+ *
+ * \param[in] input The image to be filtered.
+ * \param[in] win The window.
+ * \param[out] output The output image.
+ *
+ * \pre \p input and \p output have to be initialized.
+ */
+ template <typename I, typename W, typename O>
+ void dilation_fast(const Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+
+ // Functors.
+
+
+ template <typename I, typename W, typename O>
+ struct dilation_fast_t
+ {
+ typedef mln_point(I) P;
+ typedef mln_dpoint(I) D;
+
+ // i/o
+
+ const I& input;
+ const W& win;
+ O& output;
+
+ // aux data
+
+ accu::max_h<mln_vset(I)> max;
+ P p;
+ window<D> win_fp, win_fm, win_bp, win_bm, win_dp, win_dm;
+ mln_qiter(W) q_fp, q_fm, q_bp, q_bm, q_dp, q_dm;
+
+ // ctor
+
+ dilation_fast_t(const I& input_, const W& win_, O& output_)
+ :
+ // i/o
+ input(exact(input_)),
+ win(exact(win_)),
+ output(exact(output_)),
+ // aux data
+ max(input.values()),
+ p(),
+ win_fp(set::diff(win, geom::shift(win, left))),
+ win_fm(set::diff(geom::shift(win, left), win)),
+ win_bp(set::diff(win, geom::shift(win, right))),
+ win_bm(set::diff(geom::shift(win, right), win)),
+ win_dp(set::diff(win, geom::shift(win, up))),
+ win_dm(set::diff(geom::shift(win, up), win)),
+ q_fp(win_fp, p), q_fm(win_fm, p),
+ q_bp(win_bp, p), q_bm(win_bm, p),
+ q_dp(win_dp, p), q_dm(win_dm, p)
+ {
+ }
+
+ // parts
+
+ void init()
+ {
+ max.init();
+ mln_qiter(W) q(win, p);
+ for_all(q) if (input.has(q))
+ max.take(input(q));
+ }
+
+ void down()
+ {
+ for_all(q_dm) if (input.has(q_dm))
+ max.untake(input(q_dm));
+ for_all(q_dp) if (input.has(q_dp))
+ max.take(input(q_dp));
+ output(p) = max.to_value();
+ }
+
+ void fwd()
+ {
+ for_all(q_fm) if (input.has(q_fm))
+ max.untake(input(q_fm));
+ for_all(q_fp) if (input.has(q_fp))
+ max.take(input(q_fp));
+ output(p) = max.to_value();
+ }
+
+ void bkd()
+ {
+ for_all(q_bm) if (input.has(q_bm))
+ max.untake(input(q_bm));
+ for_all(q_bp) if (input.has(q_bp))
+ max.take(input(q_bp));
+ output(p) = max.to_value();
+ }
+
+ }; // end of dilation_fast_t
+
+
+ template <typename I, typename W, typename O>
+ void dilation_fast_(const Image<I>& input, const Window<W>& win, O& output)
+ {
+ // FIXME: resize border!
+ dilation_fast_t<I,W,O> f(exact(input), exact(win), output);
+ canvas::browsing::snake_fwd(f);
+ }
+
+ } // end of namespace mln::level::impl
+
+
+ // Facades.
+
+ template <typename I, typename W, typename O>
+ void dilation_fast(const Image<I>& input, const Window<W>& win,
+ Image<O>& output)
+ {
+ mln_assertion(exact(output).domain() == exact(input).domain());
+ impl::dilation_fast_(exact(input), exact(win), exact(output));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_DILATION_FAST_HH
Index: trunk/milena/mln/level/ero.hh (deleted)
===================================================================
Index: trunk/milena/mln/accu/max_h.hh
===================================================================
--- trunk/milena/mln/accu/max_h.hh (revision 0)
+++ trunk/milena/mln/accu/max_h.hh (revision 1099)
@@ -0,0 +1,241 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_ACCU_MAX_H_HH
+# define MLN_ACCU_MAX_H_HH
+
+/*! \file mln/accu/max_h.hh
+ *
+ * \brief Define a generic max accumulator class based on histogram.
+ */
+
+# include <mln/core/concept/accumulator.hh>
+# include <mln/accu/histo.hh>
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+
+ /*! Generic max function based on histogram over a value set with
+ * type \c S.
+ */
+ template <typename S>
+ struct max_h : public Accumulator< max_h<S> >
+ {
+ typedef mln_value(S) value;
+
+ max_h(const Value_Set<S>& s);
+ max_h();
+
+ void init();
+ void take(const value& v);
+ void take_as_init(const value& v);
+ void take(const max_h<S>& other);
+ void untake(const value& v);
+
+ unsigned card() const { return h_.sum(); }
+
+ value to_value() const;
+
+ const accu::histo<S>& histo() const;
+
+ protected:
+
+ mutable accu::histo<S> h_;
+ const S& s_; // derived from h_
+
+ mutable std::size_t sum_;
+ mutable bool valid_;
+ mutable std::size_t i_; // the max index
+ mutable value v_; // the max value
+
+ // Auxiliary methods
+ void update_() const;
+ void go_minus_() const;
+ void go_plus_() const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename S>
+ max_h<S>::max_h(const Value_Set<S>& s)
+ : h_(s),
+ s_(h_.vset())
+ {
+ init();
+ }
+
+ template <typename S>
+ max_h<S>::max_h()
+ : h_(),
+ s_(h_.vset())
+ {
+ init();
+ }
+
+ template <typename S>
+ void
+ max_h<S>::take(const value& v)
+ {
+ h_.take(v);
+ if (h_.sum() == 1)
+ {
+ this->take_as_init(v);
+ return;
+ }
+ if (v > v_)
+ {
+ ++sum_;
+ valid_ = false;
+ }
+ }
+
+ template <typename S>
+ void
+ max_h<S>::take(const max_h<S>& other)
+ {
+ // h_
+ h_.take(other.h_);
+ for (unsigned i = this->card() - 1; i > i_; --i)
+ sum_ += other.h_[i];
+ valid_ = false;
+ // FIXME: Optimize.
+ }
+
+ template <typename S>
+ void
+ max_h<S>::untake(const value& v)
+ {
+ mln_precondition(h_(v) != 0);
+ h_.untake(v);
+ if (h_.sum() == 0)
+ {
+ init();
+ return;
+ }
+ if (v > v_)
+ {
+ mln_invariant(sum_ >= 1);
+ --sum_;
+ valid_ = false;
+ }
+ else
+ if (v == v_ && h_[i_] == 0)
+ valid_ = false;
+ }
+
+ template <typename S>
+ void
+ max_h<S>::update_() const
+ {
+ if (sum_ != 0)
+ go_plus_();
+ else
+ if (h_[i_] == 0)
+ go_minus_();
+ valid_ = true;
+ }
+
+ template <typename S>
+ void
+ max_h<S>::go_minus_() const
+ {
+ do
+ --i_;
+ while (h_[i_] == 0);
+ }
+
+ template <typename S>
+ void
+ max_h<S>::go_plus_() const
+ {
+ do
+ {
+ ++i_;
+ if (h_[i_] != 0)
+ sum_ -= h_[i_];
+ } while (sum_ != 0);
+ v_ = s_[i_];
+ }
+
+ template <typename S>
+ void
+ max_h<S>::init()
+ {
+ h_.init();
+ sum_ = 0;
+ i_ = mln_min(value);
+ v_ = s_[i_];
+ valid_ = true;
+ }
+
+ template <typename S>
+ void
+ max_h<S>::take_as_init(const value& v)
+ {
+ h_.take(v);
+ sum_ = 0;
+ i_ = s_.index_of(v);
+ v_ = v;
+ valid_ = true;
+ }
+
+ template <typename S>
+ typename max_h<S>::value
+ max_h<S>::to_value() const
+ {
+ if (! valid_)
+ update_();
+ return v_;
+ }
+
+ template <typename S>
+ const accu::histo<S>&
+ max_h<S>::histo() const
+ {
+ return h_;
+ }
+
+ template <typename S>
+ std::ostream& operator<<(std::ostream& ostr, const max_h<S>& m)
+ {
+ return ostr << m.to_value();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_MAX_H_HH
1
0
milena r1098: add rgb value type and separate prinln and println_with_border
by Matthieu Garrigues 10 Sep '07
by Matthieu Garrigues 10 Sep '07
10 Sep '07
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-10 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
add rgb value type and separate prinln and println_with_border
* mln/debug/println.hh: Splitted
* mln/debug/println_with_border.hh: New.
* mln/value/rgb.hh: templated value rgb<n>
* mln/value/rgb8.hh: just a typedef
* mln/value/rgb8_non_templated.hh: the old version without template
(to delete)
* tests/debug_println_with_border.cc: (uplate includes)
* tests/value_rgb8.cc: tests rgb operation
---
mln/debug/println.hh | 30 ----
mln/debug/println_with_border.hh | 102 ++++++++++++++++
mln/value/rgb.hh | 224 +++++++++++++++++++++++++++++++++++++
mln/value/rgb8.hh | 63 ----------
mln/value/rgb8_non_templated.hh | 191 +++++++++++++++++++++++++++++++
tests/debug_println_with_border.cc | 1
tests/value_rgb8.cc | 25 +++-
7 files changed, 543 insertions(+), 93 deletions(-)
Index: trunk/milena/tests/debug_println_with_border.cc
===================================================================
--- trunk/milena/tests/debug_println_with_border.cc (revision 1097)
+++ trunk/milena/tests/debug_println_with_border.cc (revision 1098)
@@ -34,6 +34,7 @@
#include <mln/core/image1d_b.hh>
#include <mln/level/fill.hh>
#include <mln/debug/println.hh>
+#include <mln/debug/println_with_border.hh>
using namespace mln;
Index: trunk/milena/tests/value_rgb8.cc
===================================================================
--- trunk/milena/tests/value_rgb8.cc (revision 1097)
+++ trunk/milena/tests/value_rgb8.cc (revision 1098)
@@ -38,9 +38,30 @@
{
using namespace mln;
using value::rgb8;
+ using value::rgb;
{
- rgb8 c;
- // todo matthieu
+ rgb8 v;
+ v.red() = 0;
+ v.green() = 1;
+ v.blue() = 2;
+ value::int_u8_x3_t t = {0,1,2};
+ rgb8 w( t );
+
+ std::cout << w << std::endl;
+ std::cout << v << std::endl;
+
+ mln_assertion(w == w);
+ mln_assertion(w == v);
+ v.green () = 255;
+ std::cout << v << std::endl;
+ mln_assertion(v != w);
+
+ rgb<20> b = rgb<20>::max_blue;
+ std::cout << b << std::endl;
+
+ rgb<20> c = rgb<20>::white;
+ std::cout << c << std::endl;
+
}
}
Index: trunk/milena/mln/debug/println.hh
===================================================================
--- trunk/milena/mln/debug/println.hh (revision 1097)
+++ trunk/milena/mln/debug/println.hh (revision 1098)
@@ -67,15 +67,6 @@
std::cout << std::endl;
}
- template <typename S, typename I>
- void println_with_border(const S&, const Fast_Image<I>& input_)
- {
- const I& input = exact(input_);
- for (int i = 0; i < input.ncells(); i++)
- std::cout << format( input.buffer()[i] ) << ' ';
- std::cout << std::endl;
- }
-
// 2D version
template <typename I>
void println(const box2d& b, const I& input)
@@ -97,38 +88,17 @@
std::cout << std::endl;
}
- template <typename I>
- void println_with_border(const box2d& b, const Fast_Image<I>& input_)
- {
- const I& input = exact(input_);
- const std::size_t ncols = b.ncols() + 2 * input.border();
- for (size_t i = 0; i < input.ncells(); i++)
- {
- std::cout << format( input.buffer()[i] ) << ' ';
- if (((i+1) % ncols) == 0)
- std::cout << std::endl;
- }
- std::cout << std::endl;
- }
-
} // end of namespace mln::debug::impl
// facade
-
template <typename I>
void println(const Image<I>& input)
{
impl::println(exact(input).bbox(), exact(input));
}
- template <typename I>
- void println_with_border(const Fast_Image<I>& input)
- {
- impl::println_with_border(exact(input).bbox(), exact(input));
- }
-
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::debug
Index: trunk/milena/mln/debug/println_with_border.hh
===================================================================
--- trunk/milena/mln/debug/println_with_border.hh (revision 0)
+++ trunk/milena/mln/debug/println_with_border.hh (revision 1098)
@@ -0,0 +1,102 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_DEBUG_PRINTLN_WITH_BORDER_HH
+# define MLN_DEBUG_PRINTLN_WITH_BORDER_HH
+
+/*! \file mln/debug/println_with_border.hh
+ *
+ * \brief Print an image on the standard output.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/window.hh>
+# include <mln/debug/format.hh>
+
+# include <mln/core/box2d.hh>
+
+
+namespace mln
+{
+
+ namespace debug
+ {
+
+ /// Print the image \p input on the standard output.
+ template <typename I>
+ void println_with_border(const Fast_Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ // generic version
+ template <typename S, typename I>
+ void println_with_border(const S&, const Fast_Image<I>& input_)
+ {
+ const I& input = exact(input_);
+ for (size_t i = 0; i < input.ncells(); i++)
+ std::cout << format( input.buffer()[i] ) << ' ';
+ std::cout << std::endl;
+ }
+
+ // 2D version
+ template <typename I>
+ void println_with_border(const box2d& b, const Fast_Image<I>& input_)
+ {
+ const I& input = exact(input_);
+ const std::size_t ncols = b.ncols() + 2 * input.border();
+ for (size_t i = 0; i < input.ncells(); i++)
+ {
+ std::cout << format( input.buffer()[i] ) << ' ';
+ if (((i+1) % ncols) == 0)
+ std::cout << std::endl;
+ }
+ std::cout << std::endl;
+ }
+
+ } // end of namespace mln::debug::impl
+
+
+
+ // facade
+ template <typename I>
+ void println_with_border(const Fast_Image<I>& input)
+ {
+ impl::println_with_border(exact(input).bbox(), exact(input));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::debug
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DEBUG_PRINTLN_WITH_BORDER_HH
Index: trunk/milena/mln/value/rgb8.hh
===================================================================
--- trunk/milena/mln/value/rgb8.hh (revision 1097)
+++ trunk/milena/mln/value/rgb8.hh (revision 1098)
@@ -34,8 +34,7 @@
* 8-bit encoded.
*/
-# include <mln/core/concept/value.hh>
-# include <mln/value/int_u8.hh>
+# include <mln/value/rgb.hh>
namespace mln
@@ -44,68 +43,10 @@
namespace value
{
-
- typedef int_u8 int_u8_x3_t[3];
- typedef unsigned char uchar_x3_t[3];
- typedef float float_x3_t[3];
-
-
/*! \brief Color class for red-green-blue where every component is
* 8-bit encoded.
*/
- class rgb8 : public Value< rgb8 >
- {
- public:
-
- /// Encoding associated type.
- typedef int_u8_x3_t enc;
-
- /// Equivalent associated type.
- typedef int_u8_x3_t equiv;
-
- int_u8 red() const { return c_[0]; }
- int_u8& red() { return c_[0]; }
-
- int_u8 green() const { return c_[1]; }
- int_u8& green() { return c_[1]; }
-
- int_u8 blue() const { return c_[2]; }
- int_u8& blue() { return c_[2]; }
-
- // todo matthieu
-
- private:
- int_u8_x3_t c_;
- };
-
-
- struct props< rgb8 >
- {
- static const unsigned nbits = 24;
- static const std::size_t card_ = metal::pow<2, nbits>::value;
- typedef color_kind kind;
- typedef float_x3_t sum;
- typedef uchar_x3_t interop;
- };
-
-
-
- /*! \brief Print an rgb8 \p c into the output stream \p ostr.
- *
- * \param[in,out] ostr An output stream.
- * \param[in] c An rgb8.
- *
- * \return The modified output stream \p ostr.
- */
- std::ostream& operator<<(std::ostream& ostr, const rgb8& c);
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- // todo matthieu
-
-# endif // ! MLN_INCLUDE_ONLY
-
+ typedef rgb<8> rgb8;
} // end of namespace mln::value
} // end of namespace mln
Index: trunk/milena/mln/value/rgb.hh
===================================================================
--- trunk/milena/mln/value/rgb.hh (revision 0)
+++ trunk/milena/mln/value/rgb.hh (revision 1098)
@@ -0,0 +1,224 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_VALUE_RGB_HH
+# define MLN_VALUE_RGB_HH
+
+/*! \file mln/value/rgb8.hh
+ *
+ * \brief Color class for red-green-blue where every component is
+ * 8-bit encoded.
+ */
+
+# include <mln/core/concept/value.hh>
+# include <mln/value/int_u8.hh>
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+
+ typedef int_u8 int_u8_x3_t[3];
+ typedef unsigned char uchar_x3_t[3];
+ typedef float float_x3_t[3];
+
+
+ /*! \brief Color class for red-green-blue where every component is
+ * 8-bit encoded.
+ */
+ template <unsigned n>
+ struct rgb : public Value< rgb<n> >
+ {
+ public:
+
+ /// Encoding associated type.
+ typedef int_u<n> enc;
+
+ /// Equivalent associated type.
+ typedef int_u<n> equiv[3];
+
+ int_u<n> red() const { return c_[0]; }
+ int_u<n>& red() { return c_[0]; }
+
+ int_u<n> green() const { return c_[1]; }
+ int_u<n>& green() { return c_[1]; }
+
+ int_u<n> blue() const { return c_[2]; }
+ int_u<n>& blue() { return c_[2]; }
+
+ rgb<n>();
+ rgb<n>(equiv a);
+ rgb<n>(enc r, enc g, enc b);
+
+ rgb<n>& operator=(rgb<n>& v);
+
+ /// Zero value.
+ static const rgb<n> zero;
+
+ /// Colors.
+ static const rgb<n> black;
+ static const rgb<n> max_red;
+ static const rgb<n> max_green;
+ static const rgb<n> max_blue;
+ static const rgb<n> white;
+
+ /// Self addition
+ rgb<n>& operator+=(rgb<n>& v);
+
+ /// Self subtraction.
+ rgb<n>& operator-=(rgb<n>& v);
+
+ /// Comparaison.
+ bool operator==(rgb<n>& v);
+ bool operator!=(rgb<n>& v);
+
+
+ private:
+ equiv c_;
+ };
+
+ template <unsigned n>
+ struct props< rgb<n> >
+ {
+ static const unsigned nbits = 24;
+ static const std::size_t card_ = metal::pow<2, nbits>::value;
+ typedef color_kind kind;
+ typedef float_x3_t sum;
+ typedef uchar_x3_t interop;
+ };
+
+
+
+ /*! \brief Print an rgb \p c into the output stream \p ostr.
+ *
+ * \param[in,out] ostr An output stream.
+ * \param[in] c An rgb.
+ *
+ * \return The modified output stream \p ostr.
+ */
+ template <unsigned n>
+ std::ostream& operator<<(std::ostream& ostr, const rgb<n>& c);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned n>
+ rgb<n>::rgb()
+ {
+ }
+
+ template <unsigned n>
+ rgb<n>::rgb(equiv a)
+ {
+ std::memcpy(this->c_, a, 3);
+ }
+
+ template <unsigned n>
+ rgb<n>::rgb(enc r, enc g, enc b)
+ {
+ this->c_[0] = r;
+ this->c_[1] = g;
+ this->c_[2] = b;
+ }
+
+ template <unsigned n>
+ rgb<n>&
+ rgb<n>::operator=(rgb<n>& v)
+ {
+ std::memcpy(this->c_, v.c_, 3);
+ return *this;
+ }
+
+ template <unsigned n>
+ const rgb<n> rgb<n>::zero(0,0,0);
+
+ template <unsigned n>
+ const rgb<n> rgb<n>::black(0,0,0);
+
+ template <unsigned n>
+ const rgb<n> rgb<n>::max_red(mln_max(enc), 0, 0);
+
+ template <unsigned n>
+ const rgb<n> rgb<n>::max_green(0, mln_max(enc), 0);
+
+ template <unsigned n>
+ const rgb<n> rgb<n>::max_blue(0, 0, mln_max(enc));
+
+ template <unsigned n>
+ const rgb<n> rgb<n>::white(mln_max(enc), mln_max(enc), mln_max(enc));
+
+ template <unsigned n>
+ rgb<n>&
+ rgb<n>::operator+=(rgb<n>& v)
+ {
+ for (int i = 0; i < 3; i++)
+ this->c_[i] += v.c_[i];
+ }
+
+ template <unsigned n>
+ rgb<n>&
+ rgb<n>::operator-=(rgb<n>& v)
+ {
+ for (int i = 0; i < 3; i++)
+ this->c_[i] += v.c_[i];
+ }
+
+ template <unsigned n>
+ std::ostream& operator<<(std::ostream& ostr, const rgb<n>& v)
+ {
+ return ostr << "(R:" << debug::format(v.red())
+ << ", G:" << debug::format(v.green())
+ << ", B:" << debug::format(v.blue())
+ << ")";
+ }
+
+ template <unsigned n>
+ bool
+ rgb<n>::operator==(rgb<n>& v)
+ {
+ return (this->green() == v.green() &&
+ this->red() == v.red() &&
+ this->blue() == v.blue());
+ }
+
+ template <unsigned n>
+ bool
+ rgb<n>::operator!=(rgb<n>& v)
+ {
+ return (!(*this == v));
+ }
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_RGB_HH
Index: trunk/milena/mln/value/rgb8_non_templated.hh
===================================================================
--- trunk/milena/mln/value/rgb8_non_templated.hh (revision 0)
+++ trunk/milena/mln/value/rgb8_non_templated.hh (revision 1098)
@@ -0,0 +1,191 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_VALUE_RGB8_HH
+# define MLN_VALUE_RGB8_HH
+
+/*! \file mln/value/rgb8.hh
+ *
+ * \brief Color class for red-green-blue where every component is
+ * 8-bit encoded.
+ */
+
+# include <mln/core/concept/value.hh>
+# include <mln/value/int_u8.hh>
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+
+ typedef int_u8 int_u8_x3_t[3];
+ typedef unsigned char uchar_x3_t[3];
+ typedef float float_x3_t[3];
+
+
+ /*! \brief Color class for red-green-blue where every component is
+ * 8-bit encoded.
+ */
+ class rgb8 : public Value< rgb8 >
+ {
+ public:
+
+ /// Encoding associated type.
+ typedef int_u8 enc;
+
+ /// Equivalent associated type.
+ typedef int_u8_x3_t equiv;
+
+ int_u8 red() const { return c_[0]; }
+ int_u8& red() { return c_[0]; }
+
+ int_u8 green() const { return c_[1]; }
+ int_u8& green() { return c_[1]; }
+
+ int_u8 blue() const { return c_[2]; }
+ int_u8& blue() { return c_[2]; }
+
+ // todo matthieu
+ rgb8();
+ rgb8(int_u8_x3_t a);
+
+ rgb8& operator=(rgb8& v);
+
+ /// Zero value.
+ static const rgb8 zero;
+
+ /// Unit values.
+ static const rgb8 max_red;
+ static const rgb8 max_green;
+ static const rgb8 max_blue;
+
+ /// Self addition
+ rgb8& operator+=(rgb8& v);
+
+ /// Self subtraction.
+ rgb8& operator-=(rgb8& v);
+
+ /// Comparaison.
+ bool operator==(rgb8& v);
+ bool operator!=(rgb8& v);
+
+
+ private:
+ int_u8_x3_t c_;
+ };
+
+ template <>
+ struct props< rgb8 >
+ {
+ static const unsigned nbits = 24;
+ static const std::size_t card_ = metal::pow<2, nbits>::value;
+ typedef color_kind kind;
+ typedef float_x3_t sum;
+ typedef uchar_x3_t interop;
+ };
+
+
+
+ /*! \brief Print an rgb8 \p c into the output stream \p ostr.
+ *
+ * \param[in,out] ostr An output stream.
+ * \param[in] c An rgb8.
+ *
+ * \return The modified output stream \p ostr.
+ */
+ std::ostream& operator<<(std::ostream& ostr, const rgb8& c);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // todo matthieu
+ rgb8::rgb8()
+ {
+ }
+
+ rgb8::rgb8(int_u8_x3_t a)
+ {
+ std::memcpy(this->c_, a, 3);
+ }
+
+ rgb8&
+ rgb8::operator=(rgb8& v)
+ {
+ std::memcpy(this->c_, v.c_, 3);
+ return *this;
+ }
+
+// const rgb8 rgb8::zero = rgb8({0,0,0});
+// const rgb8 rgb8::max_red = {mln_max(enc), 0, 0};
+// const rgb8 rgb8::max_green = {0, mln_max(enc), 0};
+// const rgb8 rgb8::max_blue = {0, 0, mln_max(enc)};
+
+ rgb8&
+ rgb8::operator+=(rgb8& v)
+ {
+ for (int i = 0; i < 3; i++)
+ this->c_[i] += v.c_[i];
+ }
+ rgb8&
+ rgb8::operator-=(rgb8& v)
+ {
+ for (int i = 0; i < 3; i++)
+ this->c_[i] += v.c_[i];
+ }
+
+ std::ostream& operator<<(std::ostream& ostr, const rgb8& v)
+ {
+ return ostr << "(R:" << debug::format(v.red())
+ << ", G:" << debug::format(v.green())
+ << ", B:" << debug::format(v.blue())
+ << ")";
+ }
+
+ bool
+ rgb8::operator==(rgb8& v)
+ {
+ return (this->green() == v.green() &&
+ this->red() == v.red() &&
+ this->blue() == v.blue());
+ }
+
+ bool
+ rgb8::operator!=(rgb8& v)
+ {
+ return (!(*this == v));
+ }
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_RGB8_HH
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-10 Simon Nivault <simon.nivault(a)lrde.epita.fr>
FIXME notation for Guillaume
* mln/convert/to_window.hh: .
---
to_window.hh | 2 ++
1 file changed, 2 insertions(+)
Index: trunk/milena/mln/convert/to_window.hh
===================================================================
--- trunk/milena/mln/convert/to_window.hh (revision 1096)
+++ trunk/milena/mln/convert/to_window.hh (revision 1097)
@@ -77,6 +77,8 @@
window<D> win;
mln_niter(N) n(nbh, P::zero);
for_all(n)
+// FIXME: pour Guillaume
+// if (n < P::zero)
win.insert(n - P::zero);
return win;
}
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-10 Simon Nivault <simon.nivault(a)lrde.epita.fr>
Add iterator on line
* mln/core/image1d_b.hh,
* mln/core/image2d_b.hh: Type line_piter added.
* mln/core/line_piter.hh: The Iterator.
* mln/core/macros.hh: New macro mln_line_piter.
* tests/line_piter.cc: New.
---
mln/core/image1d_b.hh | 2
mln/core/image2d_b.hh | 2
mln/core/line_piter.hh | 185 +++++++++++++++++++++++++++++++++++++++++++++++++
mln/core/macros.hh | 3
tests/line_piter.cc | 52 +++++++++++++
5 files changed, 244 insertions(+)
Index: trunk/milena/tests/line_piter.cc
===================================================================
--- trunk/milena/tests/line_piter.cc (revision 0)
+++ trunk/milena/tests/line_piter.cc (revision 1096)
@@ -0,0 +1,52 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/*! \file tests/image2d_b.cc
+ *
+ * \brief Tests on mln::image2d_b.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/line_piter.hh>
+
+int main()
+{
+ using namespace mln;
+
+ const unsigned nrows = 6;
+ const unsigned ncols = 4;
+ const unsigned border = 2;
+
+ image2d_b<int> f(nrows, ncols, border);
+
+ image2d_b<int>::line_piter p(f.domain());
+
+ for_all(p)
+ {
+ std::cout << p <<std::endl;
+ }
+}
Index: trunk/milena/mln/core/macros.hh
===================================================================
--- trunk/milena/mln/core/macros.hh (revision 1095)
+++ trunk/milena/mln/core/macros.hh (revision 1096)
@@ -110,6 +110,9 @@
# define mln_piter(T) typename T::fwd_piter
# define mln_piter_(T) T::fwd_piter
+/// Shortcut to access the type of point by line iterator (line_piter) associated to T.
+# define mln_line_piter(T) typename T::line_piter
+
/// Shortcut to access the type of point set (pset) associated to T.
# define mln_pset(T) typename T::pset
Index: trunk/milena/mln/core/line_piter.hh
===================================================================
--- trunk/milena/mln/core/line_piter.hh (revision 0)
+++ trunk/milena/mln/core/line_piter.hh (revision 1096)
@@ -0,0 +1,185 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_CORE_LINE_PITER_HH
+# define MLN_CORE_LINE_PITER_HH
+
+/*! \file mln/core/line_piter.hh
+ *
+ * \brief Definition of iterators on points by lines.
+ */
+
+# include <mln/core/concept/point_iterator.hh>
+
+
+namespace mln
+{
+
+ /*! \brief A generic forward iterator on points by lines.
+ *
+ * The parameter \c P is the type of points.
+ */
+ template <typename P>
+ class line_piter_ : public Point_Iterator< line_piter_<P> >
+ {
+ public:
+
+ /// Space dimension.
+ enum { dim = P::dim };
+
+ /// Point_Site associated type.
+ typedef P psite;
+
+ /// Point associated type.
+ typedef P point;
+
+ /// Dpoint associated type.
+ typedef mln_dpoint(P) dpoint;
+
+ /// Coordinate associated type.
+ typedef mln_coord(P) coord;
+
+ /*! \brief Constructor.
+ *
+ * \param[in] b A box.
+ */
+ line_piter_(const box_<P>& b);
+
+ /// Convertion to point.
+ operator P() const;
+
+ /// Address of the point.
+ const P* pointer_() const;
+
+ /// Give the i-th coordinate.
+ coord operator[](unsigned i) const;
+
+ /// Test the iterator validity.
+ bool is_valid() const;
+
+ /// Invalidate the iterator.
+ void invalidate();
+
+ /// Start an iteration.
+ void start();
+
+ /// Go to the next point.
+ void next_();
+
+ private:
+ const box_<P>& b_;
+ P p_, nop_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // line_piter_<P>
+
+ template <typename P>
+ line_piter_<P>::line_piter_(const box_<P>& b)
+ : b_(b)
+ {
+ nop_ = b_.pmax();
+ if (dim == 1)
+ ++nop_[0];
+ else
+ {
+ nop_[0] = 0;
+ ++nop_[1];
+ }
+ invalidate();
+ }
+
+ template <typename P>
+ line_piter_<P>::operator P() const
+ {
+ return p_;
+ }
+
+ template <typename P>
+ const P*
+ line_piter_<P>::pointer_() const
+ {
+ return & p_;
+ }
+
+ template <typename P>
+ mln_coord(P)
+ line_piter_<P>::operator[](unsigned i) const
+ {
+ mln_invariant(p_[0] == 0);
+ assert(i < dim);
+ return p_[i];
+ }
+
+ template <typename P>
+ bool
+ line_piter_<P>::is_valid() const
+ {
+ return p_ != nop_;
+ }
+
+ template <typename P>
+ void
+ line_piter_<P>::invalidate()
+ {
+ p_ = nop_;
+ }
+
+ template <typename P>
+ void
+ line_piter_<P>::start()
+ {
+ p_ = b_.pmin();
+ }
+
+ template <typename P>
+ void
+ line_piter_<P>::next_()
+ {
+ for (int c = 1; c < dim; ++c)
+ {
+ if (p_[c] != b_.pmax()[c])
+ {
+ ++p_[c];
+ break;
+ }
+ p_[c] = b_.pmin()[c];
+ }
+ if (p_ == b_.pmin())
+ p_ = nop_;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_LINE_PITER_HH
Index: trunk/milena/mln/core/image1d_b.hh
===================================================================
--- trunk/milena/mln/core/image1d_b.hh (revision 1095)
+++ trunk/milena/mln/core/image1d_b.hh (revision 1096)
@@ -40,6 +40,7 @@
# include <mln/value/set.hh>
# include <mln/fun/i2v/all.hh>
+# include <mln/core/line_piter.hh>
// FIXME:
@@ -83,6 +84,7 @@
typedef dpoint1d dpoint;
typedef mln_fwd_piter(box1d) fwd_piter;
typedef mln_bkd_piter(box1d) bkd_piter;
+ typedef line_piter_<point> line_piter;
// End of warning.
Index: trunk/milena/mln/core/image2d_b.hh
===================================================================
--- trunk/milena/mln/core/image2d_b.hh (revision 1095)
+++ trunk/milena/mln/core/image2d_b.hh (revision 1096)
@@ -40,6 +40,7 @@
# include <mln/value/set.hh>
# include <mln/fun/i2v/all.hh>
+# include <mln/core/line_piter.hh>
// FIXME:
@@ -83,6 +84,7 @@
typedef dpoint2d dpoint;
typedef mln_fwd_piter(box2d) fwd_piter;
typedef mln_bkd_piter(box2d) bkd_piter;
+ typedef line_piter_<point> line_piter;
// End of warning.
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add fast histogram-based erosion and color skeleton.
* tests/morpho_erosion_min_h.cc: New.
* tests/value_rgb8.cc: New.
* mln/level/ero.hh: New; temporary, rename it!
* mln/accu/min_h.hh: New.
* mln/core/vec_p.hh (dpoint): New.
* mln/core/window.hh (operator<<): New.
* mln/value/rgb8.hh: New.
* tests/morpho_erosion.cc: Update.
* mln/convert/to_window.hh: Fix sig.
* mln/morpho/dilation.hh: Add todo.
* mln/morpho/erosion.hh: Add todo.
* mln/level/approx/median.hh: Add todo.
* mln/value/props.hh: Fix missing include.
mln/accu/min_h.hh | 243 ++++++++++++++++++++++++++++++++++++++++++
mln/convert/to_window.hh | 4
mln/core/vec_p.hh | 3
mln/core/window.hh | 10 +
mln/level/approx/median.hh | 7 +
mln/level/ero.hh | 188 ++++++++++++++++++++++++++++++++
mln/morpho/dilation.hh | 5
mln/morpho/erosion.hh | 11 +
mln/value/props.hh | 1
mln/value/rgb8.hh | 114 +++++++++++++++++++
tests/morpho_erosion.cc | 35 ++++--
tests/morpho_erosion_min_h.cc | 65 +++++++++++
tests/value_rgb8.cc | 46 +++++++
13 files changed, 719 insertions(+), 13 deletions(-)
Index: tests/morpho_erosion.cc
--- tests/morpho_erosion.cc (revision 1094)
+++ tests/morpho_erosion.cc (working copy)
@@ -32,6 +32,7 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
+#include <mln/core/window2d.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
@@ -44,6 +45,8 @@
#include <mln/pw/cst.hh>
#include <mln/fun/ops.hh>
+#include <mln/convert/to_vec_p.hh>
+#include <mln/convert/to_window.hh>
int main()
@@ -62,16 +65,26 @@
io::pgm::save(out, "out.pgm");
}
- {
- image2d_b<bool> bin(lena.domain()), out(lena.domain());
- level::fill(bin, pw::value(lena) > pw::cst(127));
- morpho::erosion(bin, rec, out);
-
- image2d_b<int_u8> test(lena.domain());
- image2d_b<int_u8>::fwd_piter p(lena.domain());
- for_all(p)
- test(p) = out(p) ? 255 : 0;
- io::pgm::save(test, "test.pgm");
- }
+// {
+// vec_p<point2d> vec = convert::to_vec_p(rec, point2d::zero);
+// window2d win = convert::to_window(vec);
+
+// image2d_b<int_u8> out(lena.domain());
+// level::ero(lena, win, out);
+// morpho::erosion(lena, win, out);
+// io::pgm::save(out, "out.pgm");
+// }
+
+// {
+// image2d_b<bool> bin(lena.domain()), out(lena.domain());
+// level::fill(bin, pw::value(lena) > pw::cst(127));
+// morpho::erosion(bin, rec, out);
+
+// image2d_b<int_u8> test(lena.domain());
+// image2d_b<int_u8>::fwd_piter p(lena.domain());
+// for_all(p)
+// test(p) = out(p) ? 255 : 0;
+// io::pgm::save(test, "test.pgm");
+// }
}
Index: tests/morpho_erosion_min_h.cc
--- tests/morpho_erosion_min_h.cc (revision 0)
+++ tests/morpho_erosion_min_h.cc (revision 0)
@@ -0,0 +1,65 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/*! \file tests/morpho_erosion.cc
+ *
+ * \brief Test on mln::morpho::erosion.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/win/rectangle2d.hh>
+#include <mln/core/window2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/level/ero.hh>
+
+#include <mln/convert/to_vec_p.hh>
+#include <mln/convert/to_window.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ win::rectangle2d rec(21, 21);
+ border::thickness = 66;
+
+ image2d_b<int_u8> lena = io::pgm::load("../img/lena.pgm");
+
+ {
+ vec_p<point2d> vec = convert::to_vec_p(rec, point2d::zero);
+ window2d win = convert::to_window(vec);
+
+ image2d_b<int_u8> out(lena.domain());
+ level::ero(lena, win, out);
+ io::pgm::save(out, "out.pgm");
+ }
+}
Index: tests/value_rgb8.cc
--- tests/value_rgb8.cc (revision 0)
+++ tests/value_rgb8.cc (revision 0)
@@ -0,0 +1,46 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/*! \file tests/value_rgb8.cc
+ *
+ * \brief Tests on mln::value::rgb8.
+ */
+
+#include <mln/value/rgb8.hh>
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::rgb8;
+
+ {
+ rgb8 c;
+ // todo matthieu
+ }
+}
Index: mln/convert/to_window.hh
--- mln/convert/to_window.hh (revision 1094)
+++ mln/convert/to_window.hh (working copy)
@@ -58,7 +58,7 @@
window<mln_dpoint(I)> to_window(const Image<I>& ima);
/// Convert a point set \p pset into a window.
- template <typename S, typename F>
+ template <typename S>
window<mln_dpoint(S)> to_window(const Point_Set<S>& pset);
/// Convert an std::set \p s of delta-points into a window.
@@ -97,7 +97,7 @@
return win;
}
- template <typename S, typename F>
+ template <typename S>
window<mln_dpoint(S)> to_window(const Point_Set<S>& pset)
{
return to_window(pw::cst(true) | pset);
Index: mln/core/window.hh
--- mln/core/window.hh (revision 1094)
+++ mln/core/window.hh (working copy)
@@ -97,6 +97,16 @@
};
+ // FIXME: Move code at EOF + doc.
+ template <typename D>
+ std::ostream& operator<<(std::ostream& ostr, const window<D>& win)
+ {
+ // FIXME
+ for (unsigned i = 0; i < win.ndpoints(); ++i)
+ ostr << win.dp(i);
+ return ostr;
+ }
+
# ifndef MLN_INCLUDE_ONLY
Index: mln/core/vec_p.hh
--- mln/core/vec_p.hh (revision 1094)
+++ mln/core/vec_p.hh (working copy)
@@ -64,6 +64,9 @@
/// Point associated type.
typedef P point;
+ /// Dpoint associated type.
+ typedef mln_dpoint(P) dpoint;
+
/// Point_Site associated type.
typedef P psite;
Index: mln/morpho/dilation.hh
--- mln/morpho/dilation.hh (revision 1094)
+++ mln/morpho/dilation.hh (working copy)
@@ -38,6 +38,11 @@
# include <mln/morpho/includes.hh>
+
+// todo simon
+// this file should be like erosion
+
+
namespace mln
{
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh (revision 1094)
+++ mln/morpho/erosion.hh (working copy)
@@ -148,6 +148,17 @@
# endif // MLN_CORE_WIN_RECTANGLE2D_HH
+
+// ifdef MLN_CORE_WIN_RECTANGLE2D_HH
+
+// template <typename I, typename O>
+// void erosion_wrt_win(const Image<I>& input, const win::octagon2d& win, Image<O>& output)
+// {
+// todo simon
+// }
+
+// endif MLN_CORE_WIN_RECTANGLE2D_HH
+
// ^
// |
// end of stage1 (dispatch w.r.t. the window type)
Index: mln/level/ero.hh
--- mln/level/ero.hh (revision 0)
+++ mln/level/ero.hh (revision 0)
@@ -0,0 +1,188 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_LEVEL_ERO_HH
+# define MLN_LEVEL_ERO_HH
+
+/*! \file mln/level/ero.hh
+ *
+ * \brief Ero filtering of an image.
+ *
+ * \todo Add Fast_Image versions.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/window.hh>
+# include <mln/geom/shift.hh>
+# include <mln/set/diff.hh>
+
+# include <mln/canvas/browsing/snake_fwd.hh>
+# include <mln/accu/min_h.hh>
+
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ /*! Compute in \p output the ero filter of image \p input by
+ * the window \p win.
+ *
+ * \param[in] input The image to be filtered.
+ * \param[in] win The window.
+ * \param[out] output The output image.
+ *
+ * \pre \p input and \p output have to be initialized.
+ */
+ template <typename I, typename W, typename O>
+ void ero(const Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+
+ // Functors.
+
+
+ template <typename I, typename W, typename O>
+ struct ero_t
+ {
+ typedef mln_point(I) P;
+ typedef mln_dpoint(I) D;
+
+ // i/o
+
+ const I& input;
+ const W& win;
+ O& output;
+
+ // aux data
+
+ accu::min_h<mln_vset(I)> min;
+ P p;
+ window<D> win_fp, win_fm, win_bp, win_bm, win_dp, win_dm;
+ mln_qiter(W) q_fp, q_fm, q_bp, q_bm, q_dp, q_dm;
+
+ // ctor
+
+ ero_t(const I& input_, const W& win_, O& output_)
+ :
+ // i/o
+ input(exact(input_)),
+ win(exact(win_)),
+ output(exact(output_)),
+ // aux data
+ min(input.values()),
+ p(),
+ win_fp(set::diff(win, geom::shift(win, left))),
+ win_fm(set::diff(geom::shift(win, left), win)),
+ win_bp(set::diff(win, geom::shift(win, right))),
+ win_bm(set::diff(geom::shift(win, right), win)),
+ win_dp(set::diff(win, geom::shift(win, up))),
+ win_dm(set::diff(geom::shift(win, up), win)),
+ q_fp(win_fp, p), q_fm(win_fm, p),
+ q_bp(win_bp, p), q_bm(win_bm, p),
+ q_dp(win_dp, p), q_dm(win_dm, p)
+ {
+ }
+
+ // parts
+
+ void init()
+ {
+ min.init();
+ mln_qiter(W) q(win, p);
+ for_all(q) if (input.has(q))
+ min.take(input(q));
+ }
+
+ void down()
+ {
+ for_all(q_dm) if (input.has(q_dm))
+ min.untake(input(q_dm));
+ for_all(q_dp) if (input.has(q_dp))
+ min.take(input(q_dp));
+ output(p) = min.to_value();
+ }
+
+ void fwd()
+ {
+ for_all(q_fm) if (input.has(q_fm))
+ min.untake(input(q_fm));
+ for_all(q_fp) if (input.has(q_fp))
+ min.take(input(q_fp));
+ output(p) = min.to_value();
+ }
+
+ void bkd()
+ {
+ for_all(q_bm) if (input.has(q_bm))
+ min.untake(input(q_bm));
+ for_all(q_bp) if (input.has(q_bp))
+ min.take(input(q_bp));
+ output(p) = min.to_value();
+ }
+
+ }; // end of ero_t
+
+
+ template <typename I, typename W, typename O>
+ void ero_(const Image<I>& input, const Window<W>& win, O& output)
+ {
+ // FIXME: resize border!
+ ero_t<I,W,O> f(exact(input), exact(win), output);
+ canvas::browsing::snake_fwd(f);
+ }
+
+ } // end of namespace mln::level::impl
+
+
+ // Facades.
+
+ template <typename I, typename W, typename O>
+ void ero(const Image<I>& input, const Window<W>& win,
+ Image<O>& output)
+ {
+ mln_assertion(exact(output).domain() = exact(input).domain());
+ impl::ero_(exact(input), exact(win), exact(output));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_ERO_HH
Index: mln/level/approx/median.hh
--- mln/level/approx/median.hh (revision 1094)
+++ mln/level/approx/median.hh (working copy)
@@ -78,6 +78,13 @@
level::median(tmp, win::vline2d(win.height()), output);
}
+// template <typename I, typename O>
+// void median(const Image<I>& input_, const win::disk2d& win,
+// Image<O>& output_)
+// {
+// // todo simon
+// }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::level::approx
Index: mln/accu/min_h.hh
--- mln/accu/min_h.hh (revision 0)
+++ mln/accu/min_h.hh (revision 0)
@@ -0,0 +1,243 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_ACCU_MIN_H_HH
+# define MLN_ACCU_MIN_H_HH
+
+/*! \file mln/accu/min_h.hh
+ *
+ * \brief Define a generic min accumulator class based on histogram.
+ */
+
+# include <mln/core/concept/accumulator.hh>
+# include <mln/accu/histo.hh>
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+
+ /*! Generic min function based on histogram over a value set with
+ * type \c S.
+ */
+ template <typename S>
+ struct min_h : public Accumulator< min_h<S> >
+ {
+ typedef mln_value(S) value;
+
+ min_h(const Value_Set<S>& s);
+ min_h();
+
+ void init();
+ void take(const value& v);
+ void take_as_init(const value& v);
+ void take(const min_h<S>& other);
+ void untake(const value& v);
+
+ unsigned card() const { return h_.sum(); }
+
+ value to_value() const;
+
+ const accu::histo<S>& histo() const;
+
+ protected:
+
+ mutable accu::histo<S> h_;
+ const S& s_; // derived from h_
+
+ mutable std::size_t sum_;
+ mutable bool valid_;
+ mutable std::size_t i_; // the min index
+ mutable value v_; // the min value
+
+ // Auxiliary methods
+ void update_() const;
+ void go_minus_() const;
+ void go_plus_() const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename S>
+ min_h<S>::min_h(const Value_Set<S>& s)
+ : h_(s),
+ s_(h_.vset())
+ {
+ init();
+ }
+
+ template <typename S>
+ min_h<S>::min_h()
+ : h_(),
+ s_(h_.vset())
+ {
+ init();
+ }
+
+ template <typename S>
+ void
+ min_h<S>::take(const value& v)
+ {
+ h_.take(v);
+ if (h_.sum() = 1)
+ {
+ this->take_as_init(v);
+ return;
+ }
+ if (v < v_)
+ {
+ ++sum_;
+ valid_ = false;
+ }
+ }
+
+ template <typename S>
+ void
+ min_h<S>::take(const min_h<S>& other)
+ {
+ // h_
+ h_.take(other.h_);
+ for (unsigned i = 0; i < i_; ++i)
+ sum_ += other.h_[i];
+ valid_ = false;
+ // FIXME: Optimize.
+ }
+
+ template <typename S>
+ void
+ min_h<S>::untake(const value& v)
+ {
+ mln_precondition(h_(v) != 0);
+ h_.untake(v);
+ if (h_.sum() = 0)
+ {
+ init();
+ return;
+ }
+ if (v < v_)
+ {
+ mln_invariant(sum_ >= 1);
+ --sum_;
+ valid_ = false;
+ }
+ else
+ if (v = v_ && h_[i_] = 0)
+ valid_ = false;
+ }
+
+ template <typename S>
+ void
+ min_h<S>::update_() const
+ {
+ if (sum_ != 0)
+ go_minus_();
+ else
+ if (h_[i_] = 0)
+ go_plus_();
+ valid_ = true;
+ }
+
+ template <typename S>
+ void
+ min_h<S>::go_minus_() const
+ {
+ do
+ {
+ --i_;
+ if (h_[i_] != 0)
+ sum_ -= h_[i_];
+ }
+ while (sum_ != 0);
+ v_ = s_[i_];
+ }
+
+ template <typename S>
+ void
+ min_h<S>::go_plus_() const
+ {
+ do
+ ++i_;
+ while (h_[i_] = 0);
+ v_ = s_[i_];
+ }
+
+ template <typename S>
+ void
+ min_h<S>::init()
+ {
+ h_.init();
+ sum_ = 0;
+ i_ = mln_max(value);
+ v_ = s_[i_];
+ valid_ = true;
+ }
+
+ template <typename S>
+ void
+ min_h<S>::take_as_init(const value& v)
+ {
+ h_.take(v);
+ sum_ = 0;
+ i_ = s_.index_of(v);
+ v_ = v;
+ valid_ = true;
+ }
+
+ template <typename S>
+ typename min_h<S>::value
+ min_h<S>::to_value() const
+ {
+ if (! valid_)
+ update_();
+ return v_;
+ }
+
+ template <typename S>
+ const accu::histo<S>&
+ min_h<S>::histo() const
+ {
+ return h_;
+ }
+
+ template <typename S>
+ std::ostream& operator<<(std::ostream& ostr, const min_h<S>& m)
+ {
+ return ostr << m.to_value();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_MIN_H_HH
Index: mln/value/rgb8.hh
--- mln/value/rgb8.hh (revision 0)
+++ mln/value/rgb8.hh (revision 0)
@@ -0,0 +1,114 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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 MLN_VALUE_RGB8_HH
+# define MLN_VALUE_RGB8_HH
+
+/*! \file mln/value/rgb8.hh
+ *
+ * \brief Color class for red-green-blue where every component is
+ * 8-bit encoded.
+ */
+
+# include <mln/core/concept/value.hh>
+# include <mln/value/int_u8.hh>
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+
+ typedef int_u8 int_u8_x3_t[3];
+ typedef unsigned char uchar_x3_t[3];
+ typedef float float_x3_t[3];
+
+
+ /*! \brief Color class for red-green-blue where every component is
+ * 8-bit encoded.
+ */
+ class rgb8 : public Value< rgb8 >
+ {
+ public:
+
+ /// Encoding associated type.
+ typedef int_u8_x3_t enc;
+
+ /// Equivalent associated type.
+ typedef int_u8_x3_t equiv;
+
+ int_u8 red() const { return c_[0]; }
+ int_u8& red() { return c_[0]; }
+
+ int_u8 green() const { return c_[1]; }
+ int_u8& green() { return c_[1]; }
+
+ int_u8 blue() const { return c_[2]; }
+ int_u8& blue() { return c_[2]; }
+
+ // todo matthieu
+
+ private:
+ int_u8_x3_t c_;
+ };
+
+
+ struct props< rgb8 >
+ {
+ static const unsigned nbits = 24;
+ static const std::size_t card_ = metal::pow<2, nbits>::value;
+ typedef color_kind kind;
+ typedef float_x3_t sum;
+ typedef uchar_x3_t interop;
+ };
+
+
+
+ /*! \brief Print an rgb8 \p c into the output stream \p ostr.
+ *
+ * \param[in,out] ostr An output stream.
+ * \param[in] c An rgb8.
+ *
+ * \return The modified output stream \p ostr.
+ */
+ std::ostream& operator<<(std::ostream& ostr, const rgb8& c);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // todo matthieu
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_RGB8_HH
Index: mln/value/props.hh
--- mln/value/props.hh (revision 1094)
+++ mln/value/props.hh (working copy)
@@ -34,6 +34,7 @@
* FIXME : add interop typedef in each props
*/
+# include <cstddef>
# include <climits>
# include <cfloat>
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-10 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
bug fix in image1d_b
* mln/core/image1d_b.hh: re-add array_ attribute in the image1d_b class
we actually need it to handle the border offset
=> array_ = buffer_ - vb_.pmin().ind();
)
* mln/debug/println.hh: update
* tests/debug_println_with_border.cc: add 1d test.
---
mln/core/image1d_b.hh | 21 +++++++++++++--------
mln/debug/println.hh | 5 ++---
tests/debug_println_with_border.cc | 30 +++++++++++++++++++++++++++++-
3 files changed, 44 insertions(+), 12 deletions(-)
Index: trunk/milena/tests/debug_println_with_border.cc
===================================================================
--- trunk/milena/tests/debug_println_with_border.cc (revision 1093)
+++ trunk/milena/tests/debug_println_with_border.cc (revision 1094)
@@ -31,6 +31,7 @@
*/
#include <mln/core/image2d_b.hh>
+#include <mln/core/image1d_b.hh>
#include <mln/level/fill.hh>
#include <mln/debug/println.hh>
@@ -41,7 +42,34 @@
int main()
{
border::thickness = 3;
+
+ {
image2d_b<bool> msk(3, 3);
- msk.at(1, 1) = true;
+ msk.at(0, 0) = true;
+ msk.at(1, 0) = true;
+ msk.at(2, 0) = true;
+
+ msk.at(0, 1) = true;
+ msk.at(1, 1) = false;
+ msk.at(2, 1) = true;
+
+ msk.at(0, 2) = true;
+ msk.at(1, 2) = true;
+ msk.at(2, 2) = true;
+
+ debug::println(msk);
debug::println_with_border(msk);
}
+
+ {
+ image1d_b<bool> msk(3);
+ msk.at(0) = false;
+ msk.at(1) = true;
+ msk.at(2) = false;
+
+ debug::println(msk);
+ debug::println_with_border(msk);
+
+ }
+
+}
Index: trunk/milena/mln/debug/println.hh
===================================================================
--- trunk/milena/mln/debug/println.hh (revision 1093)
+++ trunk/milena/mln/debug/println.hh (revision 1094)
@@ -71,9 +71,8 @@
void println_with_border(const S&, const Fast_Image<I>& input_)
{
const I& input = exact(input_);
- std::cout << input.ncells() << std::endl;
for (int i = 0; i < input.ncells(); i++)
- std::cout << input.buffer()[i] << ' ';
+ std::cout << format( input.buffer()[i] ) << ' ';
std::cout << std::endl;
}
@@ -105,7 +104,7 @@
const std::size_t ncols = b.ncols() + 2 * input.border();
for (size_t i = 0; i < input.ncells(); i++)
{
- std::cout << input.buffer()[i] << ' ';
+ std::cout << format( input.buffer()[i] ) << ' ';
if (((i+1) % ncols) == 0)
std::cout << std::endl;
}
Index: trunk/milena/mln/core/image1d_b.hh
===================================================================
--- trunk/milena/mln/core/image1d_b.hh (revision 1093)
+++ trunk/milena/mln/core/image1d_b.hh (revision 1094)
@@ -189,6 +189,7 @@
private:
T* buffer_;
+ T* array_;
box1d b_; // theoretical box
unsigned bdr_;
@@ -209,14 +210,16 @@
template <typename T>
image1d_b<T>::image1d_b()
- : buffer_(0)
+ : buffer_(0),
+ array_ (0)
{
bdr_ = border::thickness; // default value in ctors.
}
template <typename T>
image1d_b<T>::image1d_b(int ninds, unsigned bdr)
- : buffer_(0)
+ : buffer_(0),
+ array_ (0)
{
init_with(ninds, bdr);
}
@@ -233,7 +236,8 @@
template <typename T>
image1d_b<T>::image1d_b(const box1d& b, unsigned bdr)
- : buffer_(0)
+ : buffer_(0),
+ array_ (0)
{
init_with(b, bdr);
}
@@ -286,7 +290,7 @@
bool
image1d_b<T>::has_data() const
{
- return buffer_ != 0;
+ return buffer_ != 0 && array_ != 0;;
}
template <typename T>
@@ -333,7 +337,7 @@
image1d_b<T>::operator()(const point1d& p) const
{
mln_precondition(this->owns_(p));
- return buffer_[p.ind()];
+ return array_[p.ind()];
}
template <typename T>
@@ -341,7 +345,7 @@
image1d_b<T>::operator()(const point1d& p)
{
mln_precondition(this->owns_(p));
- return buffer_[p.ind()];
+ return array_[p.ind()];
}
template <typename T>
@@ -365,7 +369,7 @@
image1d_b<T>::at(int ind) const
{
mln_precondition(this->owns_(make::point1d(ind)));
- return buffer_[ind];
+ return array_[ind];
}
template <typename T>
@@ -373,7 +377,7 @@
image1d_b<T>::at(int ind)
{
mln_precondition(this->owns_(make::point1d(ind)));
- return buffer_[ind];
+ return array_[ind];
}
template <typename T>
@@ -436,6 +440,7 @@
unsigned
ni = vb_.len(0);
buffer_ = new T[ni];
+ array_ = buffer_ - vb_.pmin().ind();
mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Renaming io and fix warnings.
* mln/io/pgm: New directory.
* mln/io/save_pgm.hh: Rename as...
* mln/io/pgm/save.hh: ...this.
(save_pgn): Rename as...
(save): ...this.
* mln/io/load_pgm.hh: Rename as...
* mln/io/pgm/load.hh: ...this.
(load_pgm): Rename as...
(load): ...this.
* tests/level_naive_median.cc,
* tests/linear_log.cc,
* tests/level_median_hline2d.cc,
* tests/morpho_thinning.cc,
* tests/morpho_erosion.cc,
* tests/morpho_hit_or_miss.cc,
* tests/morpho_laplacian.cc,
* tests/morpho_opening_area.cc,
* tests/labeling_regional_maxima.cc,
* tests/level_median_fast.cc,
* tests/level_approx_median.cc,
* tests/level_median.cc,
* tests/linear_convolve.cc,
* tests/linear_sobel.cc,
* tests/line_convolve.cc,
* tests/linear_gaussian.cc,
* tests/linear_lap.cc,
* tests/labeling_foreground.cc,
* tests/morpho_contrast.cc,
* tests/morpho_gradient.cc: Update.
* mln/linear/gaussian.hh,
* mln/canvas/morpho/algebraic_union_find.hh,
* mln/canvas/dirbrowsing.hh,
* mln/canvas/labeling.hh: Fix warnings.
mln/canvas/dirbrowsing.hh | 2 +-
mln/canvas/labeling.hh | 1 -
mln/canvas/morpho/algebraic_union_find.hh | 1 -
mln/io/pgm/load.hh | 21 +++++++++++++--------
mln/io/pgm/save.hh | 27 ++++++++++++++++-----------
mln/linear/gaussian.hh | 11 +++++------
tests/labeling_foreground.cc | 8 ++++----
tests/labeling_regional_maxima.cc | 8 ++++----
tests/level_approx_median.cc | 8 ++++----
tests/level_median.cc | 8 ++++----
tests/level_median_fast.cc | 8 ++++----
tests/level_median_hline2d.cc | 8 ++++----
tests/level_naive_median.cc | 8 ++++----
tests/line_convolve.cc | 8 ++++----
tests/linear_convolve.cc | 8 ++++----
tests/linear_gaussian.cc | 8 ++++----
tests/linear_lap.cc | 4 ++--
tests/linear_log.cc | 8 ++++----
tests/linear_sobel.cc | 8 ++++----
tests/morpho_contrast.cc | 8 ++++----
tests/morpho_erosion.cc | 10 +++++-----
tests/morpho_gradient.cc | 8 ++++----
tests/morpho_hit_or_miss.cc | 10 +++++-----
tests/morpho_laplacian.cc | 8 ++++----
tests/morpho_opening_area.cc | 8 ++++----
tests/morpho_thinning.cc | 8 ++++----
26 files changed, 115 insertions(+), 108 deletions(-)
Index: tests/level_naive_median.cc
--- tests/level_naive_median.cc (revision 1092)
+++ tests/level_naive_median.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
#include <mln/level/naive/median.hh>
@@ -50,9 +50,9 @@
border::thickness = 52;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
level::naive::median(lena, rec, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/linear_log.cc
--- tests/linear_log.cc (revision 1092)
+++ tests/linear_log.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/value/int_u8.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/border/thickness.hh>
#include <mln/linear/log.hh>
@@ -50,7 +50,7 @@
border::thickness = 2;
- image2d_b<int_u8> lena = io::load_pgm("../img/lena.pgm");
+ image2d_b<int_u8> lena = io::pgm::load("../img/lena.pgm");
image2d_b<int> tmp(lena.domain());
linear::LoG_5x5(lena, tmp);
@@ -62,7 +62,7 @@
image2d_b<int_u8> out(lena.domain());
level::stretch(tmp, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
{
int_u8 min, max;
estim::min_max(out, min, max);
Index: tests/level_median_hline2d.cc
--- tests/level_median_hline2d.cc (revision 1092)
+++ tests/level_median_hline2d.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
#include <mln/level/median.hh>
@@ -51,14 +51,14 @@
border::thickness = 0;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain()),
ref(lena.domain());
level::median(lena, win::rectangle2d(1, 101), ref);
level::median(lena, win::hline2d(101), out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
// FIXME: mln_assertion(out = ref);
}
Index: tests/morpho_thinning.cc
--- tests/morpho_thinning.cc (revision 1092)
+++ tests/morpho_thinning.cc (working copy)
@@ -36,8 +36,8 @@
#include <mln/core/win/rectangle2d.hh>
#include <mln/core/window2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/morpho/thinning.hh>
@@ -60,10 +60,10 @@
border::thickness = 2;
image2d_b<int_u8>
- pic = io::load_pgm("../img/picasso.pgm"),
+ pic = io::pgm::load("../img/picasso.pgm"),
out(pic.domain());
morpho::thinning(pic, win_fg, win_bg, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/morpho_erosion.cc
--- tests/morpho_erosion.cc (revision 1092)
+++ tests/morpho_erosion.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
#include <mln/level/fill.hh>
@@ -54,12 +54,12 @@
win::rectangle2d rec(21, 21);
border::thickness = 66;
- image2d_b<int_u8> lena = io::load_pgm("../img/lena.pgm");
+ image2d_b<int_u8> lena = io::pgm::load("../img/lena.pgm");
{
image2d_b<int_u8> out(lena.domain());
morpho::erosion(lena, rec, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
{
@@ -71,7 +71,7 @@
image2d_b<int_u8>::fwd_piter p(lena.domain());
for_all(p)
test(p) = out(p) ? 255 : 0;
- io::save_pgm(test, "test.pgm");
+ io::pgm::save(test, "test.pgm");
}
}
Index: tests/morpho_hit_or_miss.cc
--- tests/morpho_hit_or_miss.cc (revision 1092)
+++ tests/morpho_hit_or_miss.cc (working copy)
@@ -38,8 +38,8 @@
#include <mln/geom/shift.hh>
#include <mln/set/diff.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/level/fill.hh>
#include <mln/level/stretch.hh>
@@ -53,7 +53,7 @@
window2d win_hit = geom::shift(win::rectangle2d(3, 3),
make::dpoint2d(+1, +1));
- window2d win_miss = set::diff(win::rectangle2d(5, 5), win_hit);
+ window2d win_miss = mln::set::diff(win::rectangle2d(5, 5), win_hit);
{
bool hit[] = { 0, 0, 0, 0, 0,
@@ -76,10 +76,10 @@
border::thickness = 2;
image2d_b<int_u8>
- pic = io::load_pgm("../img/picasso.pgm"),
+ pic = io::pgm::load("../img/picasso.pgm"),
out(pic.domain());
morpho::hit_or_miss(pic, win_hit, win_miss, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/morpho_laplacian.cc
--- tests/morpho_laplacian.cc (revision 1092)
+++ tests/morpho_laplacian.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u_sat.hh>
#include <mln/core/cast_image.hh>
@@ -53,11 +53,11 @@
win::rectangle2d rect(5, 5);
border::thickness = 2;
- image2d_b<int_u8> lena = io::load_pgm("../img/tiny.pgm");
+ image2d_b<int_u8> lena = io::pgm::load("../img/tiny.pgm");
image2d_b<int> lap(lena.domain());
morpho::laplacian(lena, rect, lap);
image2d_b< value::int_u_sat<8> > out(lena.domain());
arith::plus_cst(lap, 128, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/morpho_opening_area.cc
--- tests/morpho_opening_area.cc (revision 1092)
+++ tests/morpho_opening_area.cc (working copy)
@@ -34,8 +34,8 @@
#include <mln/value/int_u8.hh>
#include <mln/core/neighb2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/morpho/opening_area.hh>
@@ -47,9 +47,9 @@
using value::int_u8;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
morpho::opening_area(lena, c4(), 510, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/labeling_regional_maxima.cc
--- tests/labeling_regional_maxima.cc (revision 1092)
+++ tests/labeling_regional_maxima.cc (working copy)
@@ -34,8 +34,8 @@
#include <mln/core/neighb2d.hh>
#include <mln/value/int_u8.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/labeling/regional_maxima.hh>
@@ -46,12 +46,12 @@
using value::int_u8;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
unsigned n;
labeling::regional_maxima(lena, c4(), out, n);
mln_assertion(n = 255);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/level_median_fast.cc
--- tests/level_median_fast.cc (revision 1092)
+++ tests/level_median_fast.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
#include <mln/debug/iota.hh>
@@ -94,11 +94,11 @@
border::thickness = 52;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
level::fast_median(lena, rect, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
}
Index: tests/level_approx_median.cc
--- tests/level_approx_median.cc (revision 1092)
+++ tests/level_approx_median.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
#include <mln/level/approx/median.hh>
@@ -51,9 +51,9 @@
border::thickness = 52;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
level::approx::median(lena, rect, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/level_median.cc
--- tests/level_median.cc (revision 1092)
+++ tests/level_median.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
#include <mln/level/median.hh>
@@ -51,9 +51,9 @@
border::thickness = 52;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
level::median(lena, rect, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/linear_convolve.cc
--- tests/linear_convolve.cc (revision 1092)
+++ tests/linear_convolve.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/value/int_u8.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/math/round.hh>
#include <mln/level/transform.hh>
@@ -51,7 +51,7 @@
border::thickness = 2;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
float ws[] = { .04, .04, .04, .04, .04,
@@ -65,5 +65,5 @@
linear::convolve(lena, w, tmp);
level::transform(tmp, math::round<int_u8>(), out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/linear_sobel.cc
--- tests/linear_sobel.cc (revision 1092)
+++ tests/linear_sobel.cc (working copy)
@@ -34,8 +34,8 @@
#include <mln/value/int_u8.hh>
#include <mln/level/saturate.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/border/thickness.hh>
#include <mln/linear/sobel.hh>
@@ -49,12 +49,12 @@
border::thickness = 1;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
image2d_b<int> tmp(lena.domain());
linear::sobel(lena, tmp);
level::saturate(tmp, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/line_convolve.cc
--- tests/line_convolve.cc (revision 1092)
+++ tests/line_convolve.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/value/int_u8.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/math/round.hh>
#include <mln/level/transform.hh>
@@ -51,7 +51,7 @@
border::thickness = 4;
image2d_b<int_u8>
- lena = io::load_pgm("../img/lena.pgm"),
+ lena = io::pgm::load("../img/lena.pgm"),
out(lena.domain());
image2d_b<float> tmp(lena.domain());
@@ -59,5 +59,5 @@
linear::line_convolve(lena, ws, tmp);
level::transform(tmp, math::round<int_u8>(), out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/linear_gaussian.cc
--- tests/linear_gaussian.cc (revision 1092)
+++ tests/linear_gaussian.cc (working copy)
@@ -34,8 +34,8 @@
#include <mln/value/int_u8.hh>
#include <mln/value/int_u_sat.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/level/transform.hh>
#include <mln/level/saturate.hh>
@@ -48,12 +48,12 @@
{
using namespace mln;
- image2d_b< value::int_u8 > lena = io::load_pgm("../img/lena.pgm");
+ image2d_b< value::int_u8 > lena = io::pgm::load("../img/lena.pgm");
image2d_b<float> tmp(lena.domain());
linear::gaussian(lena, 5.1f, tmp);
image2d_b< value::int_u_sat<8> > out(lena.domain());
level::transform(tmp, math::round<int>(), out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: tests/linear_lap.cc
--- tests/linear_lap.cc (revision 1092)
+++ tests/linear_lap.cc (working copy)
@@ -32,7 +32,7 @@
#include <mln/core/image2d_b.hh>
#include <mln/value/int_u8.hh>
-#include <mln/io/load_pgm.hh>
+#include <mln/io/pgm/load.hh>
#include <mln/border/thickness.hh>
#include <mln/linear/lap.hh>
@@ -45,7 +45,7 @@
border::thickness = 1;
- image2d_b<int_u8> lena = io::load_pgm("../img/lena.pgm");
+ image2d_b<int_u8> lena = io::pgm::load("../img/lena.pgm");
image2d_b<int> tmp(lena.domain());
linear::lap_4(lena, tmp);
}
Index: tests/labeling_foreground.cc
--- tests/labeling_foreground.cc (revision 1092)
+++ tests/labeling_foreground.cc (working copy)
@@ -35,8 +35,8 @@
#include <mln/value/int_u8.hh>
#include <mln/pw/all.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/labeling/foreground.hh>
@@ -46,12 +46,12 @@
using value::int_u8;
image2d_b<int_u8>
- lena = io::load_pgm("../img/tiny.pgm"),
+ lena = io::pgm::load("../img/tiny.pgm"),
out(lena.domain());
unsigned n;
labeling::foreground((pw::value(lena) > pw::cst(127)) | lena.domain(),
c4(), out, n);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
mln_assertion(n = 14);
}
Index: tests/morpho_contrast.cc
--- tests/morpho_contrast.cc (revision 1092)
+++ tests/morpho_contrast.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
#include <mln/value/int_s.hh>
@@ -54,7 +54,7 @@
border::thickness = 2;
image2d_b<int_u8>
- lena = io::load_pgm("../img/tiny.pgm"),
+ lena = io::pgm::load("../img/tiny.pgm"),
out(lena.domain());
image2d_b< value::int_s<10> >
@@ -65,7 +65,7 @@
morpho::contrast(in, rect, tmp);
level::saturate(tmp, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
{
// self-duality test:
Index: tests/morpho_gradient.cc
--- tests/morpho_gradient.cc (revision 1092)
+++ tests/morpho_gradient.cc (working copy)
@@ -33,8 +33,8 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/win/rectangle2d.hh>
-#include <mln/io/load_pgm.hh>
-#include <mln/io/save_pgm.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/value/int_u8.hh>
#include <mln/morpho/gradient.hh>
@@ -50,9 +50,9 @@
border::thickness = 2;
image2d_b<int_u8>
- lena = io::load_pgm("../img/tiny.pgm"),
+ lena = io::pgm::load("../img/tiny.pgm"),
out(lena.domain());
morpho::gradient(lena, rect, out);
- io::save_pgm(out, "out.pgm");
+ io::pgm::save(out, "out.pgm");
}
Index: mln/io/pgm/save.hh
--- mln/io/pgm/save.hh (revision 0)
+++ mln/io/pgm/save.hh (working copy)
@@ -26,8 +26,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_IO_SAVE_PGM_HH
-# define MLN_IO_SAVE_PGM_HH
+#ifndef MLN_IO_PGM_SAVE_HH
+# define MLN_IO_PGM_SAVE_HH
# include <iostream>
# include <fstream>
@@ -50,8 +50,11 @@
namespace io
{
+ namespace pgm
+ {
+
template <typename I>
- void save_pgm(const Image<I>& ima, const std::string& filename);
+ void save(const Image<I>& ima, const std::string& filename);
# ifndef MLN_INCLUDE_ONLY
@@ -60,7 +63,7 @@
{
template <typename I>
- void save_pgm_header_(const I& ima, const std::string& filename,
+ void save_header_(const I& ima, const std::string& filename,
std::ofstream& file)
{
if (! file)
@@ -76,11 +79,11 @@
}
template <typename I>
- void save_pgm_(const Fast_Image<I>& ima_, const std::string& filename)
+ void save_(const Fast_Image<I>& ima_, const std::string& filename)
{
const I& ima = exact(ima_);
std::ofstream file(filename.c_str());
- save_pgm_header_(ima, filename, file);
+ save_header_(ima, filename, file);
const int
min_row = geom::min_row(ima),
max_row = geom::max_row(ima);
@@ -108,11 +111,11 @@
}
template <typename I>
- void save_pgm_(const Image<I>& ima_, const std::string& filename)
+ void save_(const Image<I>& ima_, const std::string& filename)
{
const I& ima = exact(ima_);
std::ofstream file(filename.c_str());
- save_pgm_header_(ima, filename, file);
+ save_header_(ima, filename, file);
const int
min_row = geom::min_row(ima),
max_row = geom::max_row(ima),
@@ -131,20 +134,22 @@
template <typename I>
- void save_pgm(const Image<I>& ima, const std::string& filename)
+ void save(const Image<I>& ima, const std::string& filename)
{
mln::metal::or_<
mln::metal::equal<mln_value(I), value::int_u<8> >,
mln::metal::equal<mln_value(I), value::int_u_sat<8> >
>::check();
- impl::save_pgm_(exact(ima), filename);
+ impl::save_(exact(ima), filename);
}
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::pgm
+
} // end of namespace mln::io
} // end of namespace mln
-#endif // ! MLN_IO_SAVE_PGM_HH
+#endif // ! MLN_IO_PGM_SAVE_HH
Index: mln/io/pgm/load.hh
--- mln/io/pgm/load.hh (revision 0)
+++ mln/io/pgm/load.hh (working copy)
@@ -26,8 +26,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_IO_LOAD_PGM_HH
-# define MLN_IO_LOAD_PGM_HH
+#ifndef MLN_IO_PGM_LOAD_HH
+# define MLN_IO_PGM_LOAD_HH
# include <iostream>
# include <fstream>
@@ -43,6 +43,9 @@
namespace io
{
+ namespace pgm
+ {
+
namespace internal
{
@@ -116,7 +119,7 @@
/// load_ascii.
template <typename I>
- void load_pgm_ascii(std::ifstream& file, I& ima)
+ void load_ascii(std::ifstream& file, I& ima)
{
mln_fwd_piter(I) p(ima.domain());
for_all(p)
@@ -132,7 +135,7 @@
/// load_raw_2d.
template <typename I>
- void load_pgm_raw_2d(std::ifstream& file, I& ima)
+ void load_raw_2d(std::ifstream& file, I& ima)
{
point2d p = make::point2d(0, ima.domain().pmin().col());
typedef mln_value(I) V;
@@ -165,7 +168,7 @@
} // end of namespace mln::io::internal
- image2d_b<value::int_u8> load_pgm(const std::string& filename)
+ image2d_b<value::int_u8> load(const std::string& filename)
{
std::ifstream file(filename.c_str());
if (! file)
@@ -180,16 +183,18 @@
image2d_b<value::int_u8> ima(nrows, ncols);
if (type = '5')
- internal::load_pgm_raw_2d(file, ima);
+ internal::load_raw_2d(file, ima);
else
if (type = '2')
- internal::load_pgm_ascii(file, ima);
+ internal::load_ascii(file, ima);
return ima;
}
+ } // end of namespace mln::io::pgm
+
} // end of namespace mln::io
} // end of namespace mln
-#endif // ! MLN_IO_LOAD_PGM_HH
+#endif // ! MLN_IO_PGM_LOAD_HH
Index: mln/linear/gaussian.hh
--- mln/linear/gaussian.hh (revision 1092)
+++ mln/linear/gaussian.hh (working copy)
@@ -52,7 +52,7 @@
template <class I, class O>
void
gaussian(const Image<I>& input, float sigma,
- Image<O>& output)
+ Image<O>& output);
# ifndef MLN_INCLUDE_ONLY
@@ -251,7 +251,7 @@
I& img = exact(img_);
// Apply on rows.
- for (int j = 0; j < geom::ncols(img); ++j)
+ for (unsigned j = 0; j < geom::ncols(img); ++j)
recursivefilter_<float>(img, coef,
make::point2d(-img.border(), j),
make::point2d(geom::nrows(img) - 1 + img.border(), j),
@@ -259,7 +259,7 @@
make::dpoint2d(1, 0));
// Apply on columns.
- for (int i = 0; i < geom::nrows(img); ++i)
+ for (unsigned i = 0; i < geom::nrows(img); ++i)
recursivefilter_<float>(img, coef,
make::point2d(i, -img.border()),
make::point2d(i, geom::ncols(img) - 1 + img.border()),
@@ -298,14 +298,13 @@
gaussian(const Image<I>& input, float sigma,
Image<O>& output)
{
- recursivefilter_coef_
+ impl::recursivefilter_coef_
coef(1.68f, 3.735f,
1.783f, 1.723f,
-0.6803f, -0.2598f,
0.6318f, 1.997f,
sigma);
-
- gaussian_common_(in, coef, sigma, out);
+ impl::gaussian_common_(input, coef, sigma, output);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/canvas/morpho/algebraic_union_find.hh
--- mln/canvas/morpho/algebraic_union_find.hh (revision 1092)
+++ mln/canvas/morpho/algebraic_union_find.hh (working copy)
@@ -100,7 +100,6 @@
// second pass
{
mln_bkd_piter(S) p(f.s);
- mln_niter(N) n(f.nbh, p);
for_all(p)
if (is_root(p))
f.output(p) = f.input(p);
Index: mln/canvas/dirbrowsing.hh
--- mln/canvas/dirbrowsing.hh (revision 1092)
+++ mln/canvas/dirbrowsing.hh (working copy)
@@ -77,7 +77,7 @@
for (int c = F::dim - 1; c >= 0; --c)
{
- if (c = f.dir)
+ if (c = int(f.dir))
continue;
if (p[c] != pmax[c])
{
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 1092)
+++ mln/canvas/labeling.hh (working copy)
@@ -97,7 +97,6 @@
// second pass
{
mln_bkd_piter(S) p(f.s);
- mln_niter(N) n(f.nbh, p);
for_all(p) if (f.handles(p))
{
if (is_root(p))
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Update level median filter with directional cases.
* mln/core/point.hh (operator+=): New.
* tests/dpoint2d.cc: Update.
* mln/canvas/browsing/snake_fwd.hh: Fix missing namespace.
* sandbox/nivault/dirbrowsing.hh: Rename as...
* mln/canvas/dirbrowsing.hh: ...this.
* mln/level/median.hh: Update.
* sandbox/nivault/median.hh: Update.
mln/canvas/browsing/snake_fwd.hh | 5
mln/canvas/dirbrowsing.hh | 2
mln/core/point.hh | 11 +
mln/level/median.hh | 198 ++++++++++++++++++--------
sandbox/nivault/median.hh | 294 +++++++++++----------------------------
tests/dpoint2d.cc | 3
6 files changed, 250 insertions(+), 263 deletions(-)
Index: tests/dpoint2d.cc
--- tests/dpoint2d.cc (revision 1091)
+++ tests/dpoint2d.cc (working copy)
@@ -50,4 +50,7 @@
const int (&vec)[2] = dp.to_vec();
mln_assertion(vec[0] = 3);
+
+ p += dp;
+ mln_assertion(q = p);
}
Index: mln/core/point.hh
--- mln/core/point.hh (revision 1091)
+++ mln/core/point.hh (working copy)
@@ -96,6 +96,8 @@
/// Origin point (all coordinates are 0).
static const point_<n,C> zero;
+ /// Shifting by \p dp.
+ point_<n, C>& operator+=(const dpoint& dp);
/// Type of the array of coordinates.
typedef const C (&vec_t)[n];
@@ -148,6 +150,15 @@
template <unsigned n, typename C>
const point_<n,C> point_<n,C>::zero = all(0);
+ template <unsigned n, typename C>
+ point_<n, C>&
+ point_<n,C>::operator+=(const dpoint& dp)
+ {
+ for (unsigned i = 0; i < n; ++i)
+ coord_[i] += dp[i];
+ return *this;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/level/median.hh
--- mln/level/median.hh (revision 1091)
+++ mln/level/median.hh (working copy)
@@ -31,21 +31,19 @@
/*! \file mln/level/median.hh
*
* \brief Median filtering of an image.
+ *
+ * \todo Add Fast_Image versions.
*/
# include <mln/core/concept/image.hh>
-# include <mln/geom/size2d.hh>
-
-# include <mln/core/window2d.hh>
-# include <mln/core/win/hline2d.hh>
-# include <mln/core/t_image.hh>
-
-# include <mln/accu/median.hh>
-# include <mln/canvas/browsing/snake_fwd.hh>
-
+# include <mln/core/window.hh>
# include <mln/geom/shift.hh>
# include <mln/set/diff.hh>
+# include <mln/canvas/browsing/snake_fwd.hh>
+# include <mln/canvas/dirbrowsing.hh>
+# include <mln/accu/median.hh>
+
namespace mln
{
@@ -58,7 +56,7 @@
*
* \param[in] input The image to be filtered.
* \param[in] win The window.
- * \param[in,out] output The output image.
+ * \param[out] output The output image.
*
* \pre \p input and \p output have to be initialized.
*/
@@ -67,16 +65,40 @@
Image<O>& output);
-# ifndef MLN_INCLUDE_ONLY
+
+ /*! Compute in \p output the median filter of image \p input in
+ * the direction \p dir with strength \p length.
+ *
+ * \param[in] input The image to be filtered.
+ * \param[in] dir The filtering direction.
+ * \param[in] length The filtering strength.
+ * \param[out] output The output image.
+ *
+ * \pre \p input and \p output have to be initialized.
+ * \pre \p dir is between 0 and less than the image dimension.
+ * \pre \p length has to be odd.
+ */
+ template <typename I, typename O>
+ void median_dir(const Image<I>& input, unsigned dir, unsigned length,
+ Image<O>& output);
+
+# ifndef MLN_INCLUDE_ONLY
+
namespace impl
{
+ // Functors.
+
+
template <typename I, typename W, typename O>
- struct median_functor
+ struct median_t
{
+ typedef mln_point(I) P;
+ typedef mln_dpoint(I) D;
+
// i/o
const I& input;
@@ -86,13 +108,13 @@
// aux data
accu::median<mln_vset(I)> med;
- mln_point(I) p;
- window2d win_fp, win_fm, win_bp, win_bm, win_dp, win_dm;
+ P p;
+ window<D> win_fp, win_fm, win_bp, win_bm, win_dp, win_dm;
mln_qiter(W) q_fp, q_fm, q_bp, q_bm, q_dp, q_dm;
// ctor
- median_functor(const I& input_, const W& win_, O& output_)
+ median_t(const I& input_, const W& win_, O& output_)
:
// i/o
input(exact(input_)),
@@ -150,99 +172,163 @@
output(p) = med.to_value();
}
- }; // end of median_functor
+ }; // end of median_t
-
- template <typename I, typename W, typename O>
- void median(const I& input, const Window<W>& win, O& output)
- {
- // FIXME: resize border!
- impl::median_functor<I,W,O> f(input, exact(win), output);
- canvas::browsing::snake_fwd(f);
- }
-
-
template <typename I, typename O>
- void median(const I& input, const win::hline2d& win, O& output)
+ struct median_dir_t
{
- typedef mln_coord(I) coord;
- const coord
- min_row = geom::min_row(input),
- max_row = geom::max_row(input),
- min_col = geom::min_col(input),
- max_col = geom::max_col(input);
- const coord half = win.length() / 2;
+ typedef mln_point(I) point;
+ enum { dim = point::dim };
- point2d p;
- coord& row = p.row();
- coord& col = p.col();
+ // i/o
+ const I& input;
+ const unsigned dir;
+ const unsigned length;
+ O& output;
- point2d pt;
- coord& ct = pt.col();
+ // aux data
+ const mln_point(I)
+ pmin, pmax;
+ const mln_coord(I)
+ pmin_dir, pmax_dir,
+ pmin_dir_plus, pmax_dir_minus;
+ accu::median<mln_vset(I)> med;
- point2d pu;
- coord& cu = pu.col();
+ // ctor
+ median_dir_t(const I& input, unsigned dir, unsigned length, O& output)
+ : // i/o
+ input(input),
+ dir(dir),
+ length(length),
+ output(exact(output)),
+ // aux data
+ pmin(input.domain().pmin()),
+ pmax(input.domain().pmax()),
+ pmin_dir(pmin[dir]),
+ pmax_dir(pmax[dir]),
+ pmin_dir_plus (pmin[dir] + length / 2),
+ pmax_dir_minus(pmax[dir] - length / 2),
+ med(input.values())
+ {
+ }
- accu::median<mln_vset(I)> med(input.values());
+ void init()
+ {
+ }
- for (row = min_row; row <= max_row; ++row)
+ void process(const mln_point(I)& p_)
{
- pt.row() = pu.row() = row;
+ mln_point(I)
+ p = p_,
+ pt = p,
+ pu = p;
+
+ typedef mln_coord(I)& coord_ref;
+ coord_ref
+ ct = pt[dir],
+ cu = pu[dir],
+ p_dir = p[dir];
// initialization (before first point of the row)
med.init();
- for (ct = min_col; ct < min_col + half; ++ct)
+ for (ct = pmin_dir; ct < pmin_dir_plus; ++ct)
+ if (input.has(pt))
med.take(input(pt));
// left columns (just take new points)
- for (col = min_col; col <= min_col + half; ++col, ++ct)
+ for (p_dir = pmin_dir; p_dir <= pmin_dir_plus; ++p_dir, ++ct)
{
+ if (input.has(pt))
med.take(input(pt));
+ if (output.has(p))
output(p) = med.to_value();
}
// middle columns (both take and untake)
- cu = min_col;
- for (; col <= max_col - half; ++cu, ++col, ++ct)
+ cu = pmin[dir];
+ for (; p_dir <= pmax_dir_minus; ++cu, ++p_dir, ++ct)
{
+ if (input.has(pt))
med.take(input(pt));
+ if (input.has(pu))
med.untake(input(pu));
+ if (output.has(p))
output(p) = med.to_value();
}
// right columns (now just untake old points)
- for (; col <= max_col; ++cu, ++col)
+ for (; p_dir <= pmax_dir; ++cu, ++p_dir)
{
+ if (input.has(pu))
med.untake(input(pu));
+ if (output.has(p))
output(p) = med.to_value();
}
}
+
+ }; // end of median_dir_t
+
+
+
+ template <typename I, typename O>
+ void median_dir_(const Image<I>& input, unsigned dir, unsigned length, O& output)
+ {
+ median_dir_t<I,O> f(exact(input), dir, length, output);
+ canvas::dirbrowsing(f);
}
+ template <typename I, typename W, typename O>
+ void median_(const Image<I>& input, const Window<W>& win, O& output)
+ {
+ // FIXME: resize border!
+ median_t<I,W,O> f(exact(input), exact(win), output);
+ canvas::browsing::snake_fwd(f);
+ }
+
+
+# ifdef MLN_CORE_WIN_HLINE2D_HH
+ template <typename I, typename O>
+ void median_(const Image<I>& input, const win::hline2d& win, O& output)
+ {
+ median_dir(input, 1, win.length(), output); // FIXME: Make 1 explicit!
+ }
+# endif
+
+# ifdef MLN_CORE_WIN_VLINE2D_HH
template <typename I, typename O>
- void median(const I& input, const win::vline2d& win, O& output)
+ void median_(const Image<I>& input, const win::vline2d& win, O& output)
{
- t_image<O> swap_output = swap_coords(output, 0, 1);
- impl::median(swap_coords(input, 0, 1),
- win::hline2d(win.length()),
- swap_output);
+ median_dir(input, 0, win.length(), output);
}
+# endif
} // end of namespace mln::level::impl
- // facade
+
+ // Facades.
template <typename I, typename W, typename O>
void median(const Image<I>& input, const Window<W>& win,
Image<O>& output)
{
mln_assertion(exact(output).domain() = exact(input).domain());
- impl::median(exact(input), exact(win), exact(output));
+ impl::median_(exact(input), exact(win), exact(output));
+ }
+
+ template <typename I, typename O>
+ void median_dir(const Image<I>& input, unsigned dir, unsigned length,
+ Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ typedef mln_point(I) P;
+ mln_precondition(dir < P::dim);
+ mln_precondition(length % 2 = 1);
+ impl::median_dir_(exact(input), dir, length, exact(output));
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/canvas/dirbrowsing.hh
--- mln/canvas/dirbrowsing.hh (revision 1090)
+++ mln/canvas/dirbrowsing.hh (working copy)
@@ -75,7 +75,7 @@
{
f.process(p);
- for (int c = f.dim - 1; c >= 0; --c)
+ for (int c = F::dim - 1; c >= 0; --c)
{
if (c = f.dir)
continue;
Index: mln/canvas/browsing/snake_fwd.hh
--- mln/canvas/browsing/snake_fwd.hh (revision 1091)
+++ mln/canvas/browsing/snake_fwd.hh (working copy)
@@ -43,6 +43,9 @@
namespace canvas
{
+ namespace browsing
+ {
+
/*! FIXME: Doc!
*
*
@@ -109,6 +112,8 @@
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::canvas::browsing
+
} // end of namespace mln::canvas
} // end of namespace mln
Index: sandbox/nivault/median.hh
--- sandbox/nivault/median.hh (revision 1091)
+++ sandbox/nivault/median.hh (working copy)
@@ -73,296 +73,178 @@
Image<O>& output);
-# ifndef MLN_INCLUDE_ONLY
+ // FIXME: Doc!
+ template <typename I, typename O>
+ void median_dir(const Image<I>& input, unsigned dir, unsigned length,
+ Image<O>& output);
+
+# ifndef MLN_INCLUDE_ONLY
+
namespace impl
{
+ // Directional median.
+
template <typename I, typename O>
- struct median_dir_functor
+ struct median_dir_t
{
- // type
typedef mln_point(I) point;
+ enum { dim = point::dim };
// i/o
const I& input;
+ const unsigned dir;
+ const unsigned length;
O& output;
- int dir;
- int dim;
- const win::hline2d& win;
+
+ // aux data
+ const mln_point(I)
+ pmin = input.domain().pmin(),
+ pmax = input.domain().pmax();
+ const mln_coord(I)
+ pmin_dir = pmin[dir],
+ pmax_dir = pmax[dir],
+ pmin_dir_plus = pmin[dir] + length / 2,
+ pmax_dir_minus = pmax[dir] - length / 2;
accu::median<mln_vset(I)> med;
// ctor
- median_dir_functor(const Image<I>& input_, const win::hline2d& win_, int dir_, O& output_)
- :
- input(exact(input_)),
- output(exact(output_)),
- dir(dir_),
- dim(I::point::dim),
- win(win_),
+ median_dir_t(const I& input, unsigned dir, unsigned length, O& output)
+ : // i/o
+ input(exact(input)),
+ dir(dir),
+ length(length),
+ output(exact(output)),
+ // aux data
+ pmin(input.domain().pmin()),
+ pmax(input.domain().pmax()),
+ pmin_dir(pmin[dir]),
+ pmax_dir(pmax[dir]),
+ pmin_dir_plus (pmin[dir] + length / 2),
+ pmax_dir_minus(pmax[dir] - length / 2),
med(input.values())
{
}
- //parts
void init()
{
}
- void process(mln_point(I) p)
+ void process(const mln_point(I)& p_)
{
mln_point(I)
- pmin = input.domain().pmin(),
- pmax = input.domain().pmax(),
+ p = p_,
pt = p,
pu = p;
- mln_coord(I)& ct = pt[dir];
- mln_coord(I)& cu = pu[dir];
+ typedef mln_coord(I)& coord_ref;
+ coord_ref
+ ct = pt[dir],
+ cu = pu[dir],
+ p_dir = p[dir];
// initialization (before first point of the row)
med.init();
- for (ct = pmin[dir]; ct < pmin[dir] + (win.length() / 2); ++ct)
+ for (ct = pmin_dir; ct < pmin_dir_plus; ++ct)
+ if (input.has(pt))
med.take(input(pt));
// left columns (just take new points)
- for (p[dir] = pmin[dir]; p[dir] <= pmin[dir] + (win.length() / 2); ++p[dir], ++ct)
+ for (p_dir = pmin_dir; p_dir <= pmin_dir_plus; ++p_dir, ++ct)
{
+ if (input.has(pt))
med.take(input(pt));
+ if (output.has(p))
output(p) = med.to_value();
}
// middle columns (both take and untake)
cu = pmin[dir];
- for (; p[dir] <= pmax[dir] - (win.length() / 2); ++cu, ++p[dir], ++ct)
+ for (; p_dir <= pmax_dir_minus; ++cu, ++p_dir, ++ct)
{
+ if (input.has(pt))
med.take(input(pt));
+ if (input.has(pu))
med.untake(input(pu));
+ if (output.has(p))
output(p) = med.to_value();
}
// right columns (now just untake old points)
- for (; p[dir] <= pmax[dir]; ++cu, ++p[dir])
+ for (; p_dir <= pmax_dir; ++cu, ++p_dir)
{
+ if (input.has(pu))
med.untake(input(pu));
+ if (output.has(p))
output(p) = med.to_value();
}
}
};
- template <typename I, typename O>
- void median_dir(const Image<I>& input_, const win::hline2d& win, unsigned dir, O& output)
- {
- struct median_dir_functor<I,O> func(input_, win, dir, output);
- canvas::dirbrowsing(func);
- }
-
-
-// // median_dir monolythique
-
-// template <typename I, typename O>
-// void median_dir(const Image<I>& input_, const win::hline2d& win, int dir, O& output)
-// {
-// const unsigned dim = I::point::dim;
-// mln_precondition(dir < dim);
-// const I& input = exact(input_);
-// mln_point(I)
-// pmin = input.domain().pmin(),
-// pmax = input.domain().pmax();
-
-// const unsigned half = win.length() / 2;
-
-// mln_point(I) p;
-// mln_point(I) pt;
-// mln_point(I) pu;
-
-// mln_coord(I)& ct = pt[dir];
-// mln_coord(I)& cu = pu[dir];
-
-// accu::median<mln_vset(I)> med(input.values());
-
-// p = pmin;
-// do
-// {
-// //traitement
-// pt = pu = p;
-
-// // initialization (before first point of the row)
-// med.init();
-// for (ct = pmin[dir]; ct < pmin[dir] + half; ++ct)
-// med.take(input(pt));
-
-// // left columns (just take new points)
-// for (p[dir] = pmin[dir]; p[dir] <= pmin[dir] + half; ++p[dir], ++ct)
-// {
-// med.take(input(pt));
-// output(p) = med.to_value();
-// }
-
-// // middle columns (both take and untake)
-// cu = pmin[dir];
-// for (; p[dir] <= pmax[dir] - half; ++cu, ++p[dir], ++ct)
-// {
-// med.take(input(pt));
-// med.untake(input(pu));
-// output(p) = med.to_value();
-// }
-
-// // right columns (now just untake old points)
-// for (; p[dir] <= pmax[dir]; ++cu, ++p[dir])
-// {
-// med.untake(input(pu));
-// output(p) = med.to_value();
-// }
-
-// // next line
-// for (int c = dim - 1; c >= 0; --c)
-// {
-// if (c = dir)
-// continue;
-// if (p[c] != pmax[c])
-// {
-// ++p[c];
-// break;
-// }
-// p[c] = pmin[c];
-// }
-// p[dir] = pmin[dir];
-// } while (p != pmin);
-// }
template <typename I, typename O>
- void median(const Image<I>& input_, const win::hline2d& win, O& output)
+ void median_dir_(const Image<I>& input_, unsigned dir, unsigned length, O& output)
{
+ median_dir_t<I,O> f(input_, win, dir, output);
+ canvas::dirbrowsing(f);
+ }
- I& input = exact(input_);
- typedef mln_coord(I) coord;
- const coord
- min_row = geom::min_row(input),
- max_row = geom::max_row(input),
- min_col = geom::min_col(input),
- max_col = geom::max_col(input);
- const coord half = win.length() / 2;
-
- point2d p;
- coord& row = p.row();
- coord& col = p.col();
-
- point2d pt;
- coord& ct = pt.col();
-
- point2d pu;
- coord& cu = pu.col();
- accu::median<mln_vset(I)> med(input.values());
- for (row = min_row; row <= max_row; ++row)
- {
- pt.row() = pu.row() = row;
+ // General median.
- // initialization (before first point of the row)
- med.init();
- for (ct = min_col; ct < min_col + half; ++ct)
- med.take(input(pt));
-
- // left columns (just take new points)
- for (col = min_col; col <= min_col + half; ++col, ++ct)
+ template <typename I, typename W, typename O>
+ void median_(const I& input, const Window<W>& win, O& output)
{
- med.take(input(pt));
- output(p) = med.to_value();
+ impl::median_t<I,W,O> f(input, exact(win), output);
+ canvas::browsing::snake_fwd(f);
}
- // middle columns (both take and untake)
- cu = min_col;
- for (; col <= max_col - half; ++cu, ++col, ++ct)
- {
- med.take(input(pt));
- med.untake(input(pu));
- output(p) = med.to_value();
- }
- // right columns (now just untake old points)
- for (; col <= max_col; ++cu, ++col)
- {
- med.untake(input(pu));
- output(p) = med.to_value();
- }
- }
- }
+# ifdef MLN_CORE_WIN_HLINE2D_HH
template <typename I, typename O>
- void median(const Fast_Image<I>& input_, const win::hline2d& win, O& output)
- {
-
- I& input = exact(input_);
- border::resize(input, win.delta());;
- border::duplicate(input);
-
- typedef mln_coord(I) coord;
- const coord
- min_row = geom::min_row(input),
- max_row = geom::max_row(input),
- min_col = geom::min_col(input),
- max_col = geom::max_col(input);
- const coord half = win.length() / 2;
-
- point2d p;
- coord& row = p.row();
- coord& col = p.col();
-
- point2d pt;
- coord& ct = pt.col();
-
- point2d pu;
- coord& cu = pu.col();
-
- accu::median<mln_vset(I)> med(input.values());
-
- for (row = min_row; row <= max_row; ++row)
- {
- pt.row() = pu.row() = row;
-
- // initialization (before first point of the row)
- med.init();
- for (ct = min_col - half; ct < min_col + half; ++ct)
- med.take(input(pt));
-
- // middle columns (both take and untake)
- cu = min_col;
- for (col = min_col; col <= max_col; ++cu, ++col, ++ct)
+ void median_(const Image<I>& input, const win::hline2d& win, O& output)
{
- med.take(input(pt));
- med.untake(input(pu));
- output(p) = med.to_value();
+ median_dir(input, 0, win.length(), output);
}
- }
- }
+# endif
+
+# ifdef MLN_CORE_WIN_VLINE2D_HH
template <typename I, typename O>
- void median(const I& input,
- const win::vline2d& win,
- O& output)
- {
- t_image<O> swap_output = swap_coords(output, 0, 1);
- impl::median(swap_coords(input, 0, 1),
- win::hline2d(win.length()),
- swap_output);
+ void median_(const Image<I>& input, const win::vline2d& win, O& output)
+ {
+ median_dir(input, 1, win.length(), output);
}
+# endif
} // end of namespace mln::level::impl
- // facade
+ // Facades.
template <typename I, typename W, typename O>
void median(const Image<I>& input, const Window<W>& win,
Image<O>& output)
{
- mln_assertion(exact(output).domain() = exact(input).domain());
- impl::median(exact(input), exact(win), exact(output));
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ impl::median_(exact(input), exact(win), exact(output));
+ }
+
+ template <typename I, typename O>
+ void median_dir(const Image<I>& input, unsigned dir, unsigned length,
+ Image<O>& output)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ typedef mln_point(I) P;
+ mln_precondition(dir < P::dim);
+ mln_precondition(length % 2 = 1);
+ impl::median_dir_(exact(input), exact(win), exact(output));
}
# endif // ! MLN_INCLUDE_ONLY
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-07 Matthieu Garrigues <garrigues.matthieu(a)lrde.epita.fr>
make the tests compile
* mln/convert/to_image.hh: replace box2d by box_<P> to handle 1d
* mln/debug/println.hh: stupid error
* tests/convert_to_vec_p.cc: stupid error
* tests/w_window1d_int.cc: rectangle1d ??? replaced by segment1d
---
mln/convert/to_image.hh | 7 +++++--
mln/debug/println.hh | 4 ++--
tests/convert_to_vec_p.cc | 4 ++--
tests/w_window1d_int.cc | 3 ++-
4 files changed, 11 insertions(+), 7 deletions(-)
Index: trunk/milena/tests/w_window1d_int.cc
===================================================================
--- trunk/milena/tests/w_window1d_int.cc (revision 1090)
+++ trunk/milena/tests/w_window1d_int.cc (revision 1091)
@@ -31,6 +31,7 @@
*/
#include <mln/core/w_window1d_int.hh>
+#include <mln/core/win/segment1d.hh>
#include <mln/convert/to_image.hh>
#include <mln/convert/to_w_window.hh>
@@ -61,7 +62,7 @@
}
{
- w_window1d_int w_win = make::w_window(win::rectangle1d(3, 5),
+ w_window1d_int w_win = make::w_window(win::segment1d(3),
convert::to_fun(f));
// -3 -2 -1 0 +1
// -2 -1 0 +1 +2
Index: trunk/milena/tests/convert_to_vec_p.cc
===================================================================
--- trunk/milena/tests/convert_to_vec_p.cc (revision 1090)
+++ trunk/milena/tests/convert_to_vec_p.cc (revision 1091)
@@ -48,7 +48,7 @@
win::segment1d win1d(5);
vec1d v1(convert::to_vec_p(win1d, p1));
- for (int i=0; i < v1.npoints(); i++)
+ for (size_t i=0; i < v1.npoints(); i++)
std::cout << (v1[i]);
std::cout << "\n";
@@ -58,7 +58,7 @@
win::rectangle2d win2d(3, 3);
vec2d v2(convert::to_vec_p(win2d, p2));
- for (int i=0; i < v2.npoints(); i++)
+ for (size_t i=0; i < v2.npoints(); i++)
std::cout << (v2[i]);
}
Index: trunk/milena/mln/convert/to_image.hh
===================================================================
--- trunk/milena/mln/convert/to_image.hh (revision 1090)
+++ trunk/milena/mln/convert/to_image.hh (revision 1091)
@@ -44,6 +44,7 @@
# include <mln/convert/to_window.hh>
# include <mln/geom/bbox.hh>
# include <mln/level/fill.hh>
+# include <mln/histo/data.hh>
# define mln_image_from(Src, Value) typename mln::image_from_< Src, Value >::ret
@@ -113,7 +114,9 @@
/// Convert an histo \p h into an image1d_b.
template <typename S>
- image1d_b<std::size_t> to_image(const histo::data<S>& h);
+ image1d_b<std::size_t>
+ to_image(const
+ mln::histo::data<S>& h);
# ifndef MLN_INCLUDE_ONLY
@@ -158,7 +161,7 @@
mln_precondition(! w_win.is_empty());
typedef mln_point(W) P;
- box2d b = geom::bbox(w_win);
+ box_<P> b = geom::bbox(w_win);
mln_image_from(W, mln_weight(W)) ima(b);
mln_qiter(W) q(w_win, P::zero);
for_all(q)
Index: trunk/milena/mln/debug/println.hh
===================================================================
--- trunk/milena/mln/debug/println.hh (revision 1090)
+++ trunk/milena/mln/debug/println.hh (revision 1091)
@@ -102,8 +102,8 @@
void println_with_border(const box2d& b, const Fast_Image<I>& input_)
{
const I& input = exact(input_);
- const int ncols = b.ncols() + 2 * input.border();
- for (int i = 0; i < input.ncells(); i++)
+ const std::size_t ncols = b.ncols() + 2 * input.border();
+ for (size_t i = 0; i < input.ncells(); i++)
{
std::cout << input.buffer()[i] << ' ';
if (((i+1) % ncols) == 0)
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-07 Simon Nivault <simon.nivault(a)lrde.epita.fr>
Some fix for compiling
* sandbox/nivault/dirbrowsing.hh: .
* sandbox/nivault/median.hh: .
* sandbox/nivault/tests/test: .
---
dirbrowsing.hh | 2 +-
median.hh | 8 ++++----
tests/test | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
Index: trunk/milena/sandbox/nivault/tests/test
===================================================================
--- trunk/milena/sandbox/nivault/tests/test (revision 1089)
+++ trunk/milena/sandbox/nivault/tests/test (revision 1090)
@@ -1,4 +1,4 @@
#!/bin/bash
-g++ -I../../.. -I../.. -I.. test.cc -O1
+g++-4.1 -ansi -pedantic -W -Wall -Wextra -Wconversion -I../../.. -I../.. -I.. test.cc
./a.out
Index: trunk/milena/sandbox/nivault/dirbrowsing.hh
===================================================================
--- trunk/milena/sandbox/nivault/dirbrowsing.hh (revision 1089)
+++ trunk/milena/sandbox/nivault/dirbrowsing.hh (revision 1090)
@@ -63,7 +63,7 @@
template <typename F>
void dirbrowsing(F& f)
{
- mln_point(F::point)
+ mln_point(F)
pmin = f.input.domain().pmin(),
pmax = f.input.domain().pmax();
Index: trunk/milena/sandbox/nivault/median.hh
===================================================================
--- trunk/milena/sandbox/nivault/median.hh (revision 1089)
+++ trunk/milena/sandbox/nivault/median.hh (revision 1090)
@@ -43,7 +43,7 @@
# include <mln/core/dpoint.hh>
# include <mln/accu/median.hh>
-# include <mln/canvas/sbrowsing.hh>
+# include <mln/canvas/browsing/snake_fwd.hh>
# include <mln/geom/shift.hh>
# include <mln/set/diff.hh>
@@ -88,13 +88,13 @@
// i/o
const I& input;
O& output;
- unsigned dir;
+ int dir;
int dim;
const win::hline2d& win;
accu::median<mln_vset(I)> med;
// ctor
- median_dir_functor(const Image<I>& input_, const win::hline2d& win_, unsigned dir_, O& output_)
+ median_dir_functor(const Image<I>& input_, const win::hline2d& win_, int dir_, O& output_)
:
input(exact(input_)),
output(exact(output_)),
@@ -162,7 +162,7 @@
// // median_dir monolythique
// template <typename I, typename O>
-// void median_dir(const Image<I>& input_, const win::hline2d& win, unsigned dir, O& output)
+// void median_dir(const Image<I>& input_, const win::hline2d& win, int dir, O& output)
// {
// const unsigned dim = I::point::dim;
// mln_precondition(dir < dim);
1
0