Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
#212: Convert Olena's Subversion repository to Git
----------------------+-----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: new
Priority: blocker | Milestone: Olena 1.1
Component: Milena | Version: 1.0
Keywords: |
----------------------+-----------------------------------------------------
I (Roland) will take care of it ASAP (following the release of Olena 1.0).
A few remarks:
* Use a script to do this, of course (reuse the one I wrote to convert
`share/`).
* Don't forget to use a real list of authors (as in the conversion of
other LRDE repositories). Compile a list of all contributors to ensure we
forgot nobody.
* Keep Subversion revision numbers in Git: they will be useful to match
information from Trac and the mailing lists.
* Actually merge branches in the Git repository, by rewriting the
history. The best is probably to create a map of Subversion merges, then
extend the script to handle this.
* Don't forget branches in source:prototypes (grrr...).
* See also #201 and #203.
* Later: Teach Git to Git beginners.
* Even later: reintegrate the PRCS repository (see #3).
--
Ticket URL: <https://trac.lrde.org/olena/ticket/212>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
1
My very first patch into the brand new Olena Git repository. Yippee!!
* m4/oln-with-lib.m4, m4/with-swilena.m4: Here.
Signed-off-by: Roland Levillain <roland(a)lrde.epita.fr>
---
ChangeLog | 6 ++++++
m4/oln-with-lib.m4 | 17 +++++++++++++++++
m4/with-swilena.m4 | 17 +++++++++++++++++
3 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 9b360b9..76c3a44 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-10-27 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Add missing copyright headers to M4 files.
+
+ * m4/oln-with-lib.m4, m4/with-swilena.m4: Here.
+
2009-10-02 Roland Levillain <roland(a)lrde.epita.fr>
Configure Makefiles under milena/apps/papers/.
diff --git a/m4/oln-with-lib.m4 b/m4/oln-with-lib.m4
index 4678d8b..4f939cb 100644
--- a/m4/oln-with-lib.m4
+++ b/m4/oln-with-lib.m4
@@ -1,5 +1,22 @@
# -*- Autoconf -*-
+# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+
# OLN_WITH_LIB(PACKAGE, HEADER, LIBRARY, [SHELL_NAME], [CPP_NAME],
# [OTHER-LIBRARIES])
# ----------------------------------------------------------------
diff --git a/m4/with-swilena.m4 b/m4/with-swilena.m4
index 0537699..08cfdf4 100644
--- a/m4/with-swilena.m4
+++ b/m4/with-swilena.m4
@@ -1,5 +1,22 @@
# -*- Autoconf -*-
+# Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+
# FIXME: Revamp and make it generic, so that it can shared among
# Olena, TC and clspr.
--
1.6.5.2
1
0
18 Nov '09
---
milena/ChangeLog | 4 ++++
milena/doc/white_paper/white_paper.tex | 2 +-
2 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index aa70a1c..b3cd42e 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,9 @@
2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * doc/white_paper/white_paper.tex: Fix an invalid URL.
+
+2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Introduce labeled_image_base.
* mln/core/internal/labeled_image_base.hh: New.
diff --git a/milena/doc/white_paper/white_paper.tex b/milena/doc/white_paper/white_paper.tex
index f32a979..0120ad6 100644
--- a/milena/doc/white_paper/white_paper.tex
+++ b/milena/doc/white_paper/white_paper.tex
@@ -171,7 +171,7 @@ Olena's \textbf{official website}: \url{http://olena.lrde.epita.fr}
Olena's \textbf{Trac}: \url{http://trac.lrde.org/olena}
Milena's \textbf{documentation}:
-\url{http://www.lrde.epita.fr/dload/doc/milena-1.0}
+\url{http://www.lrde.epita.fr/dload/doc/milena/user-refman-html}
%
\medskip
--
1.5.6.5
1
0
* mln/core/internal/labeled_image_base.hh: New.
* mln/core/image/imorph/labeled_image.hh: Make inherit from
labeled_image_base.
---
milena/ChangeLog | 9 +
milena/mln/core/image/imorph/labeled_image.hh | 194 +-------------
.../labeled_image_base.hh} | 270 +++++++-------------
3 files changed, 118 insertions(+), 355 deletions(-)
copy milena/mln/core/{image/imorph/labeled_image.hh => internal/labeled_image_base.hh} (52%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 811c23e..aa70a1c 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Introduce labeled_image_base.
+
+ * mln/core/internal/labeled_image_base.hh: New.
+
+ * mln/core/image/imorph/labeled_image.hh: Make inherit from
+ labeled_image_base.
+
+2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Fix invalid macros.
* mln/core/box_runend_piter.hh,
diff --git a/milena/mln/core/image/imorph/labeled_image.hh b/milena/mln/core/image/imorph/labeled_image.hh
index b0e5ffb..438f6ae 100644
--- a/milena/mln/core/image/imorph/labeled_image.hh
+++ b/milena/mln/core/image/imorph/labeled_image.hh
@@ -30,35 +30,17 @@
///
/// \brief Definition of a morpher on a labeled image.
-# include <mln/core/image/dmorph/image_if.hh>
-# include <mln/core/concept/function.hh>
-# include <mln/core/internal/image_identity.hh>
-# include <mln/core/site_set/box.hh>
-# include <mln/core/routine/duplicate.hh>
-
-# include <mln/accu/pair.hh>
-# include <mln/accu/nil.hh>
-# include <mln/accu/center.hh>
+# include <mln/core/internal/labeled_image_base.hh>
-# include <mln/labeling/compute.hh>
-# include <mln/labeling/pack.hh>
-# include <mln/labeling/relabel.hh>
+# include <mln/core/routine/duplicate.hh>
# include <mln/util/array.hh>
-# include <mln/pw/cst.hh>
-# include <mln/pw/value.hh>
-
-# ifndef NDEBUG
-# include <mln/accu/stat/max.hh>
-# include <mln/data/compute.hh>
-# endif // ! NDEBUG
-
-
+# include <mln/accu/center.hh>
# include <mln/accu/shape/bbox.hh>
-# include <mln/labeling/relabel.hh>
-# include <mln/make/relabelfun.hh>
+# include <mln/accu/stat/max.hh>
+# include <mln/labeling/compute.hh>
namespace mln
{
@@ -78,14 +60,13 @@ namespace mln
/// Data structure for \c mln::labeled_image<I>.
template <typename I>
struct data< labeled_image<I> >
+ : data< labeled_image_base<I, labeled_image<I> > >
{
+ typedef data< labeled_image_base<I, labeled_image<I> > > super_;
+
data(const I& ima, const mln_value(I)& nlabels);
data(const I& ima, const mln_value(I)& nlabels,
const util::array<mln_box(I)>& bboxes);
-
- I ima_;
- mln_value(I) nlabels_;
- mutable util::array< box<mln_psite(I)> > bboxes_;
};
} // end of namespace mln::internal
@@ -95,19 +76,9 @@ namespace mln
{
template <typename I>
- struct image_< labeled_image<I> > : image_< I > // Same as I except...
+ struct image_< labeled_image<I> >
+ : image_< labeled_image_base<I, labeled_image<I> > >
{
- // ...these changes.
- typedef trait::image::category::identity_morpher category;
- typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
- typedef trait::image::value_access::indirect value_access;
-
- typedef trait::image::value_io::read_only value_io;
- typedef trait::image::pw_io::read pw_io;
-
- // extended domain
- typedef trait::image::ext_value::multiple ext_value;
- typedef trait::image::ext_io::read_only ext_io;
};
} // end of namespace mln::trait
@@ -128,19 +99,15 @@ namespace mln
//
template <typename I>
class labeled_image
- : public internal::image_identity< const I, mln_domain(I), labeled_image<I> >
+ : public labeled_image_base<I, labeled_image<I> >
{
- typedef internal::image_identity< const I, mln_domain(I), labeled_image<I> >
- super_;
+ typedef labeled_image_base<I, labeled_image<I> > super_;
public:
/// Skeleton.
typedef labeled_image< tag::image_<I> > skeleton;
- /// Type of the bounding component bounding boxes.
- typedef mln_result(accu::shape::bbox<mln_psite(I)>) bbox_t;
-
/// Constructors
/// @{
/// Constructor without argument.
@@ -162,39 +129,6 @@ namespace mln
/// Duplicate the underlying image and create a new labeled_image.
void init_from_(const labeled_image<I>& model);
- /// Relabel according to a function.
- /// @{
- //
- /// Merge or delete labels according to the given function.
- /// This method ensures that the labeling remains contiguous.
- ///
- // FIXME: currently the label is kept contiguous for
- // performance reasons. Do we want to be less restrictive?
- template <typename F>
- void relabel(const Function_v2v<F>& f);
- //
- /// Labels may be removed. This overload make sure the labeling is still
- /// contiguous.
- template <typename F>
- void relabel(const Function_v2b<F>& f);
- /// @}
-
- /// Return the number of labels;
- mln_value(I) nlabels() const;
-
- /// Update bounding boxes information.
- void update_(const fun::i2v::array<mln_value(I)>& relabel_fun);
-
- /// Return the bounding box of the component \p label.
- const bbox_t& bbox(const mln_value(I)& label) const;
-
- /// Return the component bounding boxes.
- const util::array<bbox_t>& bboxes() const;
-
- /// Return the domain of the component with label \p label.
- p_if<mln_box(I),
- fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
- subdomain(const mln_value(I)& label) const;
};
@@ -204,7 +138,7 @@ namespace mln
// 'labeled_image<I>'.
template <typename I, typename J>
void init_(tag::image_t, labeled_image<I>& target,
- const labeled_image<J>& model);
+ const labeled_image<J>& model);
@@ -234,7 +168,7 @@ namespace mln
template <typename I>
inline
data< labeled_image<I> >::data(const I& ima, const mln_value(I)& nlabels)
- : ima_(ima), nlabels_(nlabels)
+ : super_(ima, nlabels)
{
}
@@ -242,7 +176,7 @@ namespace mln
inline
data< labeled_image<I> >::data(const I& ima, const mln_value(I)& nlabels,
const util::array<mln_box(I)>& bboxes)
- : ima_(ima), nlabels_(nlabels), bboxes_(bboxes)
+ : super_(ima, nlabels, bboxes)
{
}
@@ -296,61 +230,6 @@ namespace mln
this->data_->bboxes_ = model.hook_data_()->bboxes_;
}
- template <typename I>
- template <typename F>
- inline
- void
- labeled_image<I>::relabel(const Function_v2v<F>& f_)
- {
- const F& f = exact(f_);
- mln_value(I) new_nlabels;
-
- fun::i2v::array<mln_value(I)>
- packed_relabel_fun = make::relabelfun(f,
- this->data_->nlabels_,
- new_nlabels);
-
- labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_,
- packed_relabel_fun);
-
- this->data_->nlabels_ = new_nlabels;
-
- /// We may have merged or deleted labels.
- update_(packed_relabel_fun);
- }
-
-
-
- template <typename I>
- template <typename F>
- inline
- void
- labeled_image<I>::relabel(const Function_v2b<F>& f_)
- {
- const F& f = exact(f_);
-
- // Relabel the underlying image.
- typedef fun::i2v::array<mln_value(I)> fv2v_t;
- fv2v_t fv2v = make::relabelfun(f,
- this->data_->nlabels_,
- this->data_->nlabels_);
-
- labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, fv2v);
-
-
- // Then, merge or delete bounding boxes according to this relabeling.
- update_(fv2v);
- }
-
- template <typename I>
- inline
- mln_value(I)
- labeled_image<I>::nlabels() const
- {
- return this->data_->nlabels_;
- }
-
-
// init_
template <typename I, typename J>
@@ -363,49 +242,6 @@ namespace mln
}
- template <typename I>
- void
- labeled_image<I>::update_(const fun::i2v::array<mln_value(I)>& relabel_fun)
- {
- util::array<accu::shape::bbox<mln_psite(I)> >
- new_bboxes(static_cast<unsigned>(this->data_->nlabels_) + 1);
-
- for (unsigned i = 1; i < this->data_->bboxes_.size(); ++i)
- if (relabel_fun(i) != 0)
- new_bboxes[relabel_fun(i)].take(this->data_->bboxes_[i]);
-
- convert::from_to(new_bboxes, this->data_->bboxes_);
-
- mln_assertion(new_bboxes.size() == this->data_->bboxes_.size());
- }
-
-
- template <typename I>
- const typename labeled_image<I>::bbox_t&
- labeled_image<I>::bbox(const mln_value(I)& label) const
- {
- return this->data_->bboxes_[label];
- }
-
-
- template <typename I>
- const util::array<typename labeled_image<I>::bbox_t>&
- labeled_image<I>::bboxes() const
- {
- return this->data_->bboxes_;
- }
-
-
- template <typename I>
- p_if<mln_box(I),
- fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
- labeled_image<I>::subdomain(const mln_value(I)& label) const
- {
- return ((this->data_->ima_ | bbox(label))
- | (pw::value(this->data_->ima_) == pw::cst(label))).domain();
- }
-
-
// Make routines.
namespace make
diff --git a/milena/mln/core/image/imorph/labeled_image.hh b/milena/mln/core/internal/labeled_image_base.hh
similarity index 52%
copy from milena/mln/core/image/imorph/labeled_image.hh
copy to milena/mln/core/internal/labeled_image_base.hh
index b0e5ffb..e79bb12 100644
--- a/milena/mln/core/image/imorph/labeled_image.hh
+++ b/milena/mln/core/internal/labeled_image_base.hh
@@ -23,25 +23,20 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH
-# define MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH
+#ifndef MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
+# define MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
/// \file
///
-/// \brief Definition of a morpher on a labeled image.
+/// \brief Definition of a base class for labeled image morphers.
# include <mln/core/image/dmorph/image_if.hh>
# include <mln/core/concept/function.hh>
# include <mln/core/internal/image_identity.hh>
# include <mln/core/site_set/box.hh>
-# include <mln/core/routine/duplicate.hh>
-# include <mln/accu/pair.hh>
-# include <mln/accu/nil.hh>
-# include <mln/accu/center.hh>
+# include <mln/accu/shape/bbox.hh>
-# include <mln/labeling/compute.hh>
-# include <mln/labeling/pack.hh>
# include <mln/labeling/relabel.hh>
# include <mln/util/array.hh>
@@ -49,35 +44,23 @@
# include <mln/pw/cst.hh>
# include <mln/pw/value.hh>
-# ifndef NDEBUG
-# include <mln/accu/stat/max.hh>
-# include <mln/data/compute.hh>
-# endif // ! NDEBUG
-
-
-# include <mln/accu/shape/bbox.hh>
-# include <mln/labeling/relabel.hh>
# include <mln/make/relabelfun.hh>
namespace mln
{
- // Forward declarations.
- template <typename I> struct labeled_image;
- namespace accu
- {
- template <typename T> struct nil;
- template <typename T> struct bbox;
- }
+ // Forward declaration.
+ template <typename I, typename E>
+ class labeled_image_base;
namespace internal
{
- /// Data structure for \c mln::labeled_image<I>.
- template <typename I>
- struct data< labeled_image<I> >
+ /// Data structure for \c mln::labeled_image_base<I,E>.
+ template <typename I, typename E>
+ struct data< labeled_image_base<I,E> >
{
data(const I& ima, const mln_value(I)& nlabels);
data(const I& ima, const mln_value(I)& nlabels,
@@ -91,11 +74,12 @@ namespace mln
} // end of namespace mln::internal
+
namespace trait
{
- template <typename I>
- struct image_< labeled_image<I> > : image_< I > // Same as I except...
+ template <typename I, typename E>
+ struct image_< labeled_image_base<I,E> > : image_< I > // Same as I except...
{
// ...these changes.
typedef trait::image::category::identity_morpher category;
@@ -114,54 +98,35 @@ namespace mln
- /// Morpher providing an improved interface for labeled image.
- ///
- /// \tparam I The label image type.
- ///
- /// This image type allows to access every site set at a given
- /// label.
- ///
- /// This image type guaranties that labels are contiguous (from 1 to
- /// n).
- ///
- /// \ingroup modimageidmorpher
- //
- template <typename I>
- class labeled_image
- : public internal::image_identity< const I, mln_domain(I), labeled_image<I> >
+ /*! \brief Base class Morpher providing an improved interface for
+ labeled image.
+
+ \tparam I The label image type.
+
+ This image type allows to access every site set at a given
+ label.
+
+ This image type guaranties that labels are contiguous (from 1 to
+ n).
+
+ */
+ template <typename I, typename E>
+ class labeled_image_base
+ : public internal::image_identity< const I, mln_domain(I), E >
{
- typedef internal::image_identity< const I, mln_domain(I), labeled_image<I> >
+ typedef internal::image_identity< const I, mln_domain(I), E >
super_;
public:
-
- /// Skeleton.
- typedef labeled_image< tag::image_<I> > skeleton;
-
/// Type of the bounding component bounding boxes.
typedef mln_result(accu::shape::bbox<mln_psite(I)>) bbox_t;
/// Constructors
/// @{
/// Constructor without argument.
- labeled_image();
-
- /// Constructor from an image \p ima and the number of labels \p nlabels.
- labeled_image(const I& ima, const mln_value(I)& nlabels);
-
- /// Constructor from an image \p ima, the number of labels \p
- /// nlabels and the object bounding boxes.
- labeled_image(const I& ima, const mln_value(I)& nlabels,
- const util::array<mln_box(I)>& bboxes);
+ labeled_image_base();
/// @}
- /// Deferred initialization from a labeled image \p ima and the number
- /// of labels \p nlabels.
- void init_(const I& ima, const mln_value(I)& nlabels);
-
- /// Duplicate the underlying image and create a new labeled_image.
- void init_from_(const labeled_image<I>& model);
-
/// Relabel according to a function.
/// @{
//
@@ -182,9 +147,6 @@ namespace mln
/// Return the number of labels;
mln_value(I) nlabels() const;
- /// Update bounding boxes information.
- void update_(const fun::i2v::array<mln_value(I)>& relabel_fun);
-
/// Return the bounding box of the component \p label.
const bbox_t& bbox(const mln_value(I)& label) const;
@@ -195,27 +157,19 @@ namespace mln
p_if<mln_box(I),
fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
subdomain(const mln_value(I)& label) const;
- };
-
-
- // init_
-
- //FIXME: not enough generic? We would like 'J' instead of
- // 'labeled_image<I>'.
- template <typename I, typename J>
- void init_(tag::image_t, labeled_image<I>& target,
- const labeled_image<J>& model);
-
+ protected:
+ /// Update bounding boxes information.
+ void update_data(const fun::i2v::array<mln_value(I)>& relabel_fun);
- namespace make
- {
+ template <typename F>
+ void relabel_(const Function_v2v<F>& f);
- template <typename I>
- mln::labeled_image<I>
- labeled_image(const Image<I>& ima, const mln_value(I)& nlabels);
+ template <typename F>
+ void relabel_(const Function_v2b<F>& f);
- } // end of namespace mln::make
+ void update_data_(const fun::i2v::array<mln_value(I)>& relabel_fun);
+ };
@@ -223,24 +177,24 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
- // internal::data< labeled_image<I> >
+ // internal::data< labeled_image_base<I,E> >
namespace internal
{
- // data< labeled_image<I> >
+ // data< labeled_image_base<I,E> >
- template <typename I>
+ template <typename I, typename E>
inline
- data< labeled_image<I> >::data(const I& ima, const mln_value(I)& nlabels)
+ data< labeled_image_base<I,E> >::data(const I& ima, const mln_value(I)& nlabels)
: ima_(ima), nlabels_(nlabels)
{
}
- template <typename I>
+ template <typename I, typename E>
inline
- data< labeled_image<I> >::data(const I& ima, const mln_value(I)& nlabels,
+ data< labeled_image_base<I,E> >::data(const I& ima, const mln_value(I)& nlabels,
const util::array<mln_box(I)>& bboxes)
: ima_(ima), nlabels_(nlabels), bboxes_(bboxes)
{
@@ -250,57 +204,18 @@ namespace mln
} // end of namespace mln::internal
- template <typename I>
+ template <typename I, typename E>
inline
- labeled_image<I>::labeled_image()
+ labeled_image_base<I,E>::labeled_image_base()
{
}
- template <typename I>
- inline
- labeled_image<I>::labeled_image(const I& ima, const mln_value(I)& nlabels)
- {
- init_(ima, nlabels);
- }
- template <typename I>
- inline
- labeled_image<I>::labeled_image(const I& ima, const mln_value(I)& nlabels,
- const util::array<mln_box(I)>& bboxes)
- {
- mln_precondition(data::compute(accu::meta::stat::max(), ima) == nlabels);
- this->data_ = new internal::data< labeled_image<I> >(ima, nlabels, bboxes);
- }
-
-
- template <typename I>
- inline
- void
- labeled_image<I>::init_(const I& ima, const mln_value(I)& nlabels)
- {
- mln_precondition(data::compute(accu::meta::stat::max(), ima) == nlabels);
- this->data_ = new internal::data< labeled_image<I> >(ima, nlabels);
- this->data_->bboxes_ = labeling::compute(accu::meta::shape::bbox(),
- this->data_->ima_,
- this->data_->nlabels_);
- }
-
- template <typename I>
- inline
- void
- labeled_image<I>::init_from_(const labeled_image<I>& model)
- {
- this->data_
- = new internal::data< labeled_image<I> >(duplicate(model.hook_data_()->ima_),
- model.nlabels());
- this->data_->bboxes_ = model.hook_data_()->bboxes_;
- }
-
- template <typename I>
+ template <typename I, typename E>
template <typename F>
inline
void
- labeled_image<I>::relabel(const Function_v2v<F>& f_)
+ labeled_image_base<I,E>::relabel(const Function_v2v<F>& f_)
{
const F& f = exact(f_);
mln_value(I) new_nlabels;
@@ -315,17 +230,18 @@ namespace mln
this->data_->nlabels_ = new_nlabels;
+ exact(this)->relabel_(f);
+
/// We may have merged or deleted labels.
- update_(packed_relabel_fun);
+ update_data(packed_relabel_fun);
}
-
- template <typename I>
+ template <typename I, typename E>
template <typename F>
inline
void
- labeled_image<I>::relabel(const Function_v2b<F>& f_)
+ labeled_image_base<I,E>::relabel(const Function_v2b<F>& f_)
{
const F& f = exact(f_);
@@ -337,35 +253,24 @@ namespace mln
labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, fv2v);
+ exact(this)->relabel_(f);
// Then, merge or delete bounding boxes according to this relabeling.
- update_(fv2v);
+ update_data(fv2v);
}
- template <typename I>
+ template <typename I, typename E>
inline
mln_value(I)
- labeled_image<I>::nlabels() const
+ labeled_image_base<I,E>::nlabels() const
{
return this->data_->nlabels_;
}
- // init_
-
- template <typename I, typename J>
- void init_(tag::image_t, labeled_image<I>& target,
- const labeled_image<J>& model)
- {
- I ima;
- init_(tag::image, ima, model);
- target.init_(ima, model.nlabels());
- }
-
-
- template <typename I>
+ template <typename I, typename E>
void
- labeled_image<I>::update_(const fun::i2v::array<mln_value(I)>& relabel_fun)
+ labeled_image_base<I,E>::update_data(const fun::i2v::array<mln_value(I)>& relabel_fun)
{
util::array<accu::shape::bbox<mln_psite(I)> >
new_bboxes(static_cast<unsigned>(this->data_->nlabels_) + 1);
@@ -377,55 +282,68 @@ namespace mln
convert::from_to(new_bboxes, this->data_->bboxes_);
mln_assertion(new_bboxes.size() == this->data_->bboxes_.size());
+
+ exact(this)->update_data_(relabel_fun);
}
- template <typename I>
- const typename labeled_image<I>::bbox_t&
- labeled_image<I>::bbox(const mln_value(I)& label) const
+ template <typename I, typename E>
+ const typename labeled_image_base<I,E>::bbox_t&
+ labeled_image_base<I,E>::bbox(const mln_value(I)& label) const
{
return this->data_->bboxes_[label];
}
- template <typename I>
- const util::array<typename labeled_image<I>::bbox_t>&
- labeled_image<I>::bboxes() const
+ template <typename I, typename E>
+ const util::array<typename labeled_image_base<I,E>::bbox_t>&
+ labeled_image_base<I,E>::bboxes() const
{
return this->data_->bboxes_;
}
- template <typename I>
+ template <typename I, typename E>
p_if<mln_box(I),
fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
- labeled_image<I>::subdomain(const mln_value(I)& label) const
+ labeled_image_base<I,E>::subdomain(const mln_value(I)& label) const
{
return ((this->data_->ima_ | bbox(label))
| (pw::value(this->data_->ima_) == pw::cst(label))).domain();
}
- // Make routines.
- namespace make
+ template <typename I, typename E>
+ template <typename F>
+ void
+ labeled_image_base<I,E>::relabel_(const Function_v2v<F>& f)
{
+ (void) f;
+ // No-Op.
+ }
- template <typename I>
- mln::labeled_image<I>
- labeled_image(const Image<I>& ima, const mln_value(I)& nlabels)
- {
- mln_precondition(exact(ima).is_valid());
- mln::labeled_image<I> tmp(exact(ima), nlabels);
- return tmp;
- }
-
- } // end of namespace mln::make
+ template <typename I, typename E>
+ template <typename F>
+ void
+ labeled_image_base<I,E>::relabel_(const Function_v2b<F>& f)
+ {
+ (void) f;
+ // No-Op.
+ }
+ template <typename I, typename E>
+ void
+ labeled_image_base<I,E>::update_data_(
+ const fun::i2v::array<mln_value(I)>& relabel_fun)
+ {
+ (void) relabel_fun;
+ // No-Op.
+ }
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
-#endif // ! MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH
+#endif // ! MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
--
1.5.6.5
1
0
* mln/core/box_runend_piter.hh,
* mln/core/box_runstart_piter.hh: use mln_psite_ in macros
dedicated for non templated functions.
---
milena/ChangeLog | 8 ++++++++
milena/mln/core/box_runend_piter.hh | 2 +-
milena/mln/core/box_runstart_piter.hh | 2 +-
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 9812f96..811c23e 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,13 @@
2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix invalid macros.
+
+ * mln/core/box_runend_piter.hh,
+ * mln/core/box_runstart_piter.hh: use mln_psite_ in macros
+ dedicated for non templated functions.
+
+2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Remove useless traces.
* mln/geom/bbox.hh,
diff --git a/milena/mln/core/box_runend_piter.hh b/milena/mln/core/box_runend_piter.hh
index a0b1d32..e40760f 100644
--- a/milena/mln/core/box_runend_piter.hh
+++ b/milena/mln/core/box_runend_piter.hh
@@ -35,7 +35,7 @@
#define mln_box_runend_piter(I) typename mln::box_runend_piter<mln_psite(I)>
-#define mln_box_runend_piter_(I) mln::box_runend_piter<mln_psite(I)>
+#define mln_box_runend_piter_(I) mln::box_runend_piter<mln_psite_(I)>
namespace mln
diff --git a/milena/mln/core/box_runstart_piter.hh b/milena/mln/core/box_runstart_piter.hh
index a777d1e..fafcc46 100644
--- a/milena/mln/core/box_runstart_piter.hh
+++ b/milena/mln/core/box_runstart_piter.hh
@@ -35,7 +35,7 @@
#define mln_box_runstart_piter(I) typename mln::box_runstart_piter<mln_psite(I)>
-#define mln_box_runstart_piter_(I) mln::box_runstart_piter<mln_psite(I)>
+#define mln_box_runstart_piter_(I) mln::box_runstart_piter<mln_psite_(I)>
namespace mln
--
1.5.6.5
1
0
* mln/geom/bbox.hh,
* mln/geom/max_col.hh,
* mln/geom/max_row.hh,
* mln/geom/max_sli.hh,
* mln/geom/min_col.hh,
* mln/geom/min_row.hh,
* mln/geom/min_sli.hh,
* mln/geom/ncols.hh,
* mln/geom/nrows.hh,
* mln/geom/nslis.hh: Remove useless traces.
---
milena/ChangeLog | 15 +++++++++++++++
milena/mln/geom/bbox.hh | 16 +++-------------
milena/mln/geom/max_col.hh | 9 ++-------
milena/mln/geom/max_row.hh | 9 ++-------
milena/mln/geom/max_sli.hh | 6 ++----
milena/mln/geom/min_col.hh | 9 ++-------
milena/mln/geom/min_row.hh | 9 ++-------
milena/mln/geom/min_sli.hh | 6 ++----
milena/mln/geom/ncols.hh | 9 ++-------
milena/mln/geom/nrows.hh | 9 ++-------
milena/mln/geom/nslis.hh | 6 ++----
11 files changed, 36 insertions(+), 67 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 1e97d05..9812f96 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,20 @@
2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Remove useless traces.
+
+ * mln/geom/bbox.hh,
+ * mln/geom/max_col.hh,
+ * mln/geom/max_row.hh,
+ * mln/geom/max_sli.hh,
+ * mln/geom/min_col.hh,
+ * mln/geom/min_row.hh,
+ * mln/geom/min_sli.hh,
+ * mln/geom/ncols.hh,
+ * mln/geom/nrows.hh,
+ * mln/geom/nslis.hh: Remove useless traces.
+
+2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Improve influence zone geodesic.
* mln/canvas/distance_geodesic.hh: Remove useless traces.
diff --git a/milena/mln/geom/bbox.hh b/milena/mln/geom/bbox.hh
index 0ec374a..2a727e0 100644
--- a/milena/mln/geom/bbox.hh
+++ b/milena/mln/geom/bbox.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -34,7 +35,7 @@
* \todo Re-activate precondition so introduce
* "set::nsites(Site_Set)"...
*
- * \todo Add a static check "domain is ok for bbox (like grid)".
+ * \todo Add a static check "domain is ok for bbox (like grid)".
*
* \todo Add the weighted_window case.
*/
@@ -120,34 +121,27 @@ namespace mln
inline
box<mln_site(S)> bbox(const Site_Set<S>& pset)
{
- trace::entering("geom::bbox");
// mln_precondition(set::is_empty(pset) != 0);
box<mln_site(S)> b = impl::bbox_(mln_trait_site_set_bbox(S)(),
exact(pset));
- trace::exiting("geom::bbox");
return b;
}
template <typename I>
box<mln_site(I)> bbox(const Image<I>& ima_)
{
- trace::entering("geom::bbox");
-
const I& ima = exact(ima_);
mln_precondition(ima.is_valid());
box<mln_site(I)> b = geom::bbox(ima.domain());
- trace::exiting("geom::bbox");
return b;
}
template <typename W>
box<mln_psite(W)> bbox(const Window<W>& win)
{
- trace::entering("geom::bbox");
-
typedef mln_psite(W) P;
accu::shape::bbox<P> b;
P O = literal::origin;
@@ -155,18 +149,14 @@ namespace mln
for_all(q)
b.take(q);
- trace::exiting("geom::bbox");
return b;
}
template <typename W>
box<mln_psite(W)> bbox(const Weighted_Window<W>& win)
{
- trace::entering("geom::bbox");
-
box<mln_psite(W)> b = bbox(exact(win).win());
- trace::exiting("geom::bbox");
return b;
}
diff --git a/milena/mln/geom/max_col.hh b/milena/mln/geom/max_col.hh
index 7e600ce..36eb213 100644
--- a/milena/mln/geom/max_col.hh
+++ b/milena/mln/geom/max_col.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -54,12 +55,9 @@ namespace mln
inline
mln_deduce(I, site, coord) max_col(const Image<I>& ima)
{
- trace::entering("mln::geom::max_col");
-
mln_precondition(exact(ima).is_valid());
mln_deduce(I, site, coord) maxcol = geom::bbox(ima).pmax().col();
- trace::exiting("mln::geom::max_col");
return maxcol;
}
@@ -68,12 +66,9 @@ namespace mln
inline
mln_deduce(B, point, coord) max_col(const Box<B>& b)
{
- trace::entering("mln::geom::max_col");
-
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
mln_deduce(B, point, coord) maxcol = exact(b).pmax().col();
- trace::exiting("mln::geom::max_col");
return maxcol;
}
diff --git a/milena/mln/geom/max_row.hh b/milena/mln/geom/max_row.hh
index 04689e8..6519906 100644
--- a/milena/mln/geom/max_row.hh
+++ b/milena/mln/geom/max_row.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -55,12 +56,9 @@ namespace mln
inline
mln_deduce(I, site, coord) max_row(const Image<I>& ima)
{
- trace::entering("mln::geom::max_row");
-
mln_precondition(exact(ima).is_valid());
mln_deduce(I, site, coord) maxrow = geom::bbox(ima).pmax().row();
- trace::exiting("mln::geom::max_row");
return maxrow;
}
@@ -69,12 +67,9 @@ namespace mln
inline
mln_deduce(B, point, coord) max_row(const Box<B>& b)
{
- trace::entering("mln::geom::max_row");
-
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
mln_deduce(B, point, coord) maxrow = exact(b).pmax().row();
- trace::exiting("mln::geom::max_row");
return maxrow;
}
diff --git a/milena/mln/geom/max_sli.hh b/milena/mln/geom/max_sli.hh
index b0c541c..cf4fc51 100644
--- a/milena/mln/geom/max_sli.hh
+++ b/milena/mln/geom/max_sli.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -51,12 +52,9 @@ namespace mln
inline
mln_deduce(I, site, coord) max_sli(const Image<I>& ima)
{
- trace::entering("mln::geom::max_sli");
-
mln_precondition(exact(ima).is_valid());
mln_deduce(I, site, coord) maxsli = geom::bbox(ima).pmax().sli();
- trace::exiting("mln::geom::max_sli");
return maxsli;
}
diff --git a/milena/mln/geom/min_col.hh b/milena/mln/geom/min_col.hh
index 2cdc052..373237e 100644
--- a/milena/mln/geom/min_col.hh
+++ b/milena/mln/geom/min_col.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -55,12 +56,9 @@ namespace mln
inline
mln_deduce(I, site, coord) min_col(const Image<I>& ima)
{
- trace::entering("mln::geom::min_col");
-
mln_precondition(exact(ima).is_valid());
mln_deduce(I, site, coord) mincol = geom::bbox(ima).pmin().col();
- trace::exiting("mln::geom::min_col");
return mincol;
}
@@ -69,12 +67,9 @@ namespace mln
inline
mln_deduce(B, point, coord) min_col(const Box<B>& b)
{
- trace::entering("mln::geom::min_col");
-
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
mln_deduce(B, point, coord) mincol = exact(b).pmin().col();
- trace::exiting("mln::geom::min_col");
return mincol;
}
diff --git a/milena/mln/geom/min_row.hh b/milena/mln/geom/min_row.hh
index ad8c8b7..ec833c3 100644
--- a/milena/mln/geom/min_row.hh
+++ b/milena/mln/geom/min_row.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -58,12 +59,9 @@ namespace mln
inline
mln_deduce(I, site, coord) min_row(const Image<I>& ima)
{
- trace::entering("mln::geom::min_row");
-
mln_precondition(exact(ima).is_valid());
mln_deduce(I, site, coord) minrow = geom::bbox(ima).pmin().row();
- trace::exiting("mln::geom::min_row");
return minrow;
}
@@ -72,12 +70,9 @@ namespace mln
inline
mln_deduce(B, point, coord) min_row(const Box<B>& b)
{
- trace::entering("mln::geom::min_row");
-
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
mln_deduce(B, point, coord) minrow = exact(b).pmin().row();
- trace::exiting("mln::geom::min_row");
return minrow;
}
diff --git a/milena/mln/geom/min_sli.hh b/milena/mln/geom/min_sli.hh
index 7b07a8c..87d6571 100644
--- a/milena/mln/geom/min_sli.hh
+++ b/milena/mln/geom/min_sli.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -51,12 +52,9 @@ namespace mln
inline
mln_deduce(I, site, coord) min_sli(const Image<I>& ima)
{
- trace::entering("mln::geom::min_sli");
-
mln_precondition(exact(ima).is_valid());
mln_deduce(I, site, coord) minsli = geom::bbox(ima).pmin().sli();
- trace::exiting("mln::geom::min_sli");
return minsli;
}
diff --git a/milena/mln/geom/ncols.hh b/milena/mln/geom/ncols.hh
index 4e062ce..bc4a09b 100644
--- a/milena/mln/geom/ncols.hh
+++ b/milena/mln/geom/ncols.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -55,12 +56,9 @@ namespace mln
inline
unsigned ncols(const Image<I>& ima)
{
- trace::entering("mln::geom::ncols");
-
mln_precondition(exact(ima).is_valid());
unsigned ncols = geom::max_col(ima) - geom::min_col(ima) + 1;
- trace::exiting("mln::geom::ncols");
return ncols;
}
@@ -68,12 +66,9 @@ namespace mln
template <typename B>
unsigned ncols(const Box<B>& b)
{
- trace::entering("mln::geom::ncols");
-
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
unsigned ncols = geom::max_col(b) - geom::min_col(b) + 1;
- trace::exiting("mln::geom::ncols");
return ncols;
}
diff --git a/milena/mln/geom/nrows.hh b/milena/mln/geom/nrows.hh
index b7892c8..040ca57 100644
--- a/milena/mln/geom/nrows.hh
+++ b/milena/mln/geom/nrows.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -55,24 +56,18 @@ namespace mln
inline
unsigned nrows(const Image<I>& ima)
{
- trace::entering("mln::geom::nrows");
-
mln_precondition(exact(ima).is_valid());
unsigned nrows = geom::max_row(ima) - geom::min_row(ima) + 1;
- trace::exiting("mln::geom::nrows");
return nrows;
}
template <typename B>
unsigned nrows(const Box<B>& b)
{
- trace::entering("mln::geom::nrows");
-
metal::not_<metal::equal<metal::int_<B::dim>, metal::int_<1> > >::check();
unsigned nrows = geom::max_row(b) - geom::min_row(b) + 1;
- trace::exiting("mln::geom::nrows");
return nrows;
}
diff --git a/milena/mln/geom/nslis.hh b/milena/mln/geom/nslis.hh
index 42c1899..d6953da 100644
--- a/milena/mln/geom/nslis.hh
+++ b/milena/mln/geom/nslis.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -51,12 +52,9 @@ namespace mln
inline
unsigned nslis(const Image<I>& ima)
{
- trace::entering("mln::geom::nslis");
-
mln_precondition(exact(ima).is_valid());
unsigned nslis = geom::max_sli(ima) - geom::min_sli(ima) + 1;
- trace::exiting("mln::geom::nslis");
return nslis;
}
--
1.5.6.5
1
0
* mln/canvas/distance_geodesic.hh: Remove useless traces.
* mln/transform/influence_zone_geodesic.hh: Add a specific fastest
version and move some code...
* mln/transform/influence_zone_geodesic_saturated.hh: ... here.
* tests/transform/influence_zone_geodesic.cc: Update test
according to the new interface.
* tests/transform/Makefile.am,
* tests/transform/influence_zone_geodesic_saturated.cc: New test.
---
milena/ChangeLog | 17 ++
milena/mln/canvas/distance_geodesic.hh | 56 +++---
milena/mln/transform/influence_zone_geodesic.hh | 194 ++++++++++++++++----
...sic.hh => influence_zone_geodesic_saturated.hh} | 52 ++---
milena/tests/transform/Makefile.am | 6 +-
milena/tests/transform/influence_zone_geodesic.cc | 4 +-
...sic.cc => influence_zone_geodesic_saturated.cc} | 6 +-
7 files changed, 232 insertions(+), 103 deletions(-)
copy milena/mln/transform/{influence_zone_geodesic.hh => influence_zone_geodesic_saturated.hh} (65%)
copy milena/tests/transform/{influence_zone_geodesic.cc => influence_zone_geodesic_saturated.cc} (90%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index f835a42..1e97d05 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,20 @@
+2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Improve influence zone geodesic.
+
+ * mln/canvas/distance_geodesic.hh: Remove useless traces.
+
+ * mln/transform/influence_zone_geodesic.hh: Add a specific fastest
+ version and move some code...
+
+ * mln/transform/influence_zone_geodesic_saturated.hh: ... here.
+
+ * tests/transform/influence_zone_geodesic.cc: Update test
+ according to the new interface.
+
+ * tests/transform/Makefile.am,
+ * tests/transform/influence_zone_geodesic_saturated.cc: New test.
+
2009-11-09 Guillaume Lazzara <z(a)lrde.epita.fr>
Add box_runend_piter.
diff --git a/milena/mln/canvas/distance_geodesic.hh b/milena/mln/canvas/distance_geodesic.hh
index 813e8fc..e833f08 100644
--- a/milena/mln/canvas/distance_geodesic.hh
+++ b/milena/mln/canvas/distance_geodesic.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -51,8 +52,8 @@ namespace mln
template <typename I, typename N, typename D,
typename F>
mln_ch_value(I, D)
- distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh, D max,
- F& functor);
+ distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
+ D max, F& functor);
@@ -67,7 +68,8 @@ namespace mln
template <typename I, typename N, typename D,
typename F>
void
- distance_geodesic_tests(const Image<I>& input_, const Neighborhood<N>& nbh_, D max,
+ distance_geodesic_tests(const Image<I>& input_,
+ const Neighborhood<N>& nbh_, D max,
F& functor)
{
const I& input = exact(input_);
@@ -98,8 +100,8 @@ namespace mln
template <typename I, typename N, typename D,
typename F>
mln_ch_value(I, D)
- distance_geodesic(const Image<I>& input_, const Neighborhood<N>& nbh_, D max,
- F& functor)
+ distance_geodesic(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ D max, F& functor)
{
trace::entering("canvas::impl::generic::distance_geodesic");
@@ -119,8 +121,6 @@ namespace mln
// Initialization.
{
- trace::entering("initialization");
-
functor.init(input); // <-- init
data::fill(dmap, max);
@@ -139,12 +139,10 @@ namespace mln
break;
}
}
- trace::exiting("initialization");
}
// Propagation.
{
- trace::entering("propagation");
P p;
mln_niter(N) n(nbh, p);
while (! q.is_empty())
@@ -164,7 +162,6 @@ namespace mln
q.push(n);
}
}
- trace::exiting("propagation");
}
trace::exiting("canvas::impl::generic::distance_geodesic");
@@ -180,8 +177,10 @@ namespace mln
template <typename I, typename N, typename D,
typename F>
mln_ch_value(I, D)
- distance_geodesic_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, D max,
- F& functor)
+ distance_geodesic_fastest(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ D max,
+ F& functor)
{
trace::entering("canvas::impl::distance_geodesic_fastest");
@@ -199,8 +198,6 @@ namespace mln
// Initialization.
{
- trace::entering("initialization");
-
functor.init_(input); // <-- init
data::fill(dmap, max);
// For the extension to be ignored:
@@ -221,13 +218,10 @@ namespace mln
break;
}
}
-
- trace::exiting("initialization");
}
// Propagation.
{
- trace::entering("propagation");
unsigned p;
util::array<int> dp = offsets_wrt(input, nbh);
@@ -251,9 +245,8 @@ namespace mln
}
}
}
- trace::exiting("propagation");
}
-
+
trace::exiting("canvas::impl::distance_geodesic_fastest");
return dmap;
}
@@ -272,9 +265,10 @@ namespace mln
typename F>
inline
mln_ch_value(I, D)
- distance_geodesic_dispatch(metal::false_,
- const Image<I>& input, const Neighborhood<N>& nbh, D max,
- F& functor)
+ distance_geodesic_dispatch(metal::false_,
+ const Image<I>& input,
+ const Neighborhood<N>& nbh, D max,
+ F& functor)
{
return impl::generic::distance_geodesic(input, nbh, max,
functor);
@@ -284,9 +278,10 @@ namespace mln
typename F>
inline
mln_ch_value(I, D)
- distance_geodesic_dispatch(metal::true_,
- const Image<I>& input, const Neighborhood<N>& nbh, D max,
- F& functor)
+ distance_geodesic_dispatch(metal::true_,
+ const Image<I>& input,
+ const Neighborhood<N>& nbh, D max,
+ F& functor)
{
return impl::distance_geodesic_fastest(input, nbh, max, functor);
// return impl::generic::distance_geodesic(input, nbh, max,
@@ -297,8 +292,9 @@ namespace mln
typename F>
inline
mln_ch_value(I, D)
- distance_geodesic_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, D max,
- F& functor)
+ distance_geodesic_dispatch(const Image<I>& input,
+ const Neighborhood<N>& nbh, D max,
+ F& functor)
{
enum {
test = mlc_equal(mln_trait_image_speed(I),
@@ -322,8 +318,8 @@ namespace mln
typename F>
inline
mln_ch_value(I, D)
- distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh, D max,
- F& functor)
+ distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
+ D max, F& functor)
{
trace::entering("canvas::distance_geodesic");
diff --git a/milena/mln/transform/influence_zone_geodesic.hh b/milena/mln/transform/influence_zone_geodesic.hh
index f500bcf..4d7255a 100644
--- a/milena/mln/transform/influence_zone_geodesic.hh
+++ b/milena/mln/transform/influence_zone_geodesic.hh
@@ -30,6 +30,7 @@
///
/// Geodesic influence zone transform.
+# include <mln/extension/adjust.hh>
# include <mln/canvas/distance_geodesic.hh>
# include <mln/transform/internal/influence_zone_functor.hh>
@@ -44,26 +45,9 @@ namespace mln
///
/// \param[in] input An image.
/// \param[in] nbh A neighborhood.
- /// \param[in] max The maximum influence zone distance.
- /// \param[in] background_value The value used as background (i.e.
- /// not propagated).
///
/// \return An image of influence zone.
//
- template <typename I, typename N, typename D>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input,
- const Neighborhood<N>& nbh,
- const D& max, const mln_value(I)& background_value);
-
- /// \overload
- template <typename I, typename N, typename D>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input,
- const Neighborhood<N>& nbh, const D& max);
-
-
- /// \overload
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh);
@@ -73,38 +57,176 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename D>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
- const D& max, const mln_value(I)& background_value)
+ namespace internal
{
- trace::entering("transform::influence_zone_geodesic");
- mln_precondition(exact(input).is_valid());
- mln_precondition(exact(nbh).is_valid());
+ template <typename I, typename N>
+ void
+ influence_zone_geodesic_tests(const Image<I>& input,
+ const Neighborhood<N>& nbh)
+ {
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(nbh).is_valid());
- internal::influence_zone_functor<I> f(background_value);
- (void) mln::canvas::distance_geodesic(input, nbh, max, f);
+ (void) input;
+ (void) nbh;
+ }
- trace::exiting("transform::influence_zone_geodesic");
- return f.output;
- }
+ } // end of namespace mln::transform::internal
- template <typename I, typename N, typename D>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
- const D& max)
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ influence_zone_geodesic(const Image<I>& input,
+ const Neighborhood<N>& nbh)
+ {
+ // FIXME: To be written...
+ mlc_abort(I)::check();
+ }
+
+ } // end of namespace mln::transform::impl::generic
+
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ influence_zone_geodesic_fastest(const Image<I>& input_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("transform::impl::influence_zone_geodesic_fastest");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ internal::influence_zone_geodesic_tests(input, nbh);
+ mln_precondition(input.domain().pmin() == literal::origin);
+
+ std::queue<mln_value(I)*> q;
+ mln_concrete(I) output;
+
+ util::array<int> dp = offsets_wrt(input, nbh);
+ const unsigned n_nbhs = dp.nelements();
+ const unsigned
+ ncols = input.ncols(),
+ first_offset = input.border() * (ncols + 2 * input.border() + 1);
+
+ // Initialization.
+ {
+ extension::adjust(input, nbh);
+ output = duplicate(input);
+ // For the extension to be ignored:
+ extension::fill(input, 0); // in initialization
+ extension::fill(output, 1); // in propagation
+
+ const unsigned nelts = input.nelements();
+ const mln_value(I)* p_i = & input.at_(0, 0);
+ mln_value(I)* p_o = & output.at_(0, 0);
+ for (unsigned i = first_offset; i < nelts; ++i, ++p_i, ++p_o)
+ {
+ if (*p_i == 0)
+ continue;
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ const mln_value(I)* n_i = p_i + dp[j];
+ if (*n_i == 0)
+ {
+ q.push(p_o);
+ break;
+ }
+ }
+ }
+
+ }
+
+ // Propagation.
+ {
+ mln_value(I)* ptr;
+
+ while (! q.empty())
+ {
+ ptr = q.front();
+ q.pop();
+ mln_invariant(*ptr != 0);
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ mln_value(I)* ntr = ptr + dp[j];
+ if (*ntr == 0)
+ {
+ *ntr = *ptr;
+ q.push(ntr);
+ }
+ }
+ }
+ }
+
+ trace::exiting("transform::impl::influence_zone_geodesic_fastest");
+ return output;
+ }
+
+
+ } // end of namespace mln::transform::impl
+
+
+ namespace internal
{
- return influence_zone_geodesic(input, nbh, max, literal::zero);
- }
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ influence_zone_geodesic_dispatch(trait::image::value_alignment::any,
+ trait::image::value_storage::any,
+ trait::image::value_access::any,
+ const I& input,
+ const N& nbh)
+ {
+ return impl::generic::influence_zone_geodesic(input, nbh);
+ }
+
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ influence_zone_geodesic_dispatch(trait::image::value_alignment::with_grid,
+ trait::image::value_storage::one_block,
+ trait::image::value_access::direct,
+ const I& input,
+ const N& nbh)
+ {
+ return impl::influence_zone_geodesic_fastest(input, nbh);
+ }
+
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ influence_zone_geodesic_dispatch(const Image<I>& input,
+ const Neighborhood<N>& nbh)
+ {
+ return
+ influence_zone_geodesic_dispatch(mln_trait_image_value_alignment(I)(),
+ mln_trait_image_value_storage(I)(),
+ mln_trait_image_value_access(I)(),
+ exact(input), exact(nbh));
+ }
+
+ } // end of namespace mln::transform::internal
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh)
{
- return influence_zone_geodesic(input, nbh, mln_max(unsigned));
+ trace::entering("transform::influence_zone_geodesic");
+
+ internal::influence_zone_geodesic_tests(input, nbh);
+
+ mln_concrete(I)
+ output = internal::influence_zone_geodesic_dispatch(input, nbh);
+
+ trace::exiting("transform::influence_zone_geodesic");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/transform/influence_zone_geodesic.hh b/milena/mln/transform/influence_zone_geodesic_saturated.hh
similarity index 65%
copy from milena/mln/transform/influence_zone_geodesic.hh
copy to milena/mln/transform/influence_zone_geodesic_saturated.hh
index f500bcf..5a29858 100644
--- a/milena/mln/transform/influence_zone_geodesic.hh
+++ b/milena/mln/transform/influence_zone_geodesic_saturated.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -23,8 +23,8 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
-# define MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
+#ifndef MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_SATURATED_HH
+# define MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_SATURATED_HH
/// \file
///
@@ -52,22 +52,17 @@ namespace mln
//
template <typename I, typename N, typename D>
mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input,
- const Neighborhood<N>& nbh,
- const D& max, const mln_value(I)& background_value);
+ influence_zone_geodesic_saturated(const Image<I>& input,
+ const Neighborhood<N>& nbh,
+ const D& max,
+ const mln_value(I)& background_value);
/// \overload
template <typename I, typename N, typename D>
mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input,
- const Neighborhood<N>& nbh, const D& max);
-
-
- /// \overload
- template <typename I, typename N>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh);
-
+ influence_zone_geodesic_saturated(const Image<I>& input,
+ const Neighborhood<N>& nbh,
+ const D& max);
# ifndef MLN_INCLUDE_ONLY
@@ -75,10 +70,12 @@ namespace mln
template <typename I, typename N, typename D>
mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
- const D& max, const mln_value(I)& background_value)
+ influence_zone_geodesic_saturated(const Image<I>& input,
+ const Neighborhood<N>& nbh,
+ const D& max,
+ const mln_value(I)& background_value)
{
- trace::entering("transform::influence_zone_geodesic");
+ trace::entering("transform::influence_zone_geodesic_saturated");
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
@@ -86,25 +83,18 @@ namespace mln
internal::influence_zone_functor<I> f(background_value);
(void) mln::canvas::distance_geodesic(input, nbh, max, f);
- trace::exiting("transform::influence_zone_geodesic");
+ trace::exiting("transform::influence_zone_geodesic_saturated");
return f.output;
}
template <typename I, typename N, typename D>
mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
- const D& max)
- {
- return influence_zone_geodesic(input, nbh, max, literal::zero);
- }
-
-
- template <typename I, typename N>
- mln_concrete(I)
- influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh)
+ influence_zone_geodesic_saturated(const Image<I>& input,
+ const Neighborhood<N>& nbh,
+ const D& max)
{
- return influence_zone_geodesic(input, nbh, mln_max(unsigned));
+ return influence_zone_geodesic_saturated(input, nbh, max, literal::zero);
}
# endif // ! MLN_INCLUDE_ONLY
@@ -114,4 +104,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
+#endif // ! MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_SATURATED_HH
diff --git a/milena/tests/transform/Makefile.am b/milena/tests/transform/Makefile.am
index 3cc36e8..07feb9b 100644
--- a/milena/tests/transform/Makefile.am
+++ b/milena/tests/transform/Makefile.am
@@ -25,15 +25,19 @@ check_PROGRAMS = \
distance_front \
distance_geodesic \
hough \
+ kht \
influence_zone_front \
- influence_zone_geodesic
+ influence_zone_geodesic \
+ influence_zone_geodesic_saturated
bench_closest_point_geodesic_SOURCES = bench_closest_point_geodesic.cc
distance_and_closest_point_geodesic_SOURCES = distance_and_closest_point_geodesic.cc
distance_front_SOURCES = distance_front.cc
distance_geodesic_SOURCES = distance_geodesic.cc
hough_SOURCES = hough.cc
+kht_SOURCES = kht.cc
influence_zone_front_SOURCES = influence_zone_front.cc
influence_zone_geodesic_SOURCES = influence_zone_geodesic.cc
+influence_zone_geodesic_saturated_SOURCES = influence_zone_geodesic_saturated.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/transform/influence_zone_geodesic.cc b/milena/tests/transform/influence_zone_geodesic.cc
index 56a4461..682c1e1 100644
--- a/milena/tests/transform/influence_zone_geodesic.cc
+++ b/milena/tests/transform/influence_zone_geodesic.cc
@@ -39,7 +39,7 @@ int main()
int_u8 vals[] =
{ 1, 1, 0, 0, 0, 0, 3,
- 1, 1, 1, 0, 0, 0, 0,
+ 1, 1, 1, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2, 0,
@@ -47,6 +47,6 @@ int main()
0, 0, 0, 0, 0, 0, 0 };
image2d<int_u8> input = make::image2d(vals);
- image2d<int_u8> output = transform::influence_zone_geodesic(input, c4(), int_u8(2));
+ image2d<int_u8> output = transform::influence_zone_geodesic(input, c4());
debug::println(output);
}
diff --git a/milena/tests/transform/influence_zone_geodesic.cc b/milena/tests/transform/influence_zone_geodesic_saturated.cc
similarity index 90%
copy from milena/tests/transform/influence_zone_geodesic.cc
copy to milena/tests/transform/influence_zone_geodesic_saturated.cc
index 56a4461..e925b59 100644
--- a/milena/tests/transform/influence_zone_geodesic.cc
+++ b/milena/tests/transform/influence_zone_geodesic_saturated.cc
@@ -29,7 +29,7 @@
#include <mln/make/image2d.hh>
#include <mln/debug/println.hh>
-#include <mln/transform/influence_zone_geodesic.hh>
+#include <mln/transform/influence_zone_geodesic_saturated.hh>
int main()
@@ -39,7 +39,7 @@ int main()
int_u8 vals[] =
{ 1, 1, 0, 0, 0, 0, 3,
- 1, 1, 1, 0, 0, 0, 0,
+ 1, 1, 1, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2, 0,
@@ -47,6 +47,6 @@ int main()
0, 0, 0, 0, 0, 0, 0 };
image2d<int_u8> input = make::image2d(vals);
- image2d<int_u8> output = transform::influence_zone_geodesic(input, c4(), int_u8(2));
+ image2d<int_u8> output = transform::influence_zone_geodesic_saturated(input, c4(), int_u8(2));
debug::println(output);
}
--
1.5.6.5
1
0
17 Nov '09
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add some bench + canvas + subsampling + browsing code.
* bench: New directory.
* bench/input_iz.pgm.gz: New.
* bench/fastest_statistical_tour_browsing.cc: New.
* bench/fastest_forall_p_browsing.cc: New.
* bench/iz.cc: New.
* bench/fastest_statistical_tour_nbh_browsing.cc: New.
* bench/z_sub_browsing: New.
* bench/z_sub_browsing/fast.cc: New.
* bench/z_sub_browsing/debase.hh: New.
* bench/z_sub_browsing/integral.hh: New.
* bench/z_sub_browsing/+inc: New.
* bench/z_sub_browsing/in.pgm.gz: New.
* bench/z_sub_browsing/debase.cc: New.
* bench/z_sub_browsing/integral.cc: New.
* bench/z_sub_browsing/README: New.
* theo/mln/morpho/canvas/lena_blurred.pgm.gz: New.
* theo/mln/morpho/canvas/lena.pgm.gz: New.
* theo/mln/morpho/canvas/g.pbm.gz: New.
* theo/mln/morpho/canvas/lena_min.pgm.gz: New.
* theo/mln/morpho/canvas/reconstruction_on_set.hh: Layout.
* theo/mln/morpho/canvas/f_and_g.pbm.gz: New.
* theo/mln/morpho/canvas/regminid.pbm.gz: New.
* theo/mln/morpho/canvas/one_domain.cc: New.
* theo/mln/subsampling: New directory.
* theo/mln/subsampling/sizes.cc: New.
* theo/mln/subsampling/debase.hh: New.
* theo/mln/subsampling/integral.hh: New.
* theo/mln/subsampling/in.pgm.gz: New.
* theo/mln/subsampling/debase.cc: New.
* theo/mln/subsampling/integral.cc: New.
* theo/mln/browsing: New directory.
* theo/mln/browsing/window_sliding.cc: New.
bench/fastest_forall_p_browsing.cc | 384 ++++++++++++++++
bench/fastest_statistical_tour_browsing.cc | 168 +++++++
bench/fastest_statistical_tour_nbh_browsing.cc | 186 ++++++++
bench/iz.cc | 386 ++++++++++++++++
bench/z_sub_browsing/README | 5
bench/z_sub_browsing/debase.cc | 23 +
bench/z_sub_browsing/debase.hh | 351 +++++++++++++++
bench/z_sub_browsing/fast.cc | 139 ++++++
bench/z_sub_browsing/integral.cc | 23 +
bench/z_sub_browsing/integral.hh | 165 +++++++
theo/mln/browsing/window_sliding.cc | 52 ++
theo/mln/morpho/canvas/one_domain.cc | 569 +++++++++++++++++++++++++
theo/mln/subsampling/debase.cc | 23 +
theo/mln/subsampling/debase.hh | 351 +++++++++++++++
theo/mln/subsampling/integral.cc | 38 +
theo/mln/subsampling/integral.hh | 295 ++++++++++++
theo/mln/subsampling/sizes.cc | 45 +
17 files changed, 3203 insertions(+)
Index: bench/input_iz.pgm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: bench/input_iz.pgm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: bench/fastest_statistical_tour_browsing.cc
--- bench/fastest_statistical_tour_browsing.cc (revision 0)
+++ bench/fastest_statistical_tour_browsing.cc (revision 0)
@@ -0,0 +1,168 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/pw/all.hh>
+#include <mln/data/compare.hh>
+#include <mln/debug/println.hh>
+#include <mln/util/timer.hh>
+
+
+
+# define loop(n) for (unsigned i = 0; i < n; ++i)
+
+
+
+namespace mln
+{
+
+
+ // test_
+
+ template <typename I>
+ void test_(const std::string& routine, float t, const I& ima, mln_value(I) n)
+ {
+ std::cout << routine << ' ' << t << std::endl;
+ if (ima != (pw::cst(n) | ima.domain()))
+ std::cerr << "bug in " << routine << '!' << std::endl;
+ }
+
+
+
+ // piter
+
+ template <typename I>
+ void piter_based(I& ima)
+ {
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ if ((p.row() + p.col()) % 2 == 0)
+ ++ima(p);
+ for_all(p)
+ if ((p.row() + p.col()) % 2 == 1)
+ ++ima(p);
+ }
+
+
+ // row_col
+
+ template <typename I>
+ void row_col_based(I& ima)
+ {
+ const unsigned nrows = ima.nrows(), ncols = ima.ncols();
+ for (int row = 0; row < nrows; ++row)
+ for (int col = row % 2; col < ncols; col += 2)
+ ++ima.at_(row, col);
+ for (int row = 0; row < nrows; ++row)
+ for (int col = ! (row % 2); col < ncols; col += 2)
+ ++ima.at_(row, col);
+ }
+
+
+ // run_ptr
+
+ template <typename I>
+ void run_ptr_based(I& ima)
+ {
+ mln_box_runstart_piter(I) s(ima.domain());
+ const unsigned n = s.run_length();
+
+ // half-tour 0
+ unsigned skip = 0;
+ for_all(s)
+ {
+ mln_value(I)* ptr = &ima(s) + skip;
+ for (unsigned i = 0; i < n; i += 2)
+ {
+ ++*ptr;
+ ptr += 2;
+ }
+ skip = ! skip;
+ }
+
+ // half-tour 1
+ skip = 1;
+ for_all(s)
+ {
+ mln_value(I)* ptr = &ima(s) + skip;
+ for (unsigned i = 0; i < n; i += 2)
+ {
+ ++*ptr;
+ ptr += 2;
+ }
+ skip = ! skip;
+ }
+ }
+
+
+} // end of namespace mln
+
+
+
+
+
+int main()
+{
+ using namespace mln;
+
+ const unsigned n = 10, size = 1000;
+ image2d<char> ima(size, size);
+ util::timer t;
+ std::string routine;
+
+
+ // piter
+
+ {
+ routine = "piter";
+ data::fill(ima, 0);
+ t.start();
+ loop(n) piter_based(ima);
+ test_(routine, t.stop(), ima, n);
+ }
+
+
+ // row_col
+
+ {
+ routine = "row_col";
+ data::fill(ima, 0);
+ t.start();
+ loop(n) row_col_based(ima);
+ test_(routine, t.stop(), ima, n);
+ }
+
+
+ // run_ptr
+
+ {
+ routine = "run_ptr";
+ data::fill(ima, 0);
+ t.start();
+ loop(n) run_ptr_based(ima);
+ test_(routine, t.stop(), ima, n);
+ }
+
+}
Index: bench/fastest_forall_p_browsing.cc
--- bench/fastest_forall_p_browsing.cc (revision 0)
+++ bench/fastest_forall_p_browsing.cc (revision 0)
@@ -0,0 +1,384 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/util/timer.hh>
+
+
+
+# define loop(n) for (unsigned i = 0; i < n; ++i)
+
+
+
+namespace mln
+{
+
+
+ // (r, c)
+
+ template <typename I>
+ void bench_00(I& ima)
+ {
+ const unsigned nr = ima.nrows(), nc = ima.ncols();
+ for (int r = 0; r < nr; ++r)
+ for (int c = 0; c < nc; ++c)
+ ima.at_(r, c) = 0;
+ }
+
+
+ // ptr
+
+ template <typename I>
+ void bench_0(I& ima)
+ {
+ const unsigned n = ima.nelements();
+ mln_value(I)* ptr = ima.buffer();
+ for (unsigned i = 0; i < n; ++i)
+ *ptr++ = 0;
+ }
+
+ template <typename I>
+ void bench_0(I& ima1, const I& ima2)
+ {
+ const unsigned n = ima1.nelements();
+ mln_value(I)* ptr1 = ima1.buffer();
+ const mln_value(I)* ptr2 = ima2.buffer();
+ for (unsigned i = 0; i < n; ++i)
+ *ptr1++ = *ptr2++;
+ }
+
+
+ // piter
+
+ template <typename I>
+ void bench_1(I& ima)
+ {
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ ima(p) = 0;
+ }
+
+
+ // pixter
+
+ template <typename I>
+ void bench_2(I& ima)
+ {
+ mln_fwd_pixter(I) pxl(ima);
+ for_all(pxl)
+ pxl.val() = 0;
+ }
+
+ template <typename I>
+ void bench_2(I& ima1, const I& ima2)
+ {
+ mln_fwd_pixter(I) pxl1(ima1);
+ mln_fwd_pixter(const I) pxl2(ima2);
+ for_all_2(pxl1, pxl2)
+ pxl1.val() = pxl2.val();
+ }
+
+
+ // pixter -> offset
+
+ template <typename I>
+ void bench_3(I& ima)
+ {
+ mln_fwd_pixter(I) pxl(ima);
+ for_all(pxl)
+ {
+ unsigned p = pxl.offset();
+ ima.element(p) = 0;
+ }
+ }
+
+ template <typename I>
+ void bench_3(I& ima1, const I& ima2)
+ {
+ // border::equalize(ima1, ima2);
+ mln_fwd_pixter(I) pxl(ima1);
+ for_all(pxl)
+ {
+ unsigned p = pxl.offset();
+ ima1.element(p) = ima2.element(p);
+ }
+ }
+
+
+ // pixter -> point
+
+ template <typename I>
+ void bench_4(I& ima)
+ {
+ mln_fwd_pixter(I) pxl(ima);
+ for_all(pxl)
+ {
+ unsigned o = pxl.offset();
+ mln_psite(I) p = ima.point_at_index(o);
+ ima(p) = 0;
+ }
+ }
+
+
+
+ // box_runstart_piter -> ptr
+
+ template <typename I>
+ void bench_5(I& ima)
+ {
+ mln_box_runstart_piter(I) s(ima.domain());
+ const unsigned n = s.run_length();
+ for_all(s)
+ {
+ mln_value(I)* ptr = & ima(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ *ptr++ = 0;
+ }
+ }
+ }
+
+
+ // box_runstart_piter -> (ptr, point)
+
+ template <typename I>
+ void bench_6(I& ima)
+ {
+ typedef mln_site(I) P;
+ const unsigned dim_1 = P::dim - 1;
+ mln_box_runstart_piter(I) s(ima.domain());
+ const unsigned n = s.run_length();
+ for_all(s)
+ {
+ mln_value(I)* ptr = & ima(s);
+ P p = s;
+ for (unsigned i = 0; i < n; ++i)
+ {
+ *ptr++ = 0;
+ ++p[dim_1];
+ }
+ }
+ }
+
+ template <typename I>
+ void bench_6(I& ima1, const I& ima2)
+ {
+ typedef mln_site(I) P;
+ const unsigned dim_1 = P::dim - 1;
+ mln_box_runstart_piter(I) s(ima1.domain());
+ const unsigned n = s.run_length();
+ for_all(s)
+ {
+ mln_value(I)* ptr1 = & ima1(s);
+ const mln_value(I)* ptr2 = & ima2(s);
+ P p = s;
+ for (unsigned i = 0; i < n; ++i)
+ {
+ *ptr1++ = *ptr2++;
+ ++p[dim_1];
+ }
+ }
+ }
+
+
+// template <typename I>
+// void bench_6_alt(I& ima1, const I& ima2)
+// {
+// typedef mln_site(I) P;
+// const unsigned dim_1 = P::dim - 1;
+// mln_fwd_by_run_piter(I) p(ima1.domain());
+// for_all(p)
+// {
+// if (p.at_runstart())
+// {
+// p.update(ptr1, ima1);
+// p.update(ptr2, ima2);
+// }
+// *ptr1++ = *ptr2++;
+// p; // converts to point2d
+// }
+// }
+
+
+
+ // box_runstart_piter -> (offset, point)
+
+ template <typename I>
+ void bench_7(I& ima)
+ {
+ typedef mln_site(I) P;
+ const unsigned dim_1 = P::dim - 1;
+ mln_box_runstart_piter(I) s(ima.domain());
+ const unsigned n = s.run_length();
+ for_all(s)
+ {
+ unsigned offset = ima.index_of_point(s);
+ P p = s;
+ for (unsigned i = 0; i < n; ++i)
+ {
+ ima.element(offset) = 0;
+ ++offset;
+ ++p[dim_1];
+ }
+ }
+ }
+
+
+
+} // end of namespace mln
+
+
+
+
+
+int main()
+{
+ using namespace mln;
+
+ const unsigned n = 100, size = 1000;
+ image2d<int> ima(size, size), ima2(size, size);
+ util::timer t;
+
+
+ // (r, c)
+
+ {
+ t.start();
+ loop(n) bench_00(ima);
+ float ts = t.stop();
+ std::cout << "(r, c) " << ts << std::endl;
+ }
+
+
+ // ptr
+
+ {
+ t.start();
+ loop(n) bench_0(ima);
+ float ts = t.stop();
+ std::cout << "ptr " << ts << std::endl;
+ }
+
+// {
+// t.start();
+// loop(n) bench_0(ima, ima2);
+// float ts = t.stop();
+// std::cout << "2 ptrs " << ts << std::endl;
+// }
+
+
+ // piter
+
+ {
+ t.start();
+ loop(n) bench_1(ima);
+ std::cout << "piter " << t.stop() << std::endl;
+ }
+
+
+ // pixter
+
+ {
+ t.start();
+ loop(n) bench_2(ima);
+ float ts = t.stop();
+ std::cout << "pixter " << ts << std::endl;
+ }
+
+// {
+// t.start();
+// loop(n) bench_2(ima, ima2);
+// float ts = t.stop();
+// std::cout << "2 pixters " << ts << std::endl;
+// }
+
+
+ // pixter -> offset
+
+ {
+ t.start();
+ loop(n) bench_3(ima);
+ std::cout << "pixter -> offset " << t.stop() << std::endl;
+ }
+
+// {
+// t.start();
+// loop(n) bench_3(ima, ima2);
+// std::cout << t.stop() << std::endl;
+// }
+
+
+ // pixter -> point
+
+ {
+ t.start();
+ loop(n) bench_4(ima);
+ std::cout << "pixter -> point " << t.stop() << std::endl;
+ }
+
+
+ // box_runstart_piter -> ptr
+
+ {
+ t.start();
+ loop(n) bench_5(ima);
+ std::cout << "box_runstart_piter -> ptr " << t.stop() << std::endl;
+ }
+
+
+ // box_runstart_piter -> (ptr, point)
+
+ {
+ t.start();
+ loop(n) bench_6(ima);
+ float ts = t.stop();
+ std::cout << "runstart -> (ptr, point) " << ts << std::endl;
+ }
+
+// {
+// t.start();
+// loop(n) bench_6(ima, ima2);
+// float ts = t.stop();
+// std::cout << "runstart -> (2 ptrs, point) " << ts << std::endl;
+// }
+
+
+ // box_runstart_piter -> (offset, point)
+
+ {
+ t.start();
+ loop(n) bench_7(ima);
+ float ts = t.stop();
+ std::cout << "runstart -> (offset, point) " << ts << std::endl;
+ }
+
+// {
+// t.start();
+// loop(n) bench_7(ima, ima2);
+// float ts = t.stop();
+// std::cout << "runstart -> (2 offsets, point) " << ts << std::endl;
+// }
+
+}
Index: bench/iz.cc
--- bench/iz.cc (revision 0)
+++ bench/iz.cc (revision 0)
@@ -0,0 +1,386 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <queue>
+#include <mln/core/routine/duplicate.hh>
+#include <mln/data/fill.hh>
+#include <mln/extension/fill.hh>
+
+#include <mln/transform/influence_zone_geodesic.hh>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/util/timer.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+
+
+# define loop(n) for (unsigned i = 0; i < n; ++i)
+
+
+
+namespace mln
+{
+
+
+ template <typename I, typename N>
+ mln_concrete(I) do_iz(const I& input, const N& nbh)
+ {
+ mln_ch_value(I, unsigned) dmap;
+ std::queue<unsigned> q;
+ mln_concrete(I) output;
+
+ // Initialization.
+ {
+ output = duplicate(input); // <-- init
+ extension::fill(output, 1); // For the extension to be ignored.
+
+ mln_pixter(const I) p(input);
+ mln_nixter(const I, N) n(p, nbh);
+ for_all(p)
+ if (p.val() != 0) // <-- inqueue_p_wrt_input_p
+ {
+ ; // <-- init_p
+ // FIXME: dmap.element(p.offset()) = 0;
+ for_all(n)
+ if (n.val() == 0) // <-- inqueue_p_wrt_input_n
+ {
+ q.push(p.offset());
+ break;
+ }
+ }
+ }
+
+ // Propagation.
+ {
+ unsigned p;
+
+ util::array<int> dp = offsets_wrt(input, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ while (! q.empty())
+ {
+ p = q.front();
+ q.pop();
+ // pas de saturation
+ if (output.element(p) == 0)
+ std::cerr << "oops!" << std::endl;
+ for (unsigned i = 0; i < n_nbhs; ++i)
+ {
+ unsigned n = p + dp[i];
+ if (output.element(n) == 0)
+ {
+ output.element(n) = output.element(p); // <- process
+ q.push(n);
+ }
+ }
+ }
+ }
+
+ return output;
+ }
+
+
+
+ template <typename I, typename N>
+ mln_concrete(I) do_iz__bis(const I& input, const N& nbh)
+ {
+ std::queue<unsigned> q;
+ mln_concrete(I) output;
+
+ util::array<int> dp = offsets_wrt(input, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ // Initialization.
+ {
+ output = duplicate(input); // <-- init
+ extension::fill(output, 1); // For the extension to be ignored.
+
+ mln_box_runstart_piter(I) s(input.domain());
+ const unsigned len = s.run_length();
+ for_all(s)
+ {
+ unsigned p = input.index_of_point(s);
+ for (unsigned i = 0; i < len; ++i, ++p)
+ if (input.element(p) != 0)
+ {
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (input.element(n) == 0)
+ {
+ q.push(p);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Propagation.
+ {
+ unsigned p;
+
+ while (! q.empty())
+ {
+ p = q.front();
+ q.pop();
+ mln_invariant(output.element(p) != 0);
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (output.element(n) == 0)
+ {
+ output.element(n) = output.element(p); // <- process
+ q.push(n);
+ }
+ }
+ }
+ }
+
+ return output;
+ }
+
+
+
+
+
+ template <typename I, typename N>
+ mln_concrete(I) do_iz__ter(const I& input, const N& nbh)
+ {
+ std::queue<unsigned> q;
+ mln_concrete(I) output;
+
+ util::array<int> dp = offsets_wrt(input, nbh);
+ const unsigned n_nbhs = dp.nelements();
+ const unsigned
+ skip_border = 2 * input.border(),
+ nrows = input.nrows(),
+ ncols = input.ncols();
+
+ // Initialization.
+ {
+ output = duplicate(input); // <-- init
+ extension::fill(output, 1); // For the extension to be ignored.
+
+ unsigned p = input.index_of_point(point2d(0,0));
+ for (unsigned row = 0; row < nrows; ++row, p += skip_border)
+ {
+ for (unsigned i = 0; i < ncols; ++i, ++p)
+ if (input.element(p) != 0)
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (input.element(n) == 0)
+ {
+ q.push(p);
+ break;
+ }
+ }
+ }
+ }
+
+ // Propagation.
+ {
+ unsigned p;
+
+ while (! q.empty())
+ {
+ p = q.front();
+ q.pop();
+ mln_invariant(output.element(p) != 0);
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (output.element(n) == 0)
+ {
+ output.element(n) = output.element(p); // <- process
+ q.push(n);
+ }
+ }
+ }
+ }
+
+ return output;
+ }
+
+
+
+
+ template <typename I, typename N>
+ mln_concrete(I) do_iz__ptr(const I& input, const N& nbh)
+ {
+ std::queue<mln_value(I)*> q;
+ mln_concrete(I) output;
+
+ util::array<int> dp = offsets_wrt(input, nbh);
+ const unsigned n_nbhs = dp.nelements();
+ const unsigned
+ skip_border = 2 * input.border(),
+ nrows = input.nrows(),
+ ncols = input.ncols();
+
+ // Initialization.
+ {
+ output = duplicate(input);
+ // For the extension to be ignored:
+ extension::fill(input, 0); // in initialization
+ extension::fill(output, 1); // in propagation
+
+ const unsigned nelts = input.nelements();
+ const mln_value(I)* p_i = & input.at_(0, 0);
+ mln_value(I)* p_o = & output.at_(0, 0);
+ for (unsigned i = 0; i < nelts; ++i, ++p_i, ++p_o)
+ {
+ if (*p_i == 0)
+ continue;
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ const mln_value(I)* n_i = p_i + dp[j];
+ if (*n_i == 0)
+ {
+ q.push(p_o);
+ break;
+ }
+ }
+ }
+
+ }
+
+ // Propagation.
+ {
+ mln_value(I)* ptr;
+
+ while (! q.empty())
+ {
+ ptr = q.front();
+ q.pop();
+ mln_invariant(*ptr != 0);
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ mln_value(I)* ntr = ptr + dp[j];
+ if (*ntr == 0)
+ {
+ *ntr = *ptr;
+ q.push(ntr);
+ }
+ }
+ }
+ }
+
+ return output;
+ }
+
+
+
+} // end of namespace mln
+
+
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> in;
+ io::pgm::load(in, "input_iz.pgm");
+
+ util::timer t;
+ neighb2d nbh = c4();
+
+// {
+// t.start();
+// image2d<int_u8> ref = transform::influence_zone_geodesic(in, nbh, mln_max(unsigned));
+// float ts = t.stop();
+// std::cout << ts << std::endl;
+// io::pgm::save(ref, "ref.pgm");
+// }
+
+// {
+// t.start();
+// image2d<int_u8> out = do_iz__bis(in, nbh);
+// float ts = t.stop();
+// std::cout << ts << std::endl;
+// io::pgm::save(out, "iz_bis.pgm");
+// }
+
+// {
+// t.start();
+// image2d<int_u8> out = do_iz__ter(in, nbh);
+// float ts = t.stop();
+// std::cout << ts << std::endl;
+// io::pgm::save(out, "iz_ter.pgm");
+// }
+
+// {
+// t.start();
+// image2d<int_u8> out = do_iz__ptr(in, nbh);
+// float ts = t.stop();
+// std::cout << ts << std::endl;
+// io::pgm::save(out, "iz_ptr.pgm");
+// }
+
+
+ const unsigned n_times = 10;
+
+ {
+ t.start();
+ loop(n_times) transform::influence_zone_geodesic(in, nbh, mln_max(unsigned));
+ float ts = t.stop();
+ std::cout << ts << std::endl;
+ }
+
+ {
+ t.start();
+ loop(n_times) do_iz(in, nbh);
+ float ts = t.stop();
+ std::cout << ts << std::endl;
+ }
+
+ {
+ t.start();
+ loop(n_times) do_iz__bis(in, nbh);
+ float ts = t.stop();
+ std::cout << ts << std::endl;
+ }
+
+ {
+ t.start();
+ loop(n_times) do_iz__ter(in, nbh);
+ float ts = t.stop();
+ std::cout << ts << std::endl;
+ }
+
+ {
+ t.start();
+ loop(n_times) do_iz__ptr(in, nbh);
+ float ts = t.stop();
+ std::cout << ts << std::endl;
+ }
+
+}
Index: bench/fastest_statistical_tour_nbh_browsing.cc
--- bench/fastest_statistical_tour_nbh_browsing.cc (revision 0)
+++ bench/fastest_statistical_tour_nbh_browsing.cc (revision 0)
@@ -0,0 +1,186 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/pw/all.hh>
+#include <mln/data/compare.hh>
+#include <mln/debug/println.hh>
+#include <mln/util/timer.hh>
+
+
+
+# define loop(n) for (unsigned i = 0; i < n; ++i)
+
+
+
+namespace mln
+{
+
+
+ // test_
+
+ template <typename I>
+ void test_(const std::string& routine, float t, const I& ima, unsigned n)
+ {
+ dpoint2d dp(1, 1);
+ box2d
+ b = ima.domain(),
+ inner(b.pmin() + dp, b.pmax() - dp);
+ std::cout << routine << ' ' << t << std::endl;
+ if ((ima | inner) != (pw::cst(4 * n) | inner))
+ std::cerr << "bug in " << routine << '!' << std::endl;
+ // FIXME: other tests...
+ }
+
+
+
+ // piter
+
+ template <typename I, typename N>
+ void piter_based(I& ima, const N& nbh)
+ {
+ mln_piter(I) p(ima.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ if ((p.row() + p.col()) % 2 == 0)
+ for_all(n)
+ ++ima(n);
+ for_all(p)
+ if ((p.row() + p.col()) % 2 == 1)
+ for_all(n)
+ ++ima(n);
+ }
+
+
+ // row_col
+
+ template <typename I, typename N>
+ void row_col_based(I& ima, const N& nbh)
+ {
+ const unsigned nrows = ima.nrows(), ncols = ima.ncols();
+ unsigned n_nbhs = nbh.size();
+ for (int row = 0; row < nrows; ++row)
+ for (int col = row % 2; col < ncols; col += 2)
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ ++ima.at_(row + nbh.dp(j).row(), col + nbh.dp(j).col());
+ for (int row = 0; row < nrows; ++row)
+ for (int col = ! (row % 2); col < ncols; col += 2)
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ ++ima.at_(row + nbh.dp(j).row(), col + nbh.dp(j).col());
+ }
+
+
+ // run_ptr
+
+ template <typename I, typename N>
+ void run_ptr_based(I& ima, const N& nbh)
+ {
+ mln_box_runstart_piter(I) s(ima.domain());
+ const unsigned n = s.run_length();
+
+ util::array<int> dp = offsets_wrt(ima, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ // half-tour 0
+ unsigned skip = 0;
+ for_all(s)
+ {
+ mln_value(I)* ptr = &ima(s) + skip;
+ for (unsigned i = 0; i < n; i += 2)
+ {
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ ++*(ptr + dp(j));
+ ptr += 2;
+ }
+ skip = ! skip;
+ }
+
+ // half-tour 1
+ skip = 1;
+ for_all(s)
+ {
+ mln_value(I)* ptr = &ima(s) + skip;
+ for (unsigned i = 0; i < n; i += 2)
+ {
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ ++*(ptr + dp(j));
+ ptr += 2;
+ }
+ skip = ! skip;
+ }
+ }
+
+
+} // end of namespace mln
+
+
+
+
+
+int main()
+{
+ using namespace mln;
+
+ const unsigned n = 10, size = 1000;
+ image2d<char> ima(size, size);
+ neighb2d nbh = c4();
+ util::timer t;
+ std::string routine;
+
+
+ // piter
+
+ {
+ routine = "piter";
+ data::fill(ima, 0);
+ t.start();
+ loop(n) piter_based(ima, nbh);
+ test_(routine, t.stop(), ima, n);
+ }
+
+
+ // row_col
+
+ {
+ routine = "row_col";
+ data::fill(ima, 0);
+ t.start();
+ loop(n) row_col_based(ima, nbh);
+ test_(routine, t.stop(), ima, n);
+ }
+
+
+ // run_ptr
+
+ {
+ routine = "run_ptr";
+ data::fill(ima, 0);
+ t.start();
+ loop(n) run_ptr_based(ima, nbh);
+ test_(routine, t.stop(), ima, n);
+ }
+
+}
Index: bench/z_sub_browsing/fast.cc
--- bench/z_sub_browsing/fast.cc (revision 0)
+++ bench/z_sub_browsing/fast.cc (revision 0)
@@ -0,0 +1,139 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/util/array.hh>
+#include <mln/util/timer.hh>
+#include <mln/data/fill.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+
+namespace mln
+{
+
+// template <typename I>
+// void
+// test1(const I& input, I& out)
+// {
+// unsigned s = 2;
+// util::timer timer_;
+// timer_.start();
+
+// mln_box_runstart_piter(I) sp(out.domain());
+
+// const unsigned n = sp.run_length();
+
+// unsigned row_offset = input.domain().ncols()
+// + 2 * input.border();
+
+// util::array< mln_value(I)*> ptr(s);
+// util::array<const mln_value(I)*> ptr_input(s);
+
+// sp.start();
+// while (sp.is_valid())
+// {
+// mln_site(I)
+// site = sp; // Site at scale 1.
+
+// unsigned nptr = 0;
+// for (; sp.is_valid() && nptr < ptr.size(); ++nptr)
+// {
+// ptr(nptr) = & out(sp);
+// ptr_input(nptr) = & input(sp);
+// sp.next();
+// }
+// ptr.resize(nptr);
+
+// for (unsigned col = 0; col < n; col += s, site[1] += s)
+// {
+// for (unsigned i = 0; i < ptr.size() ; ++i)
+// for (unsigned j = 0; j < s; ++j)
+// *ptr(i)++ = *ptr_input(i)++;
+// }
+// }
+
+// float t_ = timer_;
+// std::cout << "Test 1 - " << t_ << std::endl;
+// }
+
+
+ template <typename I>
+ void
+ test2(const I& input, I& out, unsigned s)
+ {
+ const unsigned s_2 = s * s, round_it = s_2 / 2;
+ util::timer timer_;
+ timer_.start();
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+
+ mln_box_runstart_piter(I) sp(input.domain());
+
+ const unsigned n = sp.run_length();
+
+ int row_offset = input.domain().ncols() + 2 * input.border();
+ int row_offset_s = row_offset - s;
+ int row_offset_next = - (s - 1) * row_offset;
+
+ mln_value(I)* ptr = out.buffer();
+ const mln_value(I)* ptr_input;
+
+ sp.start();
+ while (sp.is_valid())
+ {
+ mln_site(I)
+ site = sp; // Site at scale 1.
+
+ ptr_input = & input(sp);
+
+ for (unsigned col = 0; col < n; col += s, site[1] += s)
+ {
+
+ // tile
+ S sum = 0;
+ for (unsigned i = 0; i < s;)
+ {
+ for (unsigned j = 0; j < s; ++j)
+ sum += *ptr_input++;
+
+ ++i;
+ if (i < s)
+ ptr_input += row_offset_s;
+ }
+
+ ptr_input += row_offset_next;
+ *ptr++ = sum / s_2;
+ }
+
+ for (unsigned i = 0; i < s; ++i)
+ sp.next();
+ }
+
+ float t_ = timer_;
+ std::cout << t_ << std::endl;
+ }
+
+
+
+} // end of namespace mln
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ def::coord
+ r = 3144,
+ c = 2252;
+
+ image2d<int_u8> input;
+ io::pgm::load(input, "in.pgm");
+
+ unsigned s = 3;
+ box2d b = make::box2d((input.nrows() + s - 1) / s,
+ (input.ncols() + s - 1) / s);
+ image2d<int_u8> output(b, 0);
+ test2(input, output, s);
+
+ io::pgm::save(output, "out.pgm");
+
+}
Index: bench/z_sub_browsing/debase.hh
--- bench/z_sub_browsing/debase.hh (revision 0)
+++ bench/z_sub_browsing/debase.hh (revision 0)
@@ -0,0 +1,351 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_SUBSAMPLING_DEBASE_HH
+# define MLN_SUBSAMPLING_DEBASE_HH
+
+/// \file
+///
+/// Debase subsampling.
+
+#include <mln/core/concept/image.hh>
+
+#define MLN_FLOAT double
+#include <sandbox/theo/exec/gaussian_directional_2d.hh>
+
+
+
+namespace mln
+{
+
+ namespace subsampling
+ {
+
+ /// FIXME: Doc.
+
+ template <typename I>
+ mln_concrete(I)
+ debase(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift); // FIXME: Add round_up_size.
+
+
+ template <typename I>
+ mln_concrete(I)
+ debase(const Image<I>& input, unsigned gap);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Implementation.
+
+ namespace impl
+ {
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase");
+
+ const I& input = exact(input_);
+
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+
+ box<P> b(pmin, pmax);
+ mln_concrete(I) output(b);
+ mln_piter(I) p(output.domain());
+ for_all(p)
+ output(p) = input(p * gap + shift);
+
+ trace::exiting("subsampling::impl::debase");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_fastest(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase_fastest");
+
+ const I& input = exact(input_);
+
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+
+ box<P> b(pmin, pmax);
+
+ typedef mln_concrete(I) O;
+ O output(b);
+
+ mln_box_runstart_piter(O) s(output.domain());
+ const unsigned n = s.run_length();
+ for_all(s)
+ {
+ const mln_value(I)* pi = & input(s * gap + shift);
+ mln_value(O)* po = & output(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ *po++ = *pi;
+ pi += gap;
+ }
+ }
+
+ trace::exiting("subsampling::impl::debase_fastest");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_gaussian_antialiased_fastest(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase_gaussian_antialiased_fastest");
+
+ const I& input = exact(input_);
+
+ image2d<MLN_FLOAT> temp(input.domain());
+ data::fill(temp, input);
+ temp = linear::gaussian_directional_2d(temp, 1, 1.5, 0);
+ temp = linear::gaussian_directional_2d(temp, 0, 1.5, 0);
+
+ typedef mln_value(I) V;
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+
+ box<P> b(pmin, pmax);
+
+ typedef mln_concrete(I) O;
+ O output(b);
+
+ mln_box_runstart_piter(O) s(output.domain());
+ const unsigned n = s.run_length();
+ for_all(s)
+ {
+ const MLN_FLOAT* pi = & temp(s * gap + shift);
+ mln_value(O)* po = & output(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ *po++ = V(*pi + 0.49);
+ pi += gap;
+ }
+ }
+
+ trace::entering("subsampling::impl::debase_gaussian_antialiased_fastest");
+ return output;
+ }
+
+
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_2d_antialias_pointer_fastest(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase_2d_antialias_pointer_fastest");
+
+ const I& input = exact(input_);
+
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+
+ box<P> b(pmin, pmax);
+
+ typedef mln_concrete(I) O;
+ O output(b);
+
+ const unsigned nrows = input.nrows();
+ const unsigned ncols = input.ncols();
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+ for (unsigned row = 0; row < nrows; row += gap)
+ {
+ const V* ptr1 = & input.at_(row, 0);
+ const V* ptr2 = & input.at_(row + 1, 0);
+ const V* ptr3 = & input.at_(row + 2, 0);
+ for (unsigned col = 0; col < ncols; col += gap)
+ {
+ S s;
+
+ // mean
+ s = *ptr1++ + *ptr1++ + *ptr1++;
+ s += *ptr2++ + *ptr2++ + *ptr2++;
+ s += *ptr3++ + *ptr3++ + *ptr3++;
+ output.at_(row / gap, col / gap) = (s + 4) / 9;
+// // cut
+// s = 1 * *ptr1++ + 2 * *ptr1++ + 1 * *ptr1++;
+// s += 2 * *ptr2++ + 3 * *ptr2++ + 2 * *ptr2++;
+// s += 1 * *ptr3++ + 2 * *ptr3++ + 1 * *ptr3++;
+// output.at_(row / gap, col / gap) = (s + 7) / 15;
+ }
+ }
+
+ trace::exiting("subsampling::impl::debase_2d_antialias_pointer_fastest");
+ return output;
+ }
+
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_2d_antialias_offset_fastest(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase_2d_antialias_offset_fastest");
+
+ const I& input = exact(input_);
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+ box<P> b(pmin, pmax);
+ typedef mln_concrete(I) O;
+ O output(b);
+
+ const V* ptr1 = & input.at_(0, 0);
+ const V* ptr2 = & input.at_(1, 0);
+ const V* ptr3 = & input.at_(2, 0);
+
+ mln_box_runstart_piter(O) s(output.domain());
+ const unsigned n = s.run_length();
+
+ unsigned offset = input.delta_index(point2d(3,0) - point2d(0,3*n));
+
+ for_all(s)
+ {
+ mln_value(O)* po = & output(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ S s;
+ s = *ptr1++ + *ptr1++ + *ptr1++;
+ s += *ptr2++ + *ptr2++ + *ptr2++;
+ s += *ptr3++ + *ptr3++ + *ptr3++;
+ *po++ = (s + 4) / 9;
+ }
+ ptr1 += offset;
+ ptr2 += offset;
+ ptr3 += offset;
+ }
+
+ trace::exiting("subsampling::impl::debase_2d_antialias_offset_fastest");
+ return output;
+ }
+
+
+ } // end of namespace mln::subsampling::impl
+
+
+
+ // Dispatch.
+
+ namespace internal
+ {
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_dispatch(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ return impl::debase_2d_antialias_pointer_fastest /* debase_2d_antialias_offset_fastest */(input, gap, shift);
+ }
+
+
+ } // end of namespace mln::subsampling::internal
+
+
+
+ // Facades.
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::debase");
+
+ typedef mln_site(I) P;
+
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(input).domain().pmin() == literal::origin);
+ mln_precondition(gap > 1);
+ for (unsigned i = 0; i < P::dim; ++i)
+ mln_precondition(shift[i] < gap);
+
+ mln_concrete(I) output;
+ output = internal::debase_dispatch(input, gap, shift);
+
+ trace::exiting("subsampling::debase");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase(const Image<I>& input, unsigned gap)
+ {
+ return debase(input, gap, literal::zero);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::subsampling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SUBSAMPLING_DEBASE_HH
Index: bench/z_sub_browsing/integral.hh
--- bench/z_sub_browsing/integral.hh (revision 0)
+++ bench/z_sub_browsing/integral.hh (revision 0)
@@ -0,0 +1,165 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_SUBSAMPLING_INTEGRAL_HH
+# define MLN_SUBSAMPLING_INTEGRAL_HH
+
+/// \file
+///
+/// Both subsampling and integral image computation.
+
+#include <mln/core/concept/image.hh>
+
+
+
+namespace mln
+{
+
+ namespace subsampling
+ {
+
+ /// FIXME: Doc.
+
+ template <typename I>
+ mln_concrete(I)
+ integral(const Image<I>& input, unsigned scale);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Implementation.
+
+ namespace impl
+ {
+
+
+ template <unsigned scale, typename I>
+ inline
+ mln_concrete(I)
+ integral_(const Image<I>& input_)
+ {
+ trace::entering("subsampling::impl::integral_");
+
+ const I& input = exact(input_);
+ const unsigned scale2 = scale * scale, round_it = scale2 / 2;
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+ typedef mln_site(I) P;
+
+ box<P> b = make::box2d(input.nrows() / scale, input.ncols() / scale);
+ const unsigned nrows = b.nrows(), ncols = b.ncols();
+
+ typedef mln_concrete(I) O;
+ O output(b, 0); // no external border in 'output'
+ V* po = output.buffer();
+
+ unsigned
+ tile_cr = input.delta_index(dpoint2d(scale, - ncols * scale)),
+ cr = input.delta_index(dpoint2d(1, - (int)scale));
+
+ const V* pi = & input.at_(0, 0); // first point of tiles
+ for (unsigned row = 0; row < nrows; ++row)
+ {
+ S hsum = 0, hsum2 = 0; // horizontal integral
+ for (unsigned col = 0; col < ncols; ++col)
+ {
+ S sum = 0, sum2 = 0;
+ const V* ptr = pi;
+
+ for (unsigned r = 0; r < scale; ++r)
+ {
+ for (unsigned c = 0; c < scale; ++c)
+ {
+ sum += *ptr;
+ // sum2 += *ptr * *ptr;
+ ++ptr;
+ }
+ ptr += cr;
+ }
+
+ // ...
+ pi += scale;
+ *po++ = (round_it + sum) / scale2;
+ }
+ pi += tile_cr;
+ }
+
+ trace::exiting("subsampling::impl::integral_");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ integral(const Image<I>& input, unsigned scale)
+ {
+ // mln_precondition(input.nrows() % scale == 0);
+ // mln_precondition(input.ncols() % scale == 0);
+ if (scale == 3)
+ return integral_<3>(input);
+ else
+ std::cerr << "NYI!" << std::endl;
+ }
+
+ } // end of namespace mln::subsampling::impl
+
+
+
+
+ // Facades.
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ integral(const Image<I>& input_, unsigned scale)
+ {
+ trace::entering("subsampling::integral");
+
+ const I& input = exact(input_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(input.domain().pmin() == literal::origin);
+ mln_precondition(scale > 1);
+
+ mln_concrete(I) output;
+ output = impl::integral(input, scale);
+
+ trace::exiting("subsampling::integral");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::subsampling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SUBSAMPLING_INTEGRAL_HH
Index: bench/z_sub_browsing/in.pgm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: bench/z_sub_browsing/in.pgm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: bench/z_sub_browsing/debase.cc
--- bench/z_sub_browsing/debase.cc (revision 0)
+++ bench/z_sub_browsing/debase.cc (revision 0)
@@ -0,0 +1,23 @@
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/util/timer.hh>
+
+#include "debase.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> in;
+ io::pgm::load(in, "in.pgm");
+
+ util::timer t;
+ t.start();
+ image2d<int_u8> out = subsampling::debase(in, 3, dpoint2d(1,1));
+ float t_ = t.stop();
+ std::cout << t_ << std::endl;
+
+ io::pgm::save(out, "out.pgm");
+}
Index: bench/z_sub_browsing/integral.cc
--- bench/z_sub_browsing/integral.cc (revision 0)
+++ bench/z_sub_browsing/integral.cc (revision 0)
@@ -0,0 +1,23 @@
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/util/timer.hh>
+
+#include "integral.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> in;
+ io::pgm::load(in, "in.pgm");
+
+ util::timer t;
+ t.start();
+ image2d<int_u8> out = subsampling::integral(in, 3);
+ float t_ = t.stop();
+ std::cout << t_ << std::endl;
+
+ io::pgm::save(out, "out.pgm");
+}
Index: bench/z_sub_browsing/README
--- bench/z_sub_browsing/README (revision 0)
+++ bench/z_sub_browsing/README (revision 0)
@@ -0,0 +1,5 @@
+debase en 03 DNDEBUG: 0.08
+integral: 0.16
+fast: ???
+
+les 3 codes font une moyenne de tiles pour le sub-sampling
Index: theo/mln/morpho/canvas/lena_blurred.pgm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: theo/mln/morpho/canvas/lena_blurred.pgm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: theo/mln/morpho/canvas/lena.pgm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: theo/mln/morpho/canvas/lena.pgm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: theo/mln/morpho/canvas/g.pbm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: theo/mln/morpho/canvas/g.pbm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: theo/mln/morpho/canvas/lena_min.pgm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: theo/mln/morpho/canvas/lena_min.pgm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: theo/mln/morpho/canvas/reconstruction_on_set.hh
Index: theo/mln/morpho/canvas/f_and_g.pbm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: theo/mln/morpho/canvas/f_and_g.pbm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: theo/mln/morpho/canvas/regminid.pbm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: theo/mln/morpho/canvas/regminid.pbm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: theo/mln/morpho/canvas/one_domain.cc
--- theo/mln/morpho/canvas/one_domain.cc (revision 0)
+++ theo/mln/morpho/canvas/one_domain.cc (revision 0)
@@ -0,0 +1,569 @@
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/morpho/canvas/internal/find_root.hh>
+
+# include <mln/data/fill.hh>
+# include <mln/data/sort_psites.hh>
+# include <mln/border/equalize.hh>
+# include <mln/border/fill.hh>
+
+
+// cc
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/data/compare.hh>
+#include <mln/util/timer.hh>
+
+#include <mln/labeling/regional_maxima.hh>
+#include <mln/labeling/regional_minima.hh>
+#include <mln/pw/all.hh>
+
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace canvas
+ {
+
+
+ template <typename I, typename N, typename F>
+ inline
+ mln_result(F)
+ one_domain_union_find(const Image<I>& f_, const Neighborhood<N>& nbh_,
+ F& functor)
+ {
+ trace::entering("morpho::canvas::one_domain_union_find");
+
+ const I& f = exact(f_);
+ const N& nbh = exact(nbh_);
+
+ typedef typename F::S S;
+ typedef mln_psite(I) P;
+ typedef mln_value(I) V;
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, P) parent;
+ mln_result(F) output;
+
+ // Initialization.
+ {
+ initialize(output, f);
+ functor.output = output;
+
+ initialize(parent, f);
+ initialize(deja_vu, f);
+ data::fill(deja_vu, false);
+
+ functor.set_default(); // <-- set_default
+ }
+
+ // First pass.
+ {
+ mln_bkd_piter(S) p(functor.s());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ if (functor.domain(p)) // <-- domain
+ {
+ // Make-Set.
+ parent(p) = p;
+ functor.init(p); // <-- init
+
+ for_all(n) if (f.domain().has(n))
+ {
+ // See below (*)
+ if (functor.domain(n)) // <-- domain
+ {
+ if (deja_vu(n))
+ {
+ if (functor.equiv(p, n)) // <-- equiv
+ {
+ // Do-Union.
+ P r = internal::find_root(parent, n);
+ if (r != p)
+ {
+// if (do_merge(p, r))
+ {
+ parent(r) = p;
+ functor.merge(p, r); // <-- merge
+ }
+// else
+// no_merge(p, r);
+ }
+ }
+ else
+ functor.do_no_union(p, n); // <-- do_no_union
+ }
+ }
+ else
+ {
+ mln_invariant(deja_vu(n) == false);
+ functor.border(p, n); // <-- border
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+
+ // Second pass.
+ {
+ mln_fwd_piter(S) p(functor.s());
+ for_all(p)
+ if (functor.domain(p)) // <-- domain
+ if (parent(p) == p)
+ functor.root(p); // <-- root
+ else
+ output(p) = output(parent(p));
+ }
+
+ trace::exiting("morpho::canvas::one_domain_union_find");
+ return output;
+ }
+
+ } // end of namespace mln::morpho::canvas
+
+ } // end of namespace mln::morpho
+
+
+
+ // base functor
+
+ struct functor_base
+ {
+ void set_default()
+ {
+ }
+ template <typename P>
+ void init(const P&)
+ {
+ }
+ template <typename P>
+ void root(const P&)
+ {
+ }
+ template <typename P>
+ bool domain(const P&)
+ {
+ return true;
+ }
+ template <typename P1, typename P2>
+ void do_no_union(const P1&, const P2&)
+ {
+ }
+ template <typename P1, typename P2>
+ void border(const P1&, const P2&)
+ {
+ }
+ template <typename P1, typename P2>
+ bool equiv(const P1&, const P2&)
+ {
+ return true;
+ }
+ template <typename P1, typename P2>
+ void merge(const P1&, const P2&)
+ {
+ }
+ // no default for:
+ // typedef S
+ // .s()
+ };
+
+
+ // "binary reconstruction by dilation" functor
+
+ template <typename F, typename G>
+ struct rd_functor : functor_base
+ {
+ typedef mln_concrete(F) result;
+
+ const F& f;
+ const G& g;
+
+ typedef mln_domain(F) S;
+
+ rd_functor(const F& f, const G& g)
+ : f(f), g(g)
+ {
+ }
+
+ result output;
+ typedef mln_psite(F) P;
+
+ void set_default()
+ {
+ mln::data::fill(output, false);
+ }
+
+ bool domain(const P& p) const
+ {
+ return g(p) == true;
+ }
+
+ void init(const P& p)
+ {
+ output(p) = f(p);
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ output(p) = output(p) || output(r);
+ }
+
+ S s() const
+ {
+ return f.domain();
+ }
+
+ };
+
+
+ // "labeling" functor
+
+ template <typename I, typename L>
+ struct lab_functor : functor_base
+ {
+ typedef mln_ch_value(I, L) result;
+
+ const I& input;
+ mln_value(I) val;
+
+ L nlabels;
+ bool status;
+
+ lab_functor(const I& input, const mln_value(I)& val)
+ : input(input), val(val)
+ {
+ }
+
+ result output;
+ typedef mln_psite(I) P;
+
+ typedef mln_domain(I) S;
+
+ S s() const
+ {
+ return input.domain();
+ }
+
+ void set_default()
+ {
+ data::fill(output, L(literal::zero));
+ nlabels = 0;
+ status = true;
+ }
+
+ bool domain(const P& p) const
+ {
+ return input(p) == val;
+ }
+
+ bool equiv(const P& p, const P& n)
+ {
+ return input(n) == val;
+ }
+
+ void root(const P& p)
+ {
+ if (status == false)
+ return;
+
+ if (nlabels == mln_max(L))
+ {
+ status = false;
+ trace::warning("labeling aborted!");
+ }
+ else
+ output(p) = ++nlabels;
+ }
+
+ };
+
+
+ // "regional maxima labeling" functor
+
+ template <typename I, typename L>
+ struct regmaxlab_functor : functor_base
+ {
+ typedef mln_ch_value(I, L) result;
+
+ const I& input;
+
+ L nlabels;
+ bool status;
+ mln_ch_value(I, bool) attr;
+
+ typedef mln_psite(I) P;
+ typedef p_array<P> S;
+ S s_;
+
+ result output;
+
+ regmaxlab_functor(const I& input)
+ : input(input)
+ {
+ s_ = data::sort_psites_increasing(input);
+ }
+
+ const S& s() const
+ {
+ return s_;
+ }
+
+ void set_default()
+ {
+ initialize(attr, input);
+ data::fill(attr, true);
+ data::fill(output, L(literal::zero));
+ nlabels = 0;
+ status = true;
+ }
+
+ bool equiv(const P& p, const P& n)
+ {
+ return input(n) == input(p);
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ attr(p) = attr(p) && attr(r);
+ }
+
+ void do_no_union(const P& p, const P& n)
+ {
+ mln_invariant(input(n) > input(p));
+ attr(p) = false;
+ (void)n;
+ }
+
+ void root(const P& p)
+ {
+ if (attr(p) == false || status == false)
+ return;
+
+ if (nlabels == mln_max(L))
+ {
+ status = false;
+ trace::warning("labeling aborted!");
+ }
+ else
+ output(p) = ++nlabels;
+ }
+
+ };
+
+
+ // "regional minima identification" functor
+
+ template <typename I>
+ struct regminid_functor : functor_base
+ {
+ typedef mln_ch_value(I, bool) result;
+
+ const I& input;
+
+ typedef mln_psite(I) P;
+ typedef p_array<P> S;
+ S s_;
+
+ result output;
+
+ regminid_functor(const I& input)
+ : input(input)
+ {
+ s_ = data::sort_psites_decreasing(input);
+ }
+
+ const S& s() const
+ {
+ return s_;
+ }
+
+ void init(const P& p)
+ {
+ output(p) = true;
+ }
+
+ bool equiv(const P& p, const P& n)
+ {
+ return input(n) == input(p);
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ output(p) = output(p) && output(r);
+ }
+
+ void do_no_union(const P& p, const P& n)
+ {
+ if (input(n) < input(p))
+ output(p) = false;
+ }
+
+ };
+
+
+
+ // "reconstruction by dilation on function" functor
+
+ template <typename F, typename G>
+ struct rdf_functor : functor_base
+ {
+ typedef mln_concrete(F) result;
+
+ const F& f;
+ const G& g;
+
+ typedef mln_value(F) V;
+ typedef mln_psite(F) P;
+ typedef p_array<P> S;
+ S s_;
+
+ result output;
+
+ rdf_functor(const F& f, const G& g)
+ : f(f), g(g)
+ {
+ s_ = data::sort_psites_decreasing(g);
+ }
+
+ const S& s() const
+ {
+ return f.domain();
+ }
+
+ void set_default()
+ {
+ mln::data::fill(output, f);
+ }
+
+ bool equiv(const P& p, const P& n)
+ {
+ return g(r) == g(p) || g(p) >= output(r);
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ if (output(r) > output(p))
+ output(p) = output(r);
+ }
+
+ void do_no_union(const P& p, const P& n)
+ {
+ output(p) = mln_max(V);
+ }
+
+ void root(const P& p)
+ {
+ if (output(p) == mln_max(V))
+ output(p) = g(p);
+ }
+
+ };
+
+
+
+} // end of namespace mln
+
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef value::int_u8 L;
+ neighb2d nbh = c4();
+
+ util::timer t;
+
+
+ // On sets.
+
+// {
+// typedef image2d<bool> I;
+
+// I f, g, ref;
+
+// io::pbm::load(f, "f_and_g.pbm");
+// io::pbm::load(g, "g.pbm");
+
+// {
+// t.start();
+// rd_functor<I,I> fun(f, g);
+// I rd = morpho::canvas::one_domain_union_find(f, nbh, fun);
+// std::cout << "rd: " << t.stop() << std::endl;
+// io::pbm::save(rd, "rd.pbm");
+// }
+
+// {
+// t.start();
+// lab_functor<I,L> fun(f, true);
+// image2d<L> lab = morpho::canvas::one_domain_union_find(f, nbh, fun);
+// std::cout << "lab: " << t.stop() << std::endl;
+// io::pgm::save(lab, "lab.pgm");
+// }
+// }
+
+
+ // On functions.
+
+ {
+ typedef image2d<value::int_u8> I;
+ I f;
+ io::pgm::load(f, "./lena_blurred.pgm");
+
+// {
+// // regional maxima labeling
+// t.start();
+// regmaxlab_functor<I,L> fun(f);
+// image2d<L> lab = morpho::canvas::one_domain_union_find(f, nbh, fun);
+// std::cout << "regmax lab: " << t.stop() << std::endl;
+// io::pgm::save(lab, "regmaxlab.pgm");
+
+// L nlabels_ref;
+// if (lab != labeling::regional_maxima(f, nbh, nlabels_ref)
+// || fun.nlabels != nlabels_ref)
+// std::cerr << "oops" << std::endl;
+// }
+
+// {
+// // regional minima identification
+// t.start();
+// regminid_functor<I> fun(f);
+// image2d<bool> id = morpho::canvas::one_domain_union_find(f, nbh, fun);
+// std::cout << "regmin id: " << t.stop() << std::endl;
+// io::pbm::save(id, "regminid.pbm");
+
+// L forget_it;
+// if (id != ((pw::value(labeling::regional_minima(f, nbh, forget_it)) != pw::cst(0)) | id.domain()))
+// std::cerr << "oops" << std::endl;
+// }
+
+ {
+ // reconstruction by dilation
+ I f, g;
+ io::pgm::load(f, "lena.pgm");
+ io::pgm::load(g, "lena_min.pgm");
+ if (! (f <= g))
+ std::cerr << "OK" << std::endl;
+
+ rdf_functor<I,I> fun(f, g);
+ I rdf = morpho::canvas::one_domain_union_find(f, nbh, fun);
+ std::cout << "rdf: " << t.stop() << std::endl;
+ io::pgm::save(rdf, "rdf.pbm");
+
+ }
+
+ }
+
+}
Index: theo/mln/subsampling/sizes.cc
--- theo/mln/subsampling/sizes.cc (revision 0)
+++ theo/mln/subsampling/sizes.cc (revision 0)
@@ -0,0 +1,45 @@
+#include <iostream>
+#include <cstdlib>
+
+
+void usage(const char* argv[])
+{
+ std::cerr << argv[0] << " n_scales s q nr nc" << std::endl;
+ std::abort();
+}
+
+
+unsigned sub(unsigned nbr, unsigned down_scaling)
+{
+ return (nbr + down_scaling - 1) / down_scaling;
+}
+
+
+int main(int argc, const char* argv[])
+{
+ unsigned n_scales = std::atoi(argv[1]);
+ unsigned s = std::atoi(argv[2]);
+ unsigned q = std::atoi(argv[3]);
+
+ unsigned nr_1 = std::atoi(argv[4]);
+ unsigned nc_1 = std::atoi(argv[5]);
+
+ unsigned* nc;
+ nc = new unsigned[n_scales + 1];
+
+ nc[1] = nc_1;
+ nc[2] = sub(nc[1], s);
+ for (unsigned i = 3; i <= n_scales; ++i)
+ nc[i] = sub(nc[i - 1], q);
+
+ for (unsigned i = 1; i <= n_scales; ++i)
+ std::cout << nc[i] << ' ';
+ std::cout << std::endl;
+
+ for (unsigned i = n_scales; i > 2; --i)
+ nc[i - 1] = q * nc[i];
+
+ for (unsigned i = 1; i <= n_scales; ++i)
+ std::cout << nc[i] << ' ';
+ std::cout << std::endl;
+}
Index: theo/mln/subsampling/debase.hh
--- theo/mln/subsampling/debase.hh (revision 0)
+++ theo/mln/subsampling/debase.hh (revision 0)
@@ -0,0 +1,351 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_SUBSAMPLING_DEBASE_HH
+# define MLN_SUBSAMPLING_DEBASE_HH
+
+/// \file
+///
+/// Debase subsampling.
+
+#include <mln/core/concept/image.hh>
+
+#define MLN_FLOAT double
+#include <sandbox/theo/exec/gaussian_directional_2d.hh>
+
+
+
+namespace mln
+{
+
+ namespace subsampling
+ {
+
+ /// FIXME: Doc.
+
+ template <typename I>
+ mln_concrete(I)
+ debase(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift); // FIXME: Add round_up_size.
+
+
+ template <typename I>
+ mln_concrete(I)
+ debase(const Image<I>& input, unsigned gap);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Implementation.
+
+ namespace impl
+ {
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase");
+
+ const I& input = exact(input_);
+
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+
+ box<P> b(pmin, pmax);
+ mln_concrete(I) output(b);
+ mln_piter(I) p(output.domain());
+ for_all(p)
+ output(p) = input(p * gap + shift);
+
+ trace::exiting("subsampling::impl::debase");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_fastest(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase_fastest");
+
+ const I& input = exact(input_);
+
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+
+ box<P> b(pmin, pmax);
+
+ typedef mln_concrete(I) O;
+ O output(b);
+
+ mln_box_runstart_piter(O) s(output.domain());
+ const unsigned n = s.run_length();
+ for_all(s)
+ {
+ const mln_value(I)* pi = & input(s * gap + shift);
+ mln_value(O)* po = & output(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ *po++ = *pi;
+ pi += gap;
+ }
+ }
+
+ trace::exiting("subsampling::impl::debase_fastest");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_gaussian_antialiased_fastest(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase_gaussian_antialiased_fastest");
+
+ const I& input = exact(input_);
+
+ image2d<MLN_FLOAT> temp(input.domain());
+ data::fill(temp, input);
+ temp = linear::gaussian_directional_2d(temp, 1, 1.5, 0);
+ temp = linear::gaussian_directional_2d(temp, 0, 1.5, 0);
+
+ typedef mln_value(I) V;
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+
+ box<P> b(pmin, pmax);
+
+ typedef mln_concrete(I) O;
+ O output(b);
+
+ mln_box_runstart_piter(O) s(output.domain());
+ const unsigned n = s.run_length();
+ for_all(s)
+ {
+ const MLN_FLOAT* pi = & temp(s * gap + shift);
+ mln_value(O)* po = & output(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ *po++ = V(*pi + 0.49);
+ pi += gap;
+ }
+ }
+
+ trace::entering("subsampling::impl::debase_gaussian_antialiased_fastest");
+ return output;
+ }
+
+
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_2d_antialias_pointer_fastest(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase_2d_antialias_pointer_fastest");
+
+ const I& input = exact(input_);
+
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+
+ box<P> b(pmin, pmax);
+
+ typedef mln_concrete(I) O;
+ O output(b);
+
+ const unsigned nrows = input.nrows();
+ const unsigned ncols = input.ncols();
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+ for (unsigned row = 0; row < nrows; row += gap)
+ {
+ const V* ptr1 = & input.at_(row, 0);
+ const V* ptr2 = & input.at_(row + 1, 0);
+ const V* ptr3 = & input.at_(row + 2, 0);
+ for (unsigned col = 0; col < ncols; col += gap)
+ {
+ S s;
+
+ // mean
+ s = *ptr1++ + *ptr1++ + *ptr1++;
+ s += *ptr2++ + *ptr2++ + *ptr2++;
+ s += *ptr3++ + *ptr3++ + *ptr3++;
+ output.at_(row / gap, col / gap) = (s + 4) / 9;
+// // cut
+// s = 1 * *ptr1++ + 2 * *ptr1++ + 1 * *ptr1++;
+// s += 2 * *ptr2++ + 3 * *ptr2++ + 2 * *ptr2++;
+// s += 1 * *ptr3++ + 2 * *ptr3++ + 1 * *ptr3++;
+// output.at_(row / gap, col / gap) = (s + 7) / 15;
+ }
+ }
+
+ trace::exiting("subsampling::impl::debase_2d_antialias_pointer_fastest");
+ return output;
+ }
+
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_2d_antialias_offset_fastest(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::impl::debase_2d_antialias_offset_fastest");
+
+ const I& input = exact(input_);
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+
+ typedef mln_site(I) P;
+ P pmin = input.domain().pmin() / gap,
+ pmax = input.domain().pmax() / gap;
+ box<P> b(pmin, pmax);
+ typedef mln_concrete(I) O;
+ O output(b);
+
+ const V* ptr1 = & input.at_(0, 0);
+ const V* ptr2 = & input.at_(1, 0);
+ const V* ptr3 = & input.at_(2, 0);
+
+ mln_box_runstart_piter(O) s(output.domain());
+ const unsigned n = s.run_length();
+
+ unsigned offset = input.delta_index(point2d(3,0) - point2d(0,3*n));
+
+ for_all(s)
+ {
+ mln_value(O)* po = & output(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ S s;
+ s = *ptr1++ + *ptr1++ + *ptr1++;
+ s += *ptr2++ + *ptr2++ + *ptr2++;
+ s += *ptr3++ + *ptr3++ + *ptr3++;
+ *po++ = (s + 4) / 9;
+ }
+ ptr1 += offset;
+ ptr2 += offset;
+ ptr3 += offset;
+ }
+
+ trace::exiting("subsampling::impl::debase_2d_antialias_offset_fastest");
+ return output;
+ }
+
+
+ } // end of namespace mln::subsampling::impl
+
+
+
+ // Dispatch.
+
+ namespace internal
+ {
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase_dispatch(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ return impl::debase_2d_antialias_pointer_fastest /* debase_2d_antialias_offset_fastest */(input, gap, shift);
+ }
+
+
+ } // end of namespace mln::subsampling::internal
+
+
+
+ // Facades.
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ trace::entering("subsampling::debase");
+
+ typedef mln_site(I) P;
+
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(input).domain().pmin() == literal::origin);
+ mln_precondition(gap > 1);
+ for (unsigned i = 0; i < P::dim; ++i)
+ mln_precondition(shift[i] < gap);
+
+ mln_concrete(I) output;
+ output = internal::debase_dispatch(input, gap, shift);
+
+ trace::exiting("subsampling::debase");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ debase(const Image<I>& input, unsigned gap)
+ {
+ return debase(input, gap, literal::zero);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::subsampling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SUBSAMPLING_DEBASE_HH
Index: theo/mln/subsampling/integral.hh
--- theo/mln/subsampling/integral.hh (revision 0)
+++ theo/mln/subsampling/integral.hh (revision 0)
@@ -0,0 +1,295 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_SUBSAMPLING_INTEGRAL_HH
+# define MLN_SUBSAMPLING_INTEGRAL_HH
+
+/// \file
+///
+/// Both subsampling and integral image computation.
+
+#include <mln/core/concept/image.hh>
+#include <mln/debug/println.hh>
+
+
+
+namespace mln
+{
+
+ namespace subsampling
+ {
+
+ /// FIXME: Doc.
+
+ template <typename I>
+ mln_concrete(I)
+ integral(const Image<I>& input, unsigned scale);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Implementation.
+
+ namespace impl
+ {
+
+
+ template <unsigned scale, typename I>
+ inline
+ mln_concrete(I)
+ integral__why_is_it_slow(const Image<I>& input_)
+ {
+ trace::entering("subsampling::impl::integral__why_is_it_slow");
+
+ const I& input = exact(input_);
+ const unsigned scale2 = scale * scale, round_it = scale2 / 2;
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+ typedef mln_site(I) P;
+
+ box<P> b = make::box2d(input.nrows() / scale, input.ncols() / scale);
+ const unsigned nrows = b.nrows(), ncols = b.ncols();
+
+ typedef mln_concrete(I) O;
+ O output(b, 0); // no external border in 'output'
+ V* po = output.buffer();
+
+ unsigned
+ tile_cr = input.delta_index(dpoint2d(scale, - ncols * scale)),
+ cr = input.delta_index(dpoint2d(1, - (int)scale));
+
+ const V* pi = & input.at_(0, 0); // first point of tiles
+
+ // (row, col) are tile coordinates.
+ for (unsigned row = 0; row < nrows; ++row)
+ {
+ S hsum = 0, hsum2 = 0; // horizontal integral
+ for (unsigned col = 0; col < ncols; ++col)
+ {
+ S sum = 0, sum2 = 0;
+ const V* ptr = pi;
+
+ for (unsigned r = 0; r < scale; ++r)
+ {
+ for (unsigned c = 0; c < scale; ++c)
+ {
+ sum += *ptr;
+ ++ptr;
+ }
+ ptr += cr;
+ }
+ // ...
+ pi += scale;
+ *po++ = (round_it + sum) / scale2;
+ }
+ pi += tile_cr;
+ }
+
+ trace::exiting("subsampling::impl::integral__why_is_it_slow");
+ return output;
+ }
+
+
+
+ template <unsigned scale, typename I>
+ inline
+ mln_concrete(I)
+ integral_(const Image<I>& input_)
+ {
+ trace::entering("subsampling::impl::integral_");
+
+ const I& input = exact(input_);
+ const unsigned scale2 = scale * scale, round_it = scale2 / 2;
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+ typedef mln_site(I) P;
+
+ box<P> b = make::box2d((input.nrows() + scale - 1) / scale,
+ (input.ncols() + scale - 1) / scale);
+ typedef mln_concrete(I) O;
+ O output(b, 0);
+ V* po = output.buffer();
+
+ const unsigned nrows = input.nrows();
+ const unsigned ncols = input.ncols();
+
+ typedef const V* Ptr;
+ Ptr ptr[scale];
+ for (unsigned row = 0; row < nrows; row += scale)
+ {
+ for (unsigned r = 0; r < scale; ++r)
+ ptr[r] = & input.at_(row + r, 0);
+
+ for (unsigned col = 0; col < ncols; col += scale)
+ {
+ S sum = 0;
+ for (unsigned r = 0; r < scale; ++r)
+ for (unsigned c = 0; c < scale; ++c)
+ // g++ does *not* un-roll this inner loop!!!
+ // icc does...
+ sum += *ptr[r]++;
+
+ *po++ = (round_it + sum) / scale2;
+ }
+ }
+
+ trace::exiting("subsampling::impl::integral_");
+ return output;
+ }
+
+
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ integral_3(const Image<I>& input_)
+ {
+ trace::entering("subsampling::impl::integral_3");
+
+ const unsigned scale = 3;
+
+ const I& input = exact(input_);
+ const unsigned area = scale * scale;
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+ typedef mln_site(I) P;
+
+ box<P> b = make::box2d((input.nrows() + scale - 1) / scale,
+ (input.ncols() + scale - 1) / scale);
+ const unsigned up = b.ncols();
+
+ mln_concrete(I) sub(b, 0);
+ V* p_sub = sub.buffer();
+
+ mln_ch_value(I, S) integral_sum(b, 0);
+ S* p_isum = integral_sum.buffer();
+
+ mln_ch_value(I, S) integral_sum_2(b, 0);
+ S* p_isum_2 = integral_sum_2.buffer();
+
+ const unsigned nrows = input.nrows();
+ const unsigned ncols = input.ncols();
+
+ for (unsigned row = 0; row < nrows; row += scale)
+ {
+ S h_sum = 0, h_sum_2 = 0;
+ const V* ptr1 = & input.at_(row, 0);
+ const V* ptr2 = & input.at_(row + 1, 0);
+ const V* ptr3 = & input.at_(row + 2, 0);
+ for (unsigned col = 0; col < ncols; col += scale)
+ {
+ S sum;
+ sum = *ptr1++ + *ptr1++ + *ptr1++;
+ sum += *ptr2++ + *ptr2++ + *ptr2++;
+ sum += *ptr3++ + *ptr3++ + *ptr3++;
+
+ S val = sum / area;
+ *p_sub++ = val;
+
+ h_sum += val;
+ h_sum_2 += val * val;
+
+ if (row != 0)
+ {
+ *p_isum = h_sum + *(p_isum - up);
+ *p_isum_2 = h_sum_2 + *(p_isum_2 - up);
+ }
+ else
+ {
+ // exception
+ *p_isum = h_sum;
+ *p_isum_2 = h_sum_2;
+ }
+
+ p_isum += 1;
+ p_isum_2 += 1;
+ }
+ }
+
+ debug::println(sub);
+ debug::println(integral_sum);
+ debug::println(integral_sum_2);
+
+ trace::exiting("subsampling::impl::integral_3");
+ return sub;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ integral(const Image<I>& input, unsigned scale)
+ {
+ // mln_precondition(input.nrows() % scale == 0);
+ // mln_precondition(input.ncols() % scale == 0);
+ if (scale == 3)
+ return integral_3(input);
+ else
+ std::cerr << "NYI!" << std::endl;
+ }
+
+
+ } // end of namespace mln::subsampling::impl
+
+
+
+
+ // Facades.
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ integral(const Image<I>& input_, unsigned scale)
+ {
+ trace::entering("subsampling::integral");
+
+ const I& input = exact(input_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(input.domain().pmin() == literal::origin);
+ mln_precondition(scale > 1);
+
+ mln_concrete(I) output;
+ output = impl::integral(input, scale);
+
+ trace::exiting("subsampling::integral");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::subsampling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SUBSAMPLING_INTEGRAL_HH
Index: theo/mln/subsampling/in.pgm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: theo/mln/subsampling/in.pgm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: theo/mln/subsampling/debase.cc
--- theo/mln/subsampling/debase.cc (revision 0)
+++ theo/mln/subsampling/debase.cc (revision 0)
@@ -0,0 +1,23 @@
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/util/timer.hh>
+
+#include "debase.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> in;
+ io::pgm::load(in, "in.pgm");
+
+ util::timer t;
+ t.start();
+ image2d<int_u8> out = subsampling::debase(in, 3, dpoint2d(1,1));
+ float t_ = t.stop();
+ std::cout << t_ << std::endl;
+
+ io::pgm::save(out, "out.pgm");
+}
Index: theo/mln/subsampling/integral.cc
--- theo/mln/subsampling/integral.cc (revision 0)
+++ theo/mln/subsampling/integral.cc (revision 0)
@@ -0,0 +1,38 @@
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/util/timer.hh>
+
+#include "integral.hh"
+
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+
+ image2d<int_u8> in(6, 9);
+ debug::iota(in);
+ debug::println(in);
+
+ image2d<int_u8> out = subsampling::integral(in, 3);
+// debug::println(out);
+
+
+// {
+// image2d<int_u8> in;
+// io::pgm::load(in, "in.pgm");
+
+// util::timer t;
+// t.start();
+// image2d<int_u8> out = subsampling::integral(in, 3);
+// float t_ = t.stop();
+// std::cout << t_ << std::endl;
+
+// io::pgm::save(out, "out.pgm");
+// }
+
+}
Index: theo/mln/browsing/window_sliding.cc
--- theo/mln/browsing/window_sliding.cc (revision 0)
+++ theo/mln/browsing/window_sliding.cc (revision 0)
@@ -0,0 +1,52 @@
+#include <iostream>
+#include <cassert>
+
+
+
+
+void window_sliding(unsigned nr, unsigned nc,
+ unsigned h, unsigned w)
+{
+ const unsigned h_2 = h / 2;
+ const int d_row_up = - 1 - h_2, d_row_down = h_2;
+
+ // top part
+ for (int row = 0; row <= h_2; ++row)
+ {
+ assert(row + d_up < 0);
+ assert(row + d_down >= 0 && row + d_down < nr);
+ // top left
+ // ...
+
+ // top middle
+ // ...
+
+ // top right
+ // ...
+ }
+ // main part
+ for (int row = h_2 + 1; row <= nr - 1 - h_2; ++row)
+ {
+ assert(row + d_up >= 0 && row + d_up < nr);
+ assert(row + d_down >= 0 && row + d_down < nr);
+ }
+ // bottom part
+ for (int row = nr - h_2; row < nr; ++row)
+ {
+ assert(row + d_up >= 0 && row + d_up < nr);
+ assert(row + d_down >= nr);
+ }
+}
+
+
+
+int main()
+{
+
+// unsigned nr = 50, nc = 100;
+
+ unsigned nr = 10, nc = 10;
+ unsigned h = 3, w = 5;
+ window_sliding(nr, nc, h, w);
+
+}
1
0
[Olena] #206: Add the sources of the images of the ISMM 2009 paper to the Olena repository
by Olena Trac 12 Nov '09
by Olena Trac 12 Nov '09
12 Nov '09
#206: Add the sources of the images of the ISMM 2009 paper to the Olena
repository
-----------------------------------+----------------------------------------
Reporter: levill_r | Owner: levill_r
Type: enhancement | Status: new
Priority: minor | Milestone: Olena 1.1
Component: other | Version: 1.0
Keywords: reproducible research |
-----------------------------------+----------------------------------------
Most of the work is already done, since the repository of the ISMM 2009
paper contains the material to automatically generate the images (needs
some clean up though).
Once moved to the Olena repository, remove the generators from the ISMM
2009 repository and only keep the end products (and possibly add Make
rules to automate the update (copy) of the images from the Olena
repository).
--
Ticket URL: <https://trac.lrde.org/olena/ticket/206>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
1
12 Nov '09
#173: Complete the graph fusion example started with Géraud Béguin
----------------------+-----------------------------------------------------
Reporter: levill_r | Owner: Olena Team
Type: task | Status: new
Priority: minor | Milestone:
Component: other | Version: 1.0
Keywords: IGR |
----------------------+-----------------------------------------------------
See:
* source:branches/cleanup-2008/milena/sandbox/beguin/irm.cc
* source:branches/cleanup-2008/milena/sandbox/beguin/fusion_graph.hh
--
Ticket URL: <https://trac.lrde.org/olena/ticket/173>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
2
1