milena r1589: Add object based rle image and his test

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-12-04 Simon Nivault <simon.nivault@lrde.epita.fr> Add object based rle image and his test. * mln/core/obased_rle_encode.hh: New. * mln/core/obased_rle_image.hh: New. * tests/core/Makefile.am: Add following test. * tests/core/obased_rle_image.cc: New. * mln/core/internal/run_image.hh: Fix compression routine. * mln/core/mono_rle_encode.hh: Fix. * mln/core/rle_encode.hh: Fix. * tests/core/mono_rle_image.cc, * tests/core/rle_image.cc: Display compression. --- mln/core/internal/run_image.hh | 2 mln/core/mono_rle_encode.hh | 6 mln/core/obased_rle_encode.hh | 120 ++++++++++++++++ mln/core/obased_rle_image.hh | 292 +++++++++++++++++++++++++++++++++++++++++ mln/core/rle_encode.hh | 6 tests/core/Makefile.am | 2 tests/core/mono_rle_image.cc | 3 tests/core/obased_rle_image.cc | 78 ++++++++++ tests/core/rle_image.cc | 3 9 files changed, 507 insertions(+), 5 deletions(-) Index: trunk/milena/tests/core/mono_rle_image.cc =================================================================== --- trunk/milena/tests/core/mono_rle_image.cc (revision 1588) +++ trunk/milena/tests/core/mono_rle_image.cc (revision 1589) @@ -68,10 +68,11 @@ unsigned n; image2d<unsigned> labels = labeling::blobs((pw::value(lena) > pw::cst(172u)) | lena.domain(), c4(), n); - std::cout << n << std::endl; mono_rle_image<point2d, int_u8> rle = mono_rle_encode(level::transform(labels, fold_t()), 2); + std::cout << n << ", compression :" << rle.compression() << std::endl; + level::fill(cmp, literal::zero); level::paste(rle, cmp); Index: trunk/milena/tests/core/obased_rle_image.cc =================================================================== --- trunk/milena/tests/core/obased_rle_image.cc (revision 0) +++ trunk/milena/tests/core/obased_rle_image.cc (revision 1589) @@ -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/obased_rle_image.cc + * + * \brief Test on mln::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/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); + + obased_rle_image<point2d, int_u8> + rle = 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/tests/core/rle_image.cc =================================================================== --- trunk/milena/tests/core/rle_image.cc (revision 1588) +++ trunk/milena/tests/core/rle_image.cc (revision 1589) @@ -64,10 +64,11 @@ unsigned n; image2d<unsigned> labels = labeling::blobs((pw::value(lena) > pw::cst(172u)) | lena.domain(), c4(), n); - std::cout << n << std::endl; rle_image<point2d, int_u8> rle = rle_encode(level::transform(labels, fold_t())); + std::cout << n << ", compression :" << rle.compression() << std::endl; + level::fill(cmp, literal::zero); level::paste(rle, cmp); Index: trunk/milena/tests/core/Makefile.am =================================================================== --- trunk/milena/tests/core/Makefile.am (revision 1588) +++ trunk/milena/tests/core/Makefile.am (revision 1589) @@ -8,6 +8,7 @@ exact \ initialize \ mono_rle_image \ + obased_rle_image \ p_runs \ rle_image \ t_image @@ -17,6 +18,7 @@ exact_SOURCES = exact.cc initialize_SOURCES = initialize.cc mono_rle_image_SOURCES = mono_rle_image.cc +obased_rle_image_SOURCES = obased_rle_image.cc p_runs_SOURCES = p_runs.cc rle_image_SOURCES = rle_image.cc t_image_SOURCES = t_image.cc Index: trunk/milena/mln/core/mono_rle_encode.hh =================================================================== --- trunk/milena/mln/core/mono_rle_encode.hh (revision 1588) +++ trunk/milena/mln/core/mono_rle_encode.hh (revision 1589) @@ -94,7 +94,11 @@ else { output.insert(p_run<P>(rstart, len)); - len = 0; + if ((len = (!ignore_zero || ima(p) != literal::zero))) + { + rstart = p; + rvalue = ima(p); + } } } return output; Index: trunk/milena/mln/core/internal/run_image.hh =================================================================== --- trunk/milena/mln/core/internal/run_image.hh (revision 1588) +++ trunk/milena/mln/core/internal/run_image.hh (revision 1589) @@ -73,7 +73,7 @@ run_image_<T, P, E>::compression() const { return float(exact(this)->data_->size_mem()) / - float (sizeof(T) * exact(this)->data_->domain_->bbox().npoints()); + float (sizeof(T) * exact(this)->data_->domain_.bbox().npoints()); } # endif // ! MLN_INCLUDE_ONLY Index: trunk/milena/mln/core/obased_rle_encode.hh =================================================================== --- trunk/milena/mln/core/obased_rle_encode.hh (revision 0) +++ trunk/milena/mln/core/obased_rle_encode.hh (revision 1589) @@ -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_OBASED_RLE_ENCODE_HH +# define MLN_CORE_OBASED_RLE_ENCODE_HH + +/*! \file mln/core/obased_rle_encode.hh + * + * \brief Definintion of function which encodes an image in obased_rle_image. + */ + +# include <mln/core/obased_rle_image.hh> + +namespace mln +{ + + /*! + ** encode an image class to a obased_rle_image + ** + ** @param input has to respect the Image concept + ** + ** @return obased_rle_image + */ + template <typename I> + obased_rle_image<mln_point(I), mln_value(I)> + 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 + obased_rle_image<mln_point(I), mln_value(I)> + 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)); + } + + 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_OBASED_RLE_ENCODE_HH Index: trunk/milena/mln/core/obased_rle_image.hh =================================================================== --- trunk/milena/mln/core/obased_rle_image.hh (revision 0) +++ trunk/milena/mln/core/obased_rle_image.hh (revision 1589) @@ -0,0 +1,292 @@ +// 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_OBASED_RLE_IMAGE_HH +# define MLN_CORE_OBASED_RLE_IMAGE_HH + +/*! \file mln/core/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 <vector> + +namespace mln +{ + + // Fwd decl. + template <typename P, typename T> struct obased_rle_image; + + + namespace internal + { + + template <typename P, typename T> + struct data_< obased_rle_image<P,T> > + { + data_(const std::set<T>& values); + + /// Objects. + std::vector< std::vector<unsigned> > obj_; + + /// Bounding boxes of the objects. + std::vector< accu::bbox<P> > bbox_; + + /// Value of Objects. + 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_< obased_rle_image<P,T> > : default_image_< T, 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 obased_rle_image : public internal::run_image_< T, P, 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 obased_rle_image< tag::psite_<P>, tag::value_<T> > skeleton; + + + 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 std::vector<unsigned>& object(unsigned i) const; + + /// Give the bounding box of the i-th object. + const box_<P>& bbox_of_run(unsigned i) const; + + }; + + +# ifndef MLN_INCLUDE_ONLY + + namespace internal + { + + // internal::data_< obased_rle_image<P,T> > + + template <typename P, typename T> + inline + data_< obased_rle_image<P,T> >::data_(const std::set<T>& values) + : obj_(values.size()), + bbox_(values.size()) + { + std::copy(values.begin(), values.end(), + std::back_inserter(this->values_)); + } + + template <typename P, typename T> + inline + unsigned + data_< obased_rle_image<P,T> >::size_mem() const + { + return domain_.size_mem() + bbox_.size() + * (sizeof(T) + sizeof(box_<P>) + sizeof(std::vector<unsigned>)) + + sizeof(unsigned) * domain_.nruns(); + } + + } // end of namespace mln::internal + + template <typename P, typename T> + inline + obased_rle_image<P, T>::obased_rle_image(const std::set<T>& values) + { + this->data_ = new internal::data_< obased_rle_image<P,T> >(values); + } + + template <typename P, typename T> + inline + bool + obased_rle_image<P, T>::has_data() const + { + return this->data_->values_.size() != 0; + } + + template <typename P, typename T> + inline + const typename obased_rle_image<P, T>::vset& + obased_rle_image<P, T>::values() const + { + return vset::the(); + } + + template <typename P, typename T> + inline + 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 || + pr.first() > this->data_->domain_[this->data_->domain_.nruns() - 1].first()); + this->data_->domain_.insert(pr); + unsigned i; + for (i = 0; i < this->data_->values_.size() + && this->data_->values_[i] != value; ++i) + ; + mln_assertion(i != this->data_->values_.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()); + } + + template <typename P, typename T> + inline + typename obased_rle_image<P, T>::rvalue + obased_rle_image<P, T>::operator() (const typename obased_rle_image<P, T>::psite& site) + const + { + 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]; + } + + template <typename P, typename T> + inline + typename obased_rle_image<P, T>::lvalue + obased_rle_image<P, T>::operator() (const typename obased_rle_image<P, T>::psite& site) + { + 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]; + } + + template <typename P, typename T> + inline + const typename obased_rle_image<P, T>::pset& + obased_rle_image<P, T>::domain() const + { + return this->data_->domain_; + } + + template <typename P, typename T> + inline + const std::vector<unsigned>& + obased_rle_image<P, T>::object(unsigned i) const + { + mln_assertion(i < this->data_->obj_.size()); + return this->data_->obj_[i]; + } + + template <typename P, typename T> + inline + const box_<P>& + obased_rle_image<P, T>::bbox_of_run(unsigned i) const + { + mln_assertion(i < this->data_->bbox_.size()); + return this->data_->bbox_[i]; + } + + +# endif // ! MLN_INCLUDE_ONLY + + +} // end of namespace mln + + +#endif // ! MLN_CORE_OBASED_RLE_IMAGE_HH Index: trunk/milena/mln/core/rle_encode.hh =================================================================== --- trunk/milena/mln/core/rle_encode.hh (revision 1588) +++ trunk/milena/mln/core/rle_encode.hh (revision 1589) @@ -96,7 +96,11 @@ else { output.insert(p_run<P>(rstart, len), rvalue); - len = 0; + if ((len = (!ignore_zero || ima(p) != literal::zero))) + { + rstart = p; + rvalue = ima(p); + } } } return output;
participants (1)
-
nivaul_s@lrde.epita.fr