URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-12-05 Simon Nivault <simon.nivault(a)lrde.epita.fr>
Add mono object based rle image and add test.
* mln/core/mono_obased_rle_encode.hh: New.
* mln/core/mono_obased_rle_image.hh: New.
* mln/core/mono_rle_encode.hh: Fix.
* mln/core/mono_rle_image.hh: Add get_value() method.
* mln/core/obased_rle_image.hh: Add vector of value for easier
acces to the image.
* tests/core/Makefile.am: Add test.
* tests/core/mono_obased_rle_image.cc: New.
---
mln/core/mono_obased_rle_encode.hh | 120 ++++++++++++++++
mln/core/mono_obased_rle_image.hh | 255 ++++++++++++++++++++++++++++++++++++
mln/core/mono_rle_encode.hh | 5
mln/core/mono_rle_image.hh | 19 ++
mln/core/obased_rle_image.hh | 36 +----
tests/core/Makefile.am | 2
tests/core/mono_obased_rle_image.cc | 78 +++++++++++
7 files changed, 483 insertions(+), 32 deletions(-)
Index: trunk/milena/tests/core/Makefile.am
===================================================================
--- trunk/milena/tests/core/Makefile.am (revision 1593)
+++ trunk/milena/tests/core/Makefile.am (revision 1594)
@@ -7,6 +7,7 @@
clone \
exact \
initialize \
+ mono_obased_rle_image \
mono_rle_image \
obased_rle_image \
p_runs \
@@ -17,6 +18,7 @@
clone_SOURCES = clone.cc
exact_SOURCES = exact.cc
initialize_SOURCES = initialize.cc
+mono_obased_rle_image_SOURCES = mono_obased_rle_image.cc
mono_rle_image_SOURCES = mono_rle_image.cc
obased_rle_image_SOURCES = obased_rle_image.cc
p_runs_SOURCES = p_runs.cc
Index: trunk/milena/tests/core/mono_obased_rle_image.cc
===================================================================
--- trunk/milena/tests/core/mono_obased_rle_image.cc (revision 0)
+++ trunk/milena/tests/core/mono_obased_rle_image.cc (revision 1594)
@@ -0,0 +1,78 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/core/mono_obased_rle_image.cc
+ *
+ * \brief Test on mln::mono_obased_rle_image.hh.
+ */
+
+#include <mln/core/image2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/pw/all.hh>
+#include <mln/core/neighb2d.hh>
+
+#include <mln/labeling/blobs.hh>
+#include <mln/level/transform.hh>
+#include <mln/level/paste.hh>
+#include <mln/level/compare.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/core/mono_obased_rle_encode.hh>
+
+struct fold_t : public mln::Function_v2v< fold_t >
+{
+ typedef mln::value::int_u8 result;
+ result operator()(unsigned i) const { return i == 0 ? 0 : (i - 1) % 255 + 1; }
+};
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> lena;
+ io::pgm::load(lena, "../../img/tiny.pgm");
+ image2d<int_u8> cmp(lena.domain());
+
+ unsigned n;
+ image2d<unsigned>
+ labels = labeling::blobs((pw::value(lena) > pw::cst(172u)) | lena.domain(),
+ c4(), n);
+
+ mono_obased_rle_image<point2d, int_u8>
+ rle = mono_obased_rle_encode(level::transform(labels, fold_t()));
+
+ std::cout << n << ", compression :" << rle.compression() << std::endl;
+
+ level::fill(cmp, literal::zero);
+ level::paste(rle, cmp);
+
+ mln_assertion(cmp == level::transform(labels, fold_t()));
+}
Index: trunk/milena/mln/core/mono_rle_encode.hh
===================================================================
--- trunk/milena/mln/core/mono_rle_encode.hh (revision 1593)
+++ trunk/milena/mln/core/mono_rle_encode.hh (revision 1594)
@@ -94,11 +94,8 @@
else
{
output.insert(p_run<P>(rstart, len));
- if ((len = (!ignore_zero || ima(p) != literal::zero)))
- {
+ if ((len = (ima(p) == val)))
rstart = p;
- rvalue = ima(p);
- }
}
}
return output;
Index: trunk/milena/mln/core/mono_rle_image.hh
===================================================================
--- trunk/milena/mln/core/mono_rle_image.hh (revision 1593)
+++ trunk/milena/mln/core/mono_rle_image.hh (revision 1594)
@@ -55,7 +55,7 @@
data_(const T& val);
/// Image value.
- T value;
+ T value_;
/// domain of the image
p_runs_<P> domain_;
@@ -128,6 +128,9 @@
/// Test if this image has been initialized.
bool has_data() const;
+ /// Give the uniq value of the image.
+ rvalue get_value() const;
+
/// Give the set of values of the image.
const vset& values() const;
@@ -147,7 +150,7 @@
template <typename P, typename T>
inline
data_< mono_rle_image<P,T> >::data_(const T& val)
- : value(val)
+ : value_(val)
{
}
@@ -201,7 +204,15 @@
const
{
mln_precondition(site.pset_pos_() < this->data_->domain_.nruns());
- return this->data_->value;
+ return this->data_->value_;
+ }
+
+ template <typename P, typename T>
+ inline
+ typename mono_rle_image<P, T>::rvalue
+ mono_rle_image<P, T>::get_value() const
+ {
+ return this->data_->value_;
}
template <typename P, typename T>
@@ -210,7 +221,7 @@
mono_rle_image<P, T>::operator() (const typename mono_rle_image<P, T>::psite& site)
{
mln_precondition(site.pset_pos_() < this->data_->domain_.nruns());
- return this->data_->value;
+ return this->data_->value_;
}
template <typename P, typename T>
Index: trunk/milena/mln/core/obased_rle_image.hh
===================================================================
--- trunk/milena/mln/core/obased_rle_image.hh (revision 1593)
+++ trunk/milena/mln/core/obased_rle_image.hh (revision 1594)
@@ -62,6 +62,9 @@
std::vector< accu::bbox<P> > bbox_;
/// Value of Objects.
+ std::vector<T> v_obj_;
+
+ /// Image values.
std::vector<T> values_;
/// domain of the image
@@ -163,7 +166,7 @@
bbox_(values.size())
{
std::copy(values.begin(), values.end(),
- std::back_inserter(this->values_));
+ std::back_inserter(this->v_obj_));
}
template <typename P, typename T>
@@ -173,7 +176,7 @@
{
return domain_.size_mem() + bbox_.size()
* (sizeof(T) + sizeof(box_<P>) + sizeof(std::vector<unsigned>))
- + sizeof(unsigned) * domain_.nruns();
+ + (sizeof(unsigned) + sizeof(T)) * domain_.nruns();
}
} // end of namespace mln::internal
@@ -206,14 +209,15 @@
void
obased_rle_image<P, T>::insert(const p_run<P>& pr, T value)
{
- mln_assertion(this->data_->values_.size() == 0 || this->data_->domain_.nruns() == 0 ||
+ mln_assertion(this->data_->v_obj_.size() == 0 || this->data_->domain_.nruns() == 0 ||
pr.first() > this->data_->domain_[this->data_->domain_.nruns() - 1].first());
this->data_->domain_.insert(pr);
+ this->data_->values_.push_back(value);
unsigned i;
- for (i = 0; i < this->data_->values_.size()
- && this->data_->values_[i] != value; ++i)
+ for (i = 0; i < this->data_->v_obj_.size()
+ && this->data_->v_obj_[i] != value; ++i)
;
- mln_assertion(i != this->data_->values_.size());
+ mln_assertion(i != this->data_->v_obj_.size());
this->data_->obj_[i].push_back(this->data_->domain_.nruns() - 1);
this->data_->bbox_[i].take(pr.bbox().pmin());
this->data_->bbox_[i].take(pr.bbox().pmax());
@@ -227,15 +231,7 @@
{
mln_precondition(this->has_data() &&
site.pset_pos_() < this->data_->domain_.nruns());
- for (unsigned i = 0; i < this->data_->obj_.size(); ++i)
- {
- for (typename std::vector<unsigned>::const_iterator it = this->data_->obj_[i].begin();
- it != this->data_->obj_[i].end(); it++)
- if (*it == site.pset_pos_())
- return this->data_->values_[i];
- }
- mln_assertion(false);
- return this->data_->values_[0];
+ return this->data_->values_[site.pset_pos_()];
}
template <typename P, typename T>
@@ -245,15 +241,7 @@
{
mln_precondition(this->has_data() &&
site.pset_pos_() < this->data_->domain_.nruns());
- for (unsigned i = 0; i < this->data_->obj_.size(); ++i)
- {
- for (typename std::vector<unsigned>::const_iterator it = this->data_->obj_[i].begin();
- it != this->data_->obj_[i].end(); it++)
- if (*it == site.pset_pos_())
- return this->data_->values_[i];
- }
- mln_assertion(false);
- return this->data_->values_[0];
+ return this->data_->values_[site.pset_pos_()];
}
template <typename P, typename T>
Index: trunk/milena/mln/core/mono_obased_rle_encode.hh
===================================================================
--- trunk/milena/mln/core/mono_obased_rle_encode.hh (revision 0)
+++ trunk/milena/mln/core/mono_obased_rle_encode.hh (revision 1594)
@@ -0,0 +1,120 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_MONO_OBASED_RLE_ENCODE_HH
+# define MLN_CORE_MONO_OBASED_RLE_ENCODE_HH
+
+/*! \file mln/core/mono_obased_rle_encode.hh
+ *
+ * \brief Definintion of function which encodes an image in mono_obased_rle_image.
+ */
+
+# include <mln/core/mono_obased_rle_image.hh>
+
+namespace mln
+{
+
+ /*!
+ ** encode an image class to a mono_obased_rle_image
+ **
+ ** @param input has to respect the Image concept
+ **
+ ** @return mono_obased_rle_image
+ */
+ template <typename I>
+ mono_obased_rle_image<mln_point(I), mln_value(I)>
+ mono_obased_rle_encode(const Image<I>& input, bool ignore_zero = true);
+
+# ifndef MLN_INCLUDE_ONLY
+ /*!
+ ** test if Point p1 and p2 are on the same line
+ */
+ template <typename P>
+ inline
+ bool
+ on_the_same_line(const P& p1, const P& p2)
+ {
+ const unsigned dim = P::dim;
+ bool same_line = true;
+
+ for (unsigned n = 0; same_line && n < dim - 1; ++n)
+ same_line = (p1[n] == p2[n]);
+ return same_line;
+ }
+
+ template <typename I>
+ inline
+ mono_obased_rle_image<mln_point(I), mln_value(I)>
+ mono_obased_rle_encode(const Image<I>& input, bool ignore_zero)
+ {
+ typedef mln_point(I) P;
+
+ const I& ima = exact(input);
+ mln_piter(I) p (exact(input).domain());
+ unsigned len = 0;
+ mln_point(I) rstart;
+ mln_value(I) rvalue;
+ std::set< mln_value(I) > sv;
+
+ for_all(p)
+ {
+ if (!ignore_zero || ima(p) != literal::zero)
+ sv.insert(ima(p));
+ }
+
+ mono_obased_rle_image<mln_point(I), mln_value(I)> output(sv);
+ for_all(p)
+ if (!ignore_zero || ima(p) != literal::zero || len)
+ {
+ if (len == 0)
+ {
+ ++len;
+ rstart = p;
+ rvalue = ima(p);
+ }
+ else
+ if (rvalue == ima(p)
+ && on_the_same_line(rstart, mln_point(I)(p)))
+ ++len;
+ else
+ {
+ output.insert(p_run<P>(rstart, len), rvalue);
+ if ((len = (!ignore_zero || ima(p) != literal::zero)))
+ {
+ rstart = p;
+ rvalue = ima(p);
+ }
+ }
+ }
+ return output;
+ }
+
+#endif // ! MLN_INCLUDE_ONLY
+
+}
+
+#endif // ! MLN_CORE_MONO_OBASED_RLE_ENCODE_HH
Index: trunk/milena/mln/core/mono_obased_rle_image.hh
===================================================================
--- trunk/milena/mln/core/mono_obased_rle_image.hh (revision 0)
+++ trunk/milena/mln/core/mono_obased_rle_image.hh (revision 1594)
@@ -0,0 +1,255 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_MONO_OBASED_RLE_IMAGE_HH
+# define MLN_CORE_MONO_OBASED_RLE_IMAGE_HH
+
+/*! \file mln/core/mono_obased_rle_image.hh
+ *
+ * \brief Definition of an image with rle encoding.
+ */
+
+# include <mln/core/internal/run_image.hh>
+# include <mln/core/p_runs.hh>
+# include <mln/core/runs_psite.hh>
+# include <mln/core/box.hh>
+# include <mln/value/set.hh>
+# include <mln/core/mono_rle_image.hh>
+# include <vector>
+
+namespace mln
+{
+
+ // Fwd decl.
+ template <typename P, typename T> struct mono_obased_rle_image;
+
+
+ namespace internal
+ {
+
+ template <typename P, typename T>
+ struct data_< mono_obased_rle_image<P,T> >
+ {
+ data_(const std::set<T>& values);
+
+ /// Objects.
+ std::vector< mono_rle_image<P, T> > ima_;
+
+ /// Image value.
+ std::vector<T> values_;
+
+ /// domain of the image
+ p_runs_<P> domain_;
+
+ /// Return the size of the data in memory.
+ unsigned size_mem() const;
+ };
+
+ } // end of namespace mln::internal
+
+
+ namespace trait
+ {
+
+ template <typename P, typename T>
+ struct image_< mono_obased_rle_image<P,T> > : default_image_< T, mono_obased_rle_image<P,T> >
+ {
+ typedef trait::image::category::primary category;
+
+ typedef trait::image::access::browsing access;
+ // FIXME: Put the right dimension.
+ typedef trait::image::space::two_d space;
+ typedef trait::image::size::regular size;
+ typedef trait::image::support::aligned support;
+
+ typedef trait::image::border::none border;
+ typedef trait::image::data::linear data;
+ typedef trait::image::io::read_only io;
+ typedef trait::image::speed::slow speed;
+ };
+
+ } // end of namespace mln::trait
+
+
+ /*! \brief RLE image.
+ *
+ *
+ * Parameter \c P is the type of the image points.
+ * Parameter \c T is the type of the pixel values.
+ * This image is not point wise accessible.
+ */
+ template <typename P, typename T>
+ class mono_obased_rle_image : public internal::run_image_< T, P, mono_obased_rle_image<P, T> >
+ {
+ public:
+ typedef T value;
+ typedef T& lvalue;
+ typedef const T rvalue;
+ typedef runs_psite<P> psite;
+ typedef mln::value::set<T> vset;
+ typedef p_runs_<P> pset;
+
+
+ /// Skeleton.
+ typedef mono_obased_rle_image< tag::psite_<P>, tag::value_<T> > skeleton;
+
+
+ mono_obased_rle_image(const std::set<T>& values);
+
+ /// Add a new range to the image.
+ void insert(const p_run<P>& pr, T value);
+
+ /// Read-only access to the image value located at point \p p.
+ rvalue operator() (const psite& site) const;
+
+ /// Read-write access to the image value located at point \p p.
+ lvalue operator() (const psite& site);
+
+ /// Test if this image has been initialized.
+ bool has_data() const;
+
+ /// Give the set of values of the image.
+ const vset& values() const;
+
+ /// Give the definition domain.
+ const pset& domain() const;
+
+ /// Give the index vector of the i-th object.
+ const mono_rle_image<P, T>& object(unsigned i) const;
+
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // internal::data_< mono_obased_rle_image<P,T> >
+
+ template <typename P, typename T>
+ inline
+ data_< mono_obased_rle_image<P,T> >::data_(const std::set<T>& values)
+ : ima_(values.begin(), values.end())
+ {
+ }
+
+ template <typename P, typename T>
+ inline
+ unsigned
+ data_< mono_obased_rle_image<P,T> >::size_mem() const
+ {
+ return domain_.size_mem() * 2 + sizeof(T) * (values_.size() + ima_.size());
+ }
+
+ } // end of namespace mln::internal
+
+ template <typename P, typename T>
+ inline
+ mono_obased_rle_image<P, T>::mono_obased_rle_image(const std::set<T>& values)
+ {
+ this->data_ = new internal::data_< mono_obased_rle_image<P,T> >(values);
+ }
+
+ template <typename P, typename T>
+ inline
+ bool
+ mono_obased_rle_image<P, T>::has_data() const
+ {
+ return this->data_->ima_.size() != 0;
+ }
+
+ template <typename P, typename T>
+ inline
+ const typename mono_obased_rle_image<P, T>::vset&
+ mono_obased_rle_image<P, T>::values() const
+ {
+ return vset::the();
+ }
+
+ template <typename P, typename T>
+ inline
+ void
+ mono_obased_rle_image<P, T>::insert(const p_run<P>& pr, T value)
+ {
+ mln_assertion(this->data_->values_.size() == 0 || this->data_->domain_.nruns() == 0 ||
+ pr.first() > this->data_->domain_[this->data_->domain_.nruns() - 1].first());
+ this->data_->domain_.insert(pr);
+ this->data_->values_.push_back(value);
+ unsigned i;
+ for (i = 0; i < this->data_->ima_.size()
+ && this->data_->ima_[i].get_value() != value; ++i)
+ ;
+ mln_assertion(i != this->data_->ima_.size());
+ this->data_->ima_[i].insert(pr);
+ }
+
+ template <typename P, typename T>
+ inline
+ typename mono_obased_rle_image<P, T>::rvalue
+ mono_obased_rle_image<P, T>::operator() (const typename mono_obased_rle_image<P, T>::psite& site)
+ const
+ {
+ mln_precondition(this->has_data() &&
+ site.pset_pos_() < this->data_->domain_.nruns());
+ return this->data_->values_[site.pset_pos_()];
+ }
+
+ template <typename P, typename T>
+ inline
+ typename mono_obased_rle_image<P, T>::lvalue
+ mono_obased_rle_image<P, T>::operator() (const typename mono_obased_rle_image<P, T>::psite& site)
+ {
+ mln_precondition(this->has_data() &&
+ site.pset_pos_() < this->data_->domain_.nruns());
+ return this->data_->values_[site.pset_pos_()];
+ }
+
+ template <typename P, typename T>
+ inline
+ const typename mono_obased_rle_image<P, T>::pset&
+ mono_obased_rle_image<P, T>::domain() const
+ {
+ return this->data_->domain_;
+ }
+
+ template <typename P, typename T>
+ inline
+ const mono_rle_image<P, T>&
+ mono_obased_rle_image<P, T>::object(unsigned i) const
+ {
+ mln_assertion(i < this->data_->ima_.size());
+ return this->data_->ima_[i];
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_MONO_OBASED_RLE_IMAGE_HH