1938: value_enc_image: Add a value encode procedure.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Nicolas Ballas <ballas@lrde.epita.fr> value_enc_image: Add a value encode procedure. * tests/core/value_enc_image.cc: Update tests. * mln/core/pset_array.hh: Add a missing methods. * mln/core/value_encode.hh: New, encode an image into a value_enc ima. * mln/core/value_enc_image.hh: Add range insertion method. * mln/core/rle_encode.hh: Update the Copyright. mln/core/pset_array.hh | 9 ++- mln/core/rle_encode.hh | 2 mln/core/value_enc_image.hh | 62 ++++++++++++++++------ mln/core/value_encode.hh | 115 ++++++++++++++++++++++++++++++++++++++++++ tests/core/value_enc_image.cc | 82 +++++++++++++++++++++++++++++ 5 files changed, 250 insertions(+), 20 deletions(-) Index: tests/core/value_enc_image.cc --- tests/core/value_enc_image.cc (revision 1937) +++ tests/core/value_enc_image.cc (working copy) @@ -32,8 +32,32 @@ #include <mln/core/image2d.hh> #include <mln/core/value_enc_image.hh> -#include <iostream> +#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 "tests/data.hh" + +#include <mln/core/value_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() { @@ -49,10 +73,12 @@ p_runs_<point2d> pruns2; pruns0.insert(p_run<point2d>(make::point2d(0, 0), 2)); + pruns1.insert(p_run<point2d>(make::point2d(2, 4), 7)); pruns1.insert(p_run<point2d>(make::point2d(18, 42), 5)); pruns1.insert(p_run<point2d>(make::point2d(50, 76), 2)); pruns1.insert(p_run<point2d>(make::point2d(17,40), 6)); + pruns2.insert(p_run<point2d>(make::point2d(10,10), 5)); ima_type ima; @@ -74,4 +100,58 @@ i = 1; } } + + /// Basic test two + { + typedef value_enc_image<point2d, int> ima_type; + ima_type ima; + + ima.insert(p_run<point2d>(make::point2d(0, 0), 2), 0); + ima.insert(p_run<point2d>(make::point2d(10,10), 5), 2); + + ima.insert(p_run<point2d>(make::point2d(2, 4), 7), 1); + ima.insert(p_run<point2d>(make::point2d(18, 42), 5), 1); + ima.insert(p_run<point2d>(make::point2d(50, 76), 2), 1); + ima.insert(p_run<point2d>(make::point2d(17,40), 6), 1); + + + mln_piter_(ima_type) piter (ima.domain()); + int i = 0; + int nb = 0; + for_all(piter) + { + assert(ima(piter) == i); + + ++nb; + if (nb == 2) + i = 2; + if (nb == 7) + i = 1; + } + } + + /// A third test + { + using value::int_u8; + + image2d<int_u8> lena; + io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm"); + image2d<int_u8> cmp(lena.domain()); + + unsigned n; + image2d<unsigned> labels = + labeling::blobs((pw::value(lena) > pw::cst(172u)) | lena.domain(), + c4(), n); + + value_enc_image<point2d, int_u8> val_enc = + value_encode(level::transform(labels, fold_t())); + + level::fill(cmp, literal::zero); + level::paste(val_enc, cmp); + std::cout << val_enc.values().size() << std::endl; + + mln_assertion(cmp == level::transform(labels, fold_t())); + //io::pgm::save(cmp, "output.pgm"); + //io::pgm::save(level::transform(labels, fold_t()), "output2.pgm"); + } } Index: mln/core/pset_array.hh --- mln/core/pset_array.hh (revision 1937) +++ mln/core/pset_array.hh (working copy) @@ -181,6 +181,14 @@ return con_[i]; } + template <typename Pset> + inline + Pset& + pset_array<Pset>::operator[](unsigned i) + { + return con_[i]; + } + # endif // ! MLN_INCLUDE_ONLY @@ -236,7 +244,6 @@ typedef typename Pset::fwd_piter pset_fwd_piter_; - const pset_array<Pset>* pset_; pset_fwd_piter_ piter_; unsigned pos_; Index: mln/core/value_encode.hh --- mln/core/value_encode.hh (revision 0) +++ mln/core/value_encode.hh (revision 0) @@ -0,0 +1,115 @@ +// Copyright (C) 2007, 2008 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_VALUE_ENCODE_HH_ +# define MLN_CORE_VALUE_ENCODE_HH_ + +/*! \file mln/core/value_encode.hh + * + * \brief Definition of function which encodes an image in value_enc_image. + */ + +# include <mln/core/value_enc_image.hh> + +namespace mln +{ + + /*! + ** encode an image class to a value_enc_image + ** + ** @param input has to respect the Image concept. + ** The input image must be based on a regular grid. + ** @param ignore_zero says if zero has to be considered as a valid value + ** + ** @return value_enc_image + */ + template <typename I> + value_enc_image<mln_point(I), mln_value(I)> + value_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 + value_enc_image<mln_point(I), mln_value(I)> + value_encode(const Image<I>& input, bool ignore_zero) + { + value_enc_image<mln_point(I), mln_value(I)> output; + const I& ima = exact(input); + mln_piter(I) p (exact(input).domain()); + + unsigned len = 0; + mln_point(I) rstart; + mln_value(I) rvalue; + + 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 + { + //FIXME is it right?? + output.insert(p_run<mln_point(I)>(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_VALUE_ENCODE_HH_ Index: mln/core/value_enc_image.hh --- mln/core/value_enc_image.hh (revision 1937) +++ mln/core/value_enc_image.hh (working copy) @@ -30,7 +30,7 @@ /*! \file mln/core/value_enc_image.hh * - * \brief FIXME + * \brief Define the class value_enc_image. */ # include <mln/core/internal/image_primary.hh> @@ -40,6 +40,7 @@ # include <mln/core/p_runs.hh> # include <vector> +# include <mln/util/tracked_ptr.hh> namespace mln { @@ -51,7 +52,7 @@ namespace internal { - /// \internal Data structure for \c mln::rle_image<P,T>. + /// \internal Data structure for \c mln::value_enc_image<P,T>. template <typename P, typename T> struct data_< value_enc_image<P, T> > { @@ -94,7 +95,7 @@ /*! \brief Value encoded image. - * FIXME + * Associate a value to set of runs. */ template <typename P, typename T> class value_enc_image : @@ -107,7 +108,7 @@ typedef T value; typedef T& lvalue; typedef const T rvalue; - typedef mln::value::set<T> vset; + typedef typename std::vector<T> vset; /// Domain related typedefs typedef pset_array_psite< runs_psite<P> > psite; @@ -118,13 +119,13 @@ value_enc_image(); - /// Add a new range to the image. - void insert(const p_runs_<P>& pr, T value); + /// Add a new set of ranges to the image. + void insert(const p_runs_<P>& ps, T value); - /*! \brief Tell if the image has the given point site. - * - * \return True if the image has the point site, else false. - */ + /// Add a new range to the image + void insert(const p_run<P>& pr, T value); + + /// Tell if the image has the given point site. bool has(const psite& ps) const; /// Read-only access to the image value located at the site \site. @@ -141,7 +142,6 @@ /// Give the definition domain. const pset& domain() const; - }; @@ -181,25 +181,50 @@ const typename value_enc_image<P, T>::vset& value_enc_image<P, T>::values() const { - return vset::the(); + return this->data_->values_; } template <typename P, typename T> inline void - value_enc_image<P, T>::insert(const p_runs_<P>& pr, T value) + value_enc_image<P, T>::insert(const p_runs_<P>& ps, T value) { if (!this->has_data()) this->data_ = new internal::data_< value_enc_image<P,T> >(); - this->data_->domain_.insert(pr); + this->data_->domain_.insert(ps); this->data_->values_.push_back(value); } template <typename P, typename T> inline + void + value_enc_image<P, T>::insert(const p_run<P>& pr, T value) + { + unsigned i = 0; + typename std::vector<T>::iterator it; + + for (it = this->data_->values_.begin(); + it != this->data_->values_.end() && *it != value; + ++it) + ++i; + + if (it != this->data_->values_.end()) + this->data_->domain_[i].insert(pr); + else + { + p_runs_<P> ps = p_runs_<P> (); + ps.insert(pr); + this->data_->domain_.insert(ps); + this->data_->values_.push_back(value); + } + } + + template <typename P, typename T> + inline bool - value_enc_image<P, T>::has(const typename value_enc_image<P, T>::psite& site) const + value_enc_image<P, T>::has(const typename value_enc_image<P, T>::psite& site) + const { return this->data_->domain_.has(site); } @@ -207,7 +232,8 @@ template <typename P, typename T> inline typename value_enc_image<P, T>::rvalue - value_enc_image<P, T>::operator() (const typename value_enc_image<P, T>::psite& site) + value_enc_image<P, T>::operator() (const typename + value_enc_image<P, T>::psite& site) const { mln_precondition(this->has(site)); @@ -218,7 +244,8 @@ template <typename P, typename T> inline typename value_enc_image<P, T>::lvalue - value_enc_image<P, T>::operator() (const typename value_enc_image<P, T>::psite& site) + value_enc_image<P, T>::operator() (const typename + value_enc_image<P, T>::psite& site) { mln_precondition(this->has(site)); @@ -240,3 +267,4 @@ #endif // ! MLN_CORE_VALUE_ENC_IMAGE_CC_ + Index: mln/core/rle_encode.hh --- mln/core/rle_encode.hh (revision 1937) +++ mln/core/rle_encode.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 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
participants (1)
-
Nicolas Ballas