r3522: Reorganization of the sandbox

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2009-03-13 Etienne FOLIO <folio@lrde.epita.fr> Reorganization of the sandbox. Moved a lot of things... * folio/canevas_dt.hh: Remove. * folio/chamfer.cc: Remove. * folio/distance_front.cc: Remove. * folio/distance_front_new.hh: Remove. * folio/dt.cc: Remove. * folio/dt.hh: Remove. * folio/dt.spe.hh: Remove. * folio/dt_old/canevas_dt.hh: New. * folio/dt_old/chamfer.cc: New. * folio/dt_old/distance_front.cc: New. * folio/dt_old/distance_front_new.hh: New. * folio/dt_old/dt.cc: New. * folio/dt_old/dt.hh: New. * folio/dt_old/dt.spe.hh: New. * folio/dt_old/naive.cc: New. * folio/dt_old/psn.cc: New. * folio/dt_old/psn_log.cc: New. * folio/dt_old: New. * folio/histo/compute_histo_rgb.hh: Remove. * folio/histo: Remove. * folio/mln/histo: New. * folio/mln/value: New. * folio/mln: New. * folio/naive.cc: Remove. * folio/psn.cc: Remove. * folio/psn_log.cc: Remove. * folio/test/canvas/dt.hh: Remove. * folio/test/canvas/dt.spe.hh: Remove. * folio/test/canvas: Remove. * folio/test/chamfer.cc: Remove. * folio/test/dt.cc: Remove. * folio/test/dt/canvas: New. * folio/test/dt/chamfer.cc: New. * folio/test/dt/dt.cc: New. * folio/test/dt/dt_bench.cc: New. * folio/test/dt/dt_maze.cc: New. * folio/test/dt/naive.cc: New. * folio/test/dt/psn.cc: New. * folio/test/dt/psn_log.cc: New. * folio/test/dt/tmp.ppm: New. * folio/test/dt: New. * folio/test/dt_bench.cc: Remove. * folio/test/dt_maze.cc: Remove. * folio/test/naive.cc: Remove. * folio/test/psn.cc: Remove. * folio/test/psn_log.cc: Remove. * folio/test/tmp.ppm: Remove. * folio/value/pipo.hh: Remove. * folio/value: Remove. --- dt_old/canevas_dt.hh | 231 ++++++++++++++++++++++ dt_old/chamfer.cc | 206 ++++++++++++++++++++ dt_old/distance_front.cc | 88 ++++++++ dt_old/distance_front_new.hh | 420 +++++++++++++++++++++++++++++++++++++++++ dt_old/dt.cc | 59 +++++ dt_old/dt.hh | 101 +++++++++ dt_old/dt.spe.hh | 123 ++++++++++++ dt_old/naive.cc | 142 +++++++++++++ dt_old/psn.cc | 203 +++++++++++++++++++ dt_old/psn_log.cc | 290 ++++++++++++++++++++++++++++ mln/histo/compute_histo_rgb.hh | 36 +++ mln/value/pipo.hh | 107 ++++++++++ test/dt/canvas/dt.hh | 101 +++++++++ test/dt/canvas/dt.spe.hh | 123 ++++++++++++ test/dt/chamfer.cc | 52 +++++ test/dt/dt.cc | 66 ++++++ test/dt/dt_bench.cc | 53 +++++ test/dt/dt_maze.cc | 124 ++++++++++++ test/dt/naive.cc | 142 +++++++++++++ test/dt/psn.cc | 203 +++++++++++++++++++ test/dt/psn_log.cc | 290 ++++++++++++++++++++++++++++ 21 files changed, 3160 insertions(+) Index: trunk/milena/sandbox/folio/psn.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/psn_log.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/distance_front.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/naive.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/chamfer.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/dt.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/dt.spe.hh (deleted) =================================================================== Index: trunk/milena/sandbox/folio/canevas_dt.hh (deleted) =================================================================== Index: trunk/milena/sandbox/folio/dt.hh (deleted) =================================================================== Index: trunk/milena/sandbox/folio/distance_front_new.hh (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/psn.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/psn_log.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/naive.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/dt_maze.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/chamfer.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/dt_bench.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/dt.cc (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/tmp.ppm (deleted) =================================================================== Index: trunk/milena/sandbox/folio/test/dt/psn.cc =================================================================== --- trunk/milena/sandbox/folio/test/dt/psn.cc (revision 0) +++ trunk/milena/sandbox/folio/test/dt/psn.cc (revision 3522) @@ -0,0 +1,203 @@ +// 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_DT_CHAMFER_HH +# define MLN_DT_CHAMFER_HH + +# include <queue> +# include <map> +# include <cmath> + +# include <mln/core/concept/image.hh> +# include <mln/make/w_window.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/literal/zero.hh> + +# include <iostream> + +namespace mln +{ + + namespace dt + { + + /*! Propagation using a single neighborhood (PSN). + * + * \param[in] input_ The input image. + * \param[in] nbh The chamfer window to use for distance calcul. + * \param[in] max Max value of the output image. + * \return A distance map. + * + * \pre \p img has to be initialized. + */ + template<typename I, typename N> + mln_ch_value(I, unsigned) + psn(const Image<I>& input_, const N& nbh, unsigned max); + + +# ifndef MLN_INCLUDE_ONLY + + + namespace impl + { + } // end of namespace mln::dt::impl + + + + // Facade. + + template<typename I, typename N> + inline + mln_ch_value(I, unsigned) + psn(const Image<I>& input_, const N& nbh, unsigned max) + { + // Preconditions. + const I& input = exact(input_); + mln_precondition(input.is_valid()); + + // Types. + typedef mln_point(I) point; + + // Initialization of output. + mln_ch_value(I, unsigned) output; + initialize(output, input); + + // Initialization. + // { + + std::map<unsigned, std::queue<point> > bucket; + unsigned bucket_size = 0; + + mln_fwd_piter(I) p(input.domain()); + for_all(p) + if (input(p)) + { + output(p) = literal::zero; + bucket[0].push(p); + ++bucket_size; + } + else + output(p) = max; + + unsigned d = 0; + + // } + + while (bucket_size != 0) + { + std::queue<point> bucket_d = bucket[d]; + while (! bucket_d.empty()) + { + point p = bucket_d.front(); + bucket_d.pop(); + --bucket_size; + + if (output(p) == d) + { + mln_qiter(N) n(nbh, p); + + for_all(n) + if (output.has(n)) + { + unsigned newOut = output(p) + n.w(); + + if (newOut < output(n)) + { + output(n) = newOut; + bucket[newOut].push(n); + ++bucket_size; + } + } + } + } + bucket.erase(d); + ++d; + } + + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // ! MLN_DT_CHAMFER_HH + +#include <iostream> +#include <mln/core/image/image2d.hh> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/pw/value.hh> + +int main() +{ + using namespace mln; + + image2d<bool> ima(5,5); + bool vals[] = { 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0}; + data::fill(ima, vals); + + image2d<bool> msk(5,5); + bool rest[] = { 1, 0, 1, 1, 1, + 1, 0, 1, 1, 1, + 1, 1, 0, 0, 0, + 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1}; + data::fill(msk, rest); + + int ws[] = { 2, 1, 2, + 1, 0, 1, + 2, 1, 2 }; + image2d<unsigned> out; + out = dt::psn(ima | pw::value(msk), make::w_window2d(ws), 50); + + debug::println(ima | pw::value(msk)); + debug::println(out); + +// image2d<bool> ima = io::pbm::load("../../img/c01.pbm"); + +// image2d<value::int_u8> out2(out.domain()); +// level::stretch(out, out2); + +// io::pgm::save(out2, "out.pgm"); +} Index: trunk/milena/sandbox/folio/test/dt/psn_log.cc =================================================================== --- trunk/milena/sandbox/folio/test/dt/psn_log.cc (revision 0) +++ trunk/milena/sandbox/folio/test/dt/psn_log.cc (revision 3522) @@ -0,0 +1,290 @@ + +// 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_DT_CHAMFER_HH +# define MLN_DT_CHAMFER_HH + +# include <vector> +# include <queue> +# include <map> +# include <cmath> + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/literal/zero.hh> + +#include <mln/core/image/image2d.hh> +# include <mln/debug/println.hh> + +namespace mln +{ + + namespace dt + { + + /*! Propagation using a single neighborhood (PSN). + * + * \param[in] input_ The input image. + * \param[in] chamfer The chamfer window to use for distance calcul. + * \return A pair <distance map, closest point map>. + * + * \pre \p img has to be initialized. + */ + template<typename I, typename N> + mln_ch_value(I, unsigned) + psn(const Image<I>& input_, const N& nbh); + + +# ifndef MLN_INCLUDE_ONLY + + + namespace impl + { + + template <typename BP> + class compare + { + public: + bool + operator()(const BP& lhs, const BP& rhs) const + { + return lhs.second > rhs.second; + } + }; + + template <typename D> + unsigned + sq(const D& dp) + { + unsigned res = 0; + + for (unsigned i = 0; i < D::dim; ++i) + res += std::abs(dp[i]); // FIXME: dp[i] * dp[i]; + + return res; + } + + template <typename BP> + unsigned + size(const std::map<unsigned, std::queue<BP> >& bucket, + int d) + { + unsigned s = 0; + typename std::map<unsigned, std::queue<BP> >::const_iterator i; + for (i = bucket.begin(); i != bucket.end(); ++i) + if (i->first >= d) + s += i->second.size(); + return s; + } + + template <typename BP> + unsigned + size(const std::map<unsigned, std::queue<BP> >& bucket) + { + unsigned s = 0; + typename std::map<unsigned, std::queue<BP> >::const_iterator i; + for (i = bucket.begin(); i != bucket.end(); ++i) + s += i->second.size(); + return s; + } + + template <typename BP> + void + print(const std::map<unsigned, std::queue<BP> >& bucket) + { + typename std::map<unsigned, std::queue<BP> >::const_iterator i; + int d = -1; + for (i = bucket.begin(); i != bucket.end(); ++i) + { + if (i->first != d) + { + d = i->first; + std::cout << std::endl << d << ": "; + } + std::queue<BP> qu = i->second; // copy + std::vector<BP> v; + v.push_back(qu.front()); qu.pop(); + typename std::vector<BP>::const_iterator j; + for (j = v.begin(); j != v.end(); ++j) + std::cout << j->first << " "; // point + } + std::cout << std::endl; + } + + } // end of namespace mln::dt::impl + + + + // Facade. + + template<typename I, typename N> + inline + mln_ch_value(I, unsigned) + psn(const Image<I>& input_, const N& nbh) + { + const I& input = exact(input_); + mln_precondition(input.is_valid()); + + mln_ch_value(I, unsigned) D; + initialize(D, input); + + static const unsigned M = 666; // FIXME + + // Initialization. + typedef mln_point(I) point; + typedef mln_dpoint(I) dpoint; + typedef std::pair<point, dpoint> BP; + + std::map<unsigned, std::queue<BP> > bucket; + unsigned bucket_size = 0; + + mln_fwd_piter(I) p(input.domain()); + for_all(p) + if (input(p)) + { + D(p) = literal::zero; + bucket[0].push(BP(p, literal::zero)); + ++bucket_size; + } + else + D(p) = M; + + debug::println(input); + debug::println(D); + impl::print(bucket); + + unsigned d = 0; + + while (impl::size(bucket, d) != 0) + { + + mln_invariant(impl::size(bucket) == bucket_size); + + std::cout << "PROCESSING d = " << d << std::endl; + + std::queue<BP>& bucket_d = bucket[d]; + + while (! bucket_d.empty()) + { + point p = bucket_d.front().first; + dpoint dp = bucket_d.front().second; + + bucket_d.pop(); + --bucket_size; + + std::cout << "pop " << p << " at D=" << D(p) << std::endl; + + if (D(p) == d) + { + mln_niter(N) n_(nbh, p); + + for_all(n_) + if (D.has(n_)) + { + dpoint n = n_ - p; + unsigned newD = impl::sq(dp + n); + + std::cout << " n=" << n_ << " at D=" << D(n_) + << " and newD=" << newD + << (newD < D(p + n) ? " push" : "") + << std::endl; + + if (newD < D(p + n)) // p + n = p + n_ - p = n_ + { + D(n_) = newD; + bucket[newD].push(BP(p + n, dp + n)); + ++bucket_size; + } + } + } + } + ++d; + } + + return D; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // ! MLN_DT_CHAMFER_HH + +#include <iostream> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/pw/value.hh> + +int main() +{ + using namespace mln; + +// image2d<bool> ima(5,5); +// bool vals[] = { 1, 1, 1, 0, 0, +// 0, 0, 1, 0, 0, +// 0, 0, 1, 0, 0, +// 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0 }; + + image2d<bool> ima(3,3); + bool vals[] = { 1, 0, 0, + 0, 0, 0, + 0, 0, 0}; + data::fill(ima, vals); + + image2d<bool> msk(3,3); + bool rest[] = { 1, 0, 1, + 1, 0, 1, + 1, 1, 1}; + data::fill(msk, rest); + + image2d<unsigned> out; + out = dt::psn(ima | pw::value(msk), c4()); + + debug::println(ima | pw::value(msk)); + debug::println(out); + +// image2d<bool> ima = io::pbm::load("../../img/c01.pbm"); + +// image2d<value::int_u8> out2(out.domain()); +// level::stretch(out, out2); + +// io::pgm::save(out2, "out.pgm"); +} Index: trunk/milena/sandbox/folio/test/dt/naive.cc =================================================================== --- trunk/milena/sandbox/folio/test/dt/naive.cc (revision 0) +++ trunk/milena/sandbox/folio/test/dt/naive.cc (revision 3522) @@ -0,0 +1,142 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// +// 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 TODO + * + * \brief Defines a function that creates a distance map corresponding to a + * given image. + */ + +#ifndef MLN_DT_NAIVE_HH +# define MLN_DT_NAIVE_HH + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/function.hh> +# include <mln/literal/zero.hh> +# include <mln/accu/min.hh> + +namespace mln +{ + + namespace dt + { + + /*! Calculates the distance map corresponding to a given image + * + * \param[in] input_ The binary reference image. + * \param[in] fun_ The function used for distance aclculus. + * \return New distance map image. + * + * \pre \p input_ has to be initialized. + * + * \fixme Use instead of R the result type of F::operator(). + */ + template <typename I, typename F> + inline + mln_ch_value(I, mln_result(F)) + naive(const Image<I>& input_, const Function_v2v<F>& fun_); + + +# ifndef MLN_INCLUDE_ONLY + + // Facade. + + template <typename I, typename F> + inline + mln_ch_value(I, mln_result(F)) + naive(const Image<I>& input_, const Function_v2v<F>& fun_) + { + const I& input = exact(input_); + const F& fun = exact(fun_); + mln_precondition(input.is_valid()); + + mln_ch_value(I, mln_result(F)) output; + initialize(output, input); + + mln_piter(I) p(input.domain()); + for_all(p) + { + if (input(p)) + output(p) = literal::zero; + else + { + // p is in the background so the distance has to be computed. + accu::min_<mln_result(F)> min; + min.init(); + + mln_piter(I) q(input.domain()); + for_all(q) + if (input(q)) + { + // q is in the object. +// metal::vec<2, int> vp = p.to_point(), vq = q.to_point(); +// min.take(fun_(vp, vq)); + min.take(fun(p - q)); + } + output(p) = min; + } + } + + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // ! MLN_DT_NAIVE_HH + +#include <iostream> +#include <mln/debug/println.hh> +#include <mln/core/image/image2d.hh> +#include <mln/data/fill.hh> +#include <mln/fun/v2v/norm.hh> + +int main() +{ + using namespace mln; + + { + image2d<bool> ima(5,5); + bool vals[] = { 1, 1, 1, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; + + data::fill(ima, vals); + debug::println(ima); + + typedef fun::v2v::l2_norm< algebra::vec<2,float>, float > L2; + image2d<float> out = dt::naive(ima, L2()); + + std::cerr << "Distance:" << std::endl; + debug::println(out); + } +} Index: trunk/milena/sandbox/folio/test/dt/dt_maze.cc =================================================================== --- trunk/milena/sandbox/folio/test/dt/dt_maze.cc (revision 0) +++ trunk/milena/sandbox/folio/test/dt/dt_maze.cc (revision 3522) @@ -0,0 +1,124 @@ +/*! + * \file dt.cc + * \author ornthalas <ornthalas@gmail.com> + */ + +#include <iostream> +#include <mln/core/image/image2d.hh> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/io/ppm/load.hh> +#include <mln/io/ppm/save.hh> +#include <mln/io/pbm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/data/paste.hh> +#include <mln/value/int_u8.hh> +#include <mln/value/rgb8.hh> + +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/pw/all.hh> + +#include "../dt/path.hh" +// #include "../dt/raw_path_fast.hh" +// #include "../dt/raw_path_slow.hh" + +int main() +{ + using namespace mln; + + typedef image2d<value::rgb8> I; + typedef mln_point_(I) point; + point start; + point end; + + I ima = io::ppm::load<value::rgb8>("tmp.ppm"); // "../img/monkeys_april.ppm"); + mln_fwd_piter_(I) p(ima.domain()); + mln_bkd_piter_(I) pp(ima.domain()); + + // Create window + int ws[] = { 3, 2, 3, + 2, 0, 2, + 3, 2, 3 }; + + // Search green point + std::cout << "search green point..." << std::endl; + for_all(p) + if (ima(p) == value::rgb8(0, 255, 0)) + { + start = p; + break; + } + std::cout << " => green point is " << start << std::endl << std::endl; + + // Search red point + std::cout << "search red point..." << std::endl; + for_all(pp) + if (ima(pp) == value::rgb8(255, 0, 0)) + { + end = pp; + break; + } + std::cout << " => red point is " << end << std::endl << std::endl; + + // Create mask + std::cout << "create mask..." << std::endl; + mln_ch_value_(I, bool) mask; + initialize(mask, ima); + + for_all(p) + mask(p) = (ima(p) != value::rgb8(0, 0, 0)); + std::cout << " => saving mask.pbm..." << std::endl; + io::pbm::save(mask, "mask.pbm"); + std::cout << " => saved !" << std::endl << std::endl; + + // Create input + std::cout << "create input..." << std::endl; + mln_ch_value_(I, bool) input; + initialize(input, ima); + + for_all(p) + input(p) = (p == end); + std::cout << " => saving input.pbm..." << std::endl; + io::pbm::save(input, "input.pbm"); + std::cout << " => saved !" << std::endl << std::endl; + + // Create return image + std::cout << "create output..." << std::endl; + image2d<point> out; + std::cout << " => done !" << std::endl << std::endl; + + std::cout << "call path algorithm..." << std::endl; + out = dt::path(input | (pw::value(mask) == pw::cst(true)), + make::w_window2d(ws), mln_max(unsigned)); + std::cout << " => done !" << std::endl << std::endl; + + // Create output + std::cout << "create return image" << std::endl; + I ret; + initialize(ret, ima); + point c = start; + + // Copy inut into ret + std::cout << "copy original image into return image..." << std::endl; + for_all(p) + ret(p) = ima(p); + std::cout << " => done !" << std::endl << std::endl; + + // Create path into ret + std::cout << "create path into return image..." << std::endl; + while (c != end) + { + ret(c) = value::rgb8(255, 0, 0); + c = out(c); + } + std::cout << " => done !" << std::endl << std::endl; + + // save + std::cout << " => saving ret.ppm..." << std::endl; + io::ppm::save(ret, "ret.ppm"); + std::cout << " => saved !" << std::endl << std::endl; +} Index: trunk/milena/sandbox/folio/test/dt/chamfer.cc =================================================================== --- trunk/milena/sandbox/folio/test/dt/chamfer.cc (revision 0) +++ trunk/milena/sandbox/folio/test/dt/chamfer.cc (revision 3522) @@ -0,0 +1,52 @@ + +#include <iostream> +#include <mln/core/image/image2d.hh> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/value/int_u8.hh> + +#include "../dt/chamfer.hh" + +int main() +{ + using namespace mln; + + w_window2d_int chamfer = make::mk_chamfer_3x3_int<1, 2>(); + + { +// image2d<bool> ima(5,5); +// bool vals[] = { 1, 1, 1, 0, 0, +// 0, 0, 1, 0, 0, +// 0, 0, 1, 0, 0, +// 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0 }; + +// data::fill(ima, vals); +// debug::println(ima); + +// std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out; +// for (int i = 0; i < 999; ++i) +// out = dt::chamfer(ima, chamfer); + +// std::cerr << "Distance:" << std::endl; +// debug::println(out.first); +// std::cerr << "PPP:" << std::endl; +// debug::println(out.second); + + image2d<bool> ima = io::pbm::load("../../img/lena.pbm"); + + std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out; + out = dt::chamfer(ima, chamfer); + + image2d<value::int_u8> out2(out.first.domain()); + level::stretch(out.first, out2); + + io::pgm::save(out2, "out.pgm"); + + } +} Index: trunk/milena/sandbox/folio/test/dt/dt_bench.cc =================================================================== --- trunk/milena/sandbox/folio/test/dt/dt_bench.cc (revision 0) +++ trunk/milena/sandbox/folio/test/dt/dt_bench.cc (revision 3522) @@ -0,0 +1,53 @@ +/*! + * \file dt.cc + * \author ornthalas <ornthalas@gmail.com> + */ + +#include <iostream> +#include <mln/core/image/image2d.hh> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/data/paste.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/pw/value.hh> + +// #include "../dt/dmap.hh" +#include "../dt/raw_dmap_fast.hh" +#include "../dt/raw_dmap_slow.hh" + +// #include "../dt/iz.hh" +// #include "../dt/raw_iz_fast.hh" +// #include "../dt/raw_iz_slow.hh" + +// #include "../dt/cp.hh" +// #include "../dt/raw_cp_fast.hh" +// #include "../dt/raw_cp_slow.hh" + +int main() +{ + using namespace mln; + + image2d<bool> ima = io::pbm::load("lena.pbm"); + + int ws[] = { 3, 2, 3, + 2, 0, 2, + 3, 2, 3 }; + image2d<unsigned> out; +// for (int i = 0; i < 20; ++i) + out = dt::raw_dmap_fast(ima, make::w_window2d(ws), 666666); + + image2d<value::int_u8> out2(out.domain()); + level::stretch(out, out2); + + io::pgm::save(out2, "out.pgm"); +} + Index: trunk/milena/sandbox/folio/test/dt/canvas/dt.hh =================================================================== --- trunk/milena/sandbox/folio/test/dt/canvas/dt.hh (revision 0) +++ trunk/milena/sandbox/folio/test/dt/canvas/dt.hh (revision 3522) @@ -0,0 +1,101 @@ +/*! + * \file psn.cc + * \author ornthalas <ornthalas@gmail.com> + */ + +#ifndef DT_HH +# define DT_HH + +// The 'fastest' specialization is in: +# include "dt.spe.hh" + +namespace mln +{ + + namespace dt + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt(const Image<I>& input_, const N& nbh, const unsigned max); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + // Generic functor. + + template <typename I_, typename N_, typename L_> + struct dt_functor + { + typedef I_ I; + typedef N_ N; + typedef L_ L; + + const I& input; + const N& nbh; + unsigned max; + + dt_functor(const I_& input, const N_& nbh, const unsigned max) + : input(input), + nbh(nbh), + max(max) + {} + + void init() {} + }; + + + // Generic implementation. + + namespace generic + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(const Image<I>& input, const N& nbh, const unsigned max) + { + trace::entering("dt::impl::generic::dt_"); + + typedef dt_functor<I, N, L> F; + F f(input, nbh, max); + canvas::dt<F> run(f); + + trace::exiting("dt::impl::generic::dt_"); + return run.output; + } + + } // end of namespace mln::dt::impl::generic + + } // end of namespace mln::dt::impl + + + // Facade. + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt(const Image<I>& input, const N& nbh, const unsigned max) + { + trace::entering("dt::dt"); + mln_precondition(exact(input).is_valid()); + + mln_ch_value(I, L) output = + impl::dt_(mln_trait_image_speed(I)(), + exact(input), nbh, max); + + trace::exiting("dt::dt"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // !DT_HH Index: trunk/milena/sandbox/folio/test/dt/canvas/dt.spe.hh =================================================================== --- trunk/milena/sandbox/folio/test/dt/canvas/dt.spe.hh (revision 0) +++ trunk/milena/sandbox/folio/test/dt/canvas/dt.spe.hh (revision 3522) @@ -0,0 +1,123 @@ +/*! + * \file test_psn.spe.hh + * \author ornthalas <ornthalas@gmail.com> + */ + +#ifndef DT_SPE_HH +# define DT_SPE_HH + +# ifndef DT_HH +# error "Forbidden inclusion of *.spe.hh" +# endif // ! DT_HH + +# include "canevas_dt.hh" + +namespace mln +{ + + namespace dt + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt(const Image<I>& input_, const N& nbh, const unsigned max); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + + // Fwd decl of the Generic version. + + namespace generic + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(const Image<I>& input_, const N& nbh, const unsigned max); + + } // end of namespace mln::dt::impl::generic + + + // Fastest functor. + + template <typename I_, typename N_, typename L_> + struct dt_fasfunctor + { + typedef I_ I; + typedef N_ N; + typedef L_ L; + + const I& input; + const N& nbh; + unsigned max; + + dt_fasfunctor(const I_& input, const N_& nbh, const unsigned max) + : input(input), + nbh(nbh), + max(max) + {} + + void init() {} + }; + + + // Fastest implementation. + + namespace fastest + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(const I& input, const N& nbh, const unsigned max) + { + trace::entering("dt::impl::dt_fas"); + + typedef dt_fasfunctor<I,N,L> F; + F f(input, nbh, max); + canvas::dt_fastest<F> run(f); +b + trace::exiting("dt::impl::dt_fas"); + return run.output; + } + + } // end of namespace mln::dt::impl::fastest + + + // Disjunction between "fastest" and "not fastest". + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(trait::image::speed::any, + const I& input, const N& nbh, const unsigned max) + { + return generic::dt_(input, nbh, max); + } + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(trait::image::speed::fastest, + const I& input, const N& nbh, const unsigned max) + { + return fastest::dt_(input, nbh, max); + } + + + } // end of namespace mln::dt::impl + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + + +#endif // !DT_SPE_HH Index: trunk/milena/sandbox/folio/test/dt/dt.cc =================================================================== --- trunk/milena/sandbox/folio/test/dt/dt.cc (revision 0) +++ trunk/milena/sandbox/folio/test/dt/dt.cc (revision 3522) @@ -0,0 +1,66 @@ +/*! + * \file dt.cc + * \author ornthalas <ornthalas@gmail.com> + */ + +#include <iostream> +#include <mln/core/image/image2d.hh> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/data/paste.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/pw/value.hh> + +#include "../dt/dmap.hh" +// #include "../dt/raw_dmap_fast.hh" +// #include "../dt/raw_dmap_slow.hh" + +// #include "../dt/path.hh" +// #include "../dt/raw_path_fast.hh" +// #include "../dt/raw_path_slow.hh" + +// #include "../dt/cp.hh" +// #include "../dt/raw_cp_fast.hh" +// #include "../dt/raw_cp_slow.hh" + +int main() +{ + using namespace mln; + + image2d<bool> ima(5,5); + bool vals[] = { 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0}; + data::fill(ima, vals); + + image2d<bool> msk(5,5); + bool rest[] = { 1, 0, 1, 1, 1, + 1, 0, 1, 1, 1, + 1, 1, 0, 0, 0, + 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1}; + data::fill(msk, rest); + + int ws[] = { 3, 2, 3, + 2, 0, 2, + 3, 2, 3 }; + +// image2d<mln_point_(image2d<bool>)> out; + image2d<unsigned> out; + out = dt::dmap(ima | pw::value(msk), make::w_window2d(ws), 50); + +// debug::println(ima); + debug::println(ima | pw::value(msk)); + debug::println(out); +} Index: trunk/milena/sandbox/folio/test/dt/tmp.ppm =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: trunk/milena/sandbox/folio/test/dt/tmp.ppm ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: trunk/milena/sandbox/folio/dt_old/psn.cc =================================================================== --- trunk/milena/sandbox/folio/dt_old/psn.cc (revision 0) +++ trunk/milena/sandbox/folio/dt_old/psn.cc (revision 3522) @@ -0,0 +1,203 @@ +// 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_DT_CHAMFER_HH +# define MLN_DT_CHAMFER_HH + +# include <queue> +# include <map> +# include <cmath> + +# include <mln/core/concept/image.hh> +# include <mln/make/w_window.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/literal/zero.hh> + +# include <iostream> + +namespace mln +{ + + namespace dt + { + + /*! Propagation using a single neighborhood (PSN). + * + * \param[in] input_ The input image. + * \param[in] nbh The chamfer window to use for distance calcul. + * \param[in] max Max value of the output image. + * \return A distance map. + * + * \pre \p img has to be initialized. + */ + template<typename I, typename N> + mln_ch_value(I, unsigned) + psn(const Image<I>& input_, const N& nbh, unsigned max); + + +# ifndef MLN_INCLUDE_ONLY + + + namespace impl + { + } // end of namespace mln::dt::impl + + + + // Facade. + + template<typename I, typename N> + inline + mln_ch_value(I, unsigned) + psn(const Image<I>& input_, const N& nbh, unsigned max) + { + // Preconditions. + const I& input = exact(input_); + mln_precondition(input.is_valid()); + + // Types. + typedef mln_point(I) point; + + // Initialization of output. + mln_ch_value(I, unsigned) output; + initialize(output, input); + + // Initialization. + // { + + std::map<unsigned, std::queue<point> > bucket; + unsigned bucket_size = 0; + + mln_fwd_piter(I) p(input.domain()); + for_all(p) + if (input(p)) + { + output(p) = literal::zero; + bucket[0].push(p); + ++bucket_size; + } + else + output(p) = max; + + unsigned d = 0; + + // } + + while (bucket_size != 0) + { + std::queue<point> bucket_d = bucket[d]; + while (! bucket_d.empty()) + { + point p = bucket_d.front(); + bucket_d.pop(); + --bucket_size; + + if (output(p) == d) + { + mln_qiter(N) n(nbh, p); + + for_all(n) + if (output.has(n)) + { + unsigned newOut = output(p) + n.w(); + + if (newOut < output(n)) + { + output(n) = newOut; + bucket[newOut].push(n); + ++bucket_size; + } + } + } + } + bucket.erase(d); + ++d; + } + + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // ! MLN_DT_CHAMFER_HH + +#include <iostream> +#include <mln/core/image/image2d.hh> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/pw/value.hh> + +int main() +{ + using namespace mln; + + image2d<bool> ima(5,5); + bool vals[] = { 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0}; + data::fill(ima, vals); + + image2d<bool> msk(5,5); + bool rest[] = { 1, 0, 1, 1, 1, + 1, 0, 1, 1, 1, + 1, 1, 0, 0, 0, + 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1}; + data::fill(msk, rest); + + int ws[] = { 2, 1, 2, + 1, 0, 1, + 2, 1, 2 }; + image2d<unsigned> out; + out = dt::psn(ima | pw::value(msk), make::w_window2d(ws), 50); + + debug::println(ima | pw::value(msk)); + debug::println(out); + +// image2d<bool> ima = io::pbm::load("../../img/c01.pbm"); + +// image2d<value::int_u8> out2(out.domain()); +// level::stretch(out, out2); + +// io::pgm::save(out2, "out.pgm"); +} Index: trunk/milena/sandbox/folio/dt_old/canevas_dt.hh =================================================================== --- trunk/milena/sandbox/folio/dt_old/canevas_dt.hh (revision 0) +++ trunk/milena/sandbox/folio/dt_old/canevas_dt.hh (revision 3522) @@ -0,0 +1,231 @@ +/*! + * \file canevas_dt.hh + * \author ornthalas <ornthalas@gmail.com> + */ + +#ifndef CANEVAS_DT_HH +# define CANEVAS_DT_HH + +# include <queue> +# include <map> +# include <mln/core/concept/image.hh> +# include <mln/make/w_window.hh> +# include <mln/literal/zero.hh> + +# include <mln/core/concept/neighborhood.hh> + +namespace mln +{ + + namespace canvas + { + + // General version. + + template <typename F> + struct dt + { + // Functor. + F& f; + + typedef typename F::I I; + typedef typename F::N N; + typedef typename F::L L; + typedef mln_psite(I) point; + + mln_ch_value(I, L) output; + + // Ctor. + dt(F& f); + + void init(); + void run(); + + std::map<unsigned, std::queue<point> > bucket; + unsigned bucket_size; + + unsigned current_distance; + }; + + template <typename F> + struct dt_fastest + { + // Functor. + F& f; + + typedef typename F::I I; + typedef typename F::N N; + typedef typename F::L L; + typedef mln_psite(I) point; + + mln_ch_value(I, L) output; + + // Ctor. + dt_fastest(F& f); + + void init(); + void run(); + + std::map<unsigned, std::queue<point> > bucket; + unsigned bucket_size; + + unsigned current_distance; + }; + +# ifndef MLN_INCLUDE_ONLY + + /*-------------. + | canvas::dt. | + `-------------*/ + + template <typename F> + dt<F>::dt(F& f) + : f(f), + bucket_size(0), + current_distance(0) + { + trace::entering("canvas::dt"); + + this->init(); + this->run(); + + trace::exiting("canvas::dt"); + } + + template <typename F> + void + dt<F>::init() + { + this->f.init(); + initialize(this->output, this->f.input); + + mln_fwd_piter(I) p(this->f.input.domain()); + for_all(p) + if (this->f.input(p)) + { + this->output(p) = literal::zero; + this->bucket[0].push(p); + ++this->bucket_size; + } + else + this->output(p) = this->max; + } + + template <typename F> + void + dt<F>::run() + { + while (this->bucket_size != 0) + { + std::queue<point> bucket_d = this->bucket[this->current_distance]; + while (! bucket_d.empty()) + { + point p = bucket_d.front(); + bucket_d.pop(); + --bucket_size; + + if (this->output(p) == this->current_distance) + { + mln_qiter(N) n(this->nbh, p); + + for_all(n) + if (this->output.has(n)) + { + unsigned new_out = this->output(p) + n.w(); + + if (new_out < this->output(n)) + { + this->output(n) = new_out; + this->bucket[new_out].push(n); + ++this->bucket_size; + } + } + } + } + this->bucket.erase(this->current_distance); + ++this->current_distance; + } + } + + /*---------------------. + | canvas::dt_fastest. | + `---------------------*/ + template <typename F> + dt_fastest<F>::dt_fastest(F& f) + : f(f), + bucket_size(0), + current_distance(0) + { + trace::entering("canvas::dt"); + + this->init(); + this->run(); + + trace::exiting("canvas::dt"); + } + + template <typename F> + void + dt_fastest<F>::init() + { + this->f.init(); + initialize(this->output, this->f.input); + + mln_fwd_piter(I) p(this->f.input.domain()); + for_all(p) + if (this->f.input(p)) + { + this->output(p) = literal::zero; + this->bucket[0].push(p); + ++this->bucket_size; + } + else + this->output(p) = this->max; + } + + template <typename F> + void + dt_fastest<F>::run() + { + while (this->bucket_size != 0) + { + std::queue<point> bucket_d = this->bucket[this->current_distance]; + while (! bucket_d.empty()) + { + point p = bucket_d.front(); + bucket_d.pop(); + --bucket_size; + + if (this->output(p) == this->current_distance) + { + mln_qiter(N) n(this->nbh, p); + + for_all(n) + if (this->output.has(n)) + { + unsigned new_out = this->output(p) + n.w(); + + if (new_out < this->output(n)) + { + this->output(n) = new_out; + this->bucket[new_out].push(n); + ++this->bucket_size; + } + } + } + } + this->bucket.erase(this->current_distance); + ++this->current_distance; + } + } + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace mln::canvas + +} // end of namespace mln + + +#endif // ! MLN_CANVAS_DT_HH Index: trunk/milena/sandbox/folio/dt_old/dt.hh =================================================================== --- trunk/milena/sandbox/folio/dt_old/dt.hh (revision 0) +++ trunk/milena/sandbox/folio/dt_old/dt.hh (revision 3522) @@ -0,0 +1,101 @@ +/*! + * \file psn.cc + * \author ornthalas <ornthalas@gmail.com> + */ + +#ifndef DT_HH +# define DT_HH + +// The 'fastest' specialization is in: +# include "dt.spe.hh" + +namespace mln +{ + + namespace dt + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt(const Image<I>& input_, const N& nbh, unsigned max); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + // Generic functor. + + template <typename I_, typename N_, typename L_> + struct dt_functor + { + typedef I_ I; + typedef N_ N; + typedef L_ L; + + const I& input; + const N& nbh; + unsigned max; + + dt_functor(const I_& input, const N_& nbh, const unsigned max) + : input(input), + nbh(nbh), + max(max) + {} + + void init() {} + }; + + + // Generic implementation. + + namespace generic + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(const Image<I>& input, const N& nbh, unsigned max) + { + trace::entering("dt::impl::generic::dt_"); + + typedef dt_functor<I, N, L> F; + F f(input, nbh, max); + canvas::dt<F> run(f); + + trace::exiting("dt::impl::generic::dt_"); + return run.output; + } + + } // end of namespace mln::dt::impl::generic + + } // end of namespace mln::dt::impl + + + // Facade. + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt(const Image<I>& input, const N& nbh, unsigned max) + { + trace::entering("dt::dt"); + mln_precondition(exact(input).is_valid()); + + mln_ch_value(I, L) output = + impl::dt_(mln_trait_image_speed(I)(), + exact(input), nbh, max); + + trace::exiting("dt::dt"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // !DT_HH Index: trunk/milena/sandbox/folio/dt_old/psn_log.cc =================================================================== --- trunk/milena/sandbox/folio/dt_old/psn_log.cc (revision 0) +++ trunk/milena/sandbox/folio/dt_old/psn_log.cc (revision 3522) @@ -0,0 +1,290 @@ + +// 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_DT_CHAMFER_HH +# define MLN_DT_CHAMFER_HH + +# include <vector> +# include <queue> +# include <map> +# include <cmath> + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/literal/zero.hh> + +#include <mln/core/image/image2d.hh> +# include <mln/debug/println.hh> + +namespace mln +{ + + namespace dt + { + + /*! Propagation using a single neighborhood (PSN). + * + * \param[in] input_ The input image. + * \param[in] chamfer The chamfer window to use for distance calcul. + * \return A pair <distance map, closest point map>. + * + * \pre \p img has to be initialized. + */ + template<typename I, typename N> + mln_ch_value(I, unsigned) + psn(const Image<I>& input_, const N& nbh); + + +# ifndef MLN_INCLUDE_ONLY + + + namespace impl + { + + template <typename BP> + class compare + { + public: + bool + operator()(const BP& lhs, const BP& rhs) const + { + return lhs.second > rhs.second; + } + }; + + template <typename D> + unsigned + sq(const D& dp) + { + unsigned res = 0; + + for (unsigned i = 0; i < D::dim; ++i) + res += std::abs(dp[i]); // FIXME: dp[i] * dp[i]; + + return res; + } + + template <typename BP> + unsigned + size(const std::map<unsigned, std::queue<BP> >& bucket, + int d) + { + unsigned s = 0; + typename std::map<unsigned, std::queue<BP> >::const_iterator i; + for (i = bucket.begin(); i != bucket.end(); ++i) + if (i->first >= d) + s += i->second.size(); + return s; + } + + template <typename BP> + unsigned + size(const std::map<unsigned, std::queue<BP> >& bucket) + { + unsigned s = 0; + typename std::map<unsigned, std::queue<BP> >::const_iterator i; + for (i = bucket.begin(); i != bucket.end(); ++i) + s += i->second.size(); + return s; + } + + template <typename BP> + void + print(const std::map<unsigned, std::queue<BP> >& bucket) + { + typename std::map<unsigned, std::queue<BP> >::const_iterator i; + int d = -1; + for (i = bucket.begin(); i != bucket.end(); ++i) + { + if (i->first != d) + { + d = i->first; + std::cout << std::endl << d << ": "; + } + std::queue<BP> qu = i->second; // copy + std::vector<BP> v; + v.push_back(qu.front()); qu.pop(); + typename std::vector<BP>::const_iterator j; + for (j = v.begin(); j != v.end(); ++j) + std::cout << j->first << " "; // point + } + std::cout << std::endl; + } + + } // end of namespace mln::dt::impl + + + + // Facade. + + template<typename I, typename N> + inline + mln_ch_value(I, unsigned) + psn(const Image<I>& input_, const N& nbh) + { + const I& input = exact(input_); + mln_precondition(input.is_valid()); + + mln_ch_value(I, unsigned) D; + initialize(D, input); + + static const unsigned M = 666; // FIXME + + // Initialization. + typedef mln_point(I) point; + typedef mln_dpoint(I) dpoint; + typedef std::pair<point, dpoint> BP; + + std::map<unsigned, std::queue<BP> > bucket; + unsigned bucket_size = 0; + + mln_fwd_piter(I) p(input.domain()); + for_all(p) + if (input(p)) + { + D(p) = literal::zero; + bucket[0].push(BP(p, literal::zero)); + ++bucket_size; + } + else + D(p) = M; + + debug::println(input); + debug::println(D); + impl::print(bucket); + + unsigned d = 0; + + while (impl::size(bucket, d) != 0) + { + + mln_invariant(impl::size(bucket) == bucket_size); + + std::cout << "PROCESSING d = " << d << std::endl; + + std::queue<BP>& bucket_d = bucket[d]; + + while (! bucket_d.empty()) + { + point p = bucket_d.front().first; + dpoint dp = bucket_d.front().second; + + bucket_d.pop(); + --bucket_size; + + std::cout << "pop " << p << " at D=" << D(p) << std::endl; + + if (D(p) == d) + { + mln_niter(N) n_(nbh, p); + + for_all(n_) + if (D.has(n_)) + { + dpoint n = n_ - p; + unsigned newD = impl::sq(dp + n); + + std::cout << " n=" << n_ << " at D=" << D(n_) + << " and newD=" << newD + << (newD < D(p + n) ? " push" : "") + << std::endl; + + if (newD < D(p + n)) // p + n = p + n_ - p = n_ + { + D(n_) = newD; + bucket[newD].push(BP(p + n, dp + n)); + ++bucket_size; + } + } + } + } + ++d; + } + + return D; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // ! MLN_DT_CHAMFER_HH + +#include <iostream> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/pw/value.hh> + +int main() +{ + using namespace mln; + +// image2d<bool> ima(5,5); +// bool vals[] = { 1, 1, 1, 0, 0, +// 0, 0, 1, 0, 0, +// 0, 0, 1, 0, 0, +// 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0 }; + + image2d<bool> ima(3,3); + bool vals[] = { 1, 0, 0, + 0, 0, 0, + 0, 0, 0}; + data::fill(ima, vals); + + image2d<bool> msk(3,3); + bool rest[] = { 1, 0, 1, + 1, 0, 1, + 1, 1, 1}; + data::fill(msk, rest); + + image2d<unsigned> out; + out = dt::psn(ima | pw::value(msk), c4()); + + debug::println(ima | pw::value(msk)); + debug::println(out); + +// image2d<bool> ima = io::pbm::load("../../img/c01.pbm"); + +// image2d<value::int_u8> out2(out.domain()); +// level::stretch(out, out2); + +// io::pgm::save(out2, "out.pgm"); +} Index: trunk/milena/sandbox/folio/dt_old/distance_front.cc =================================================================== --- trunk/milena/sandbox/folio/dt_old/distance_front.cc (revision 0) +++ trunk/milena/sandbox/folio/dt_old/distance_front.cc (revision 3522) @@ -0,0 +1,88 @@ +// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory +// (LRDE) +// +// 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/transform/distance_front.cc +/// +/// Test on mln::transform::distance_front. + +#include <mln/core/var.hh> +#include <mln/core/image/image2d.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/make/w_window2d_int.hh> +#include <mln/value/int_u8.hh> +#include <mln/data/fill.hh> +#include <mln/debug/println.hh> +#include <mln/opt/at.hh> +#include <mln/level/compare.hh> + +#include <mln/transform/internal/distance_functor.hh> +#include "distance_front_new.hh" + + +int main() +{ + using namespace mln; + using value::int_u8; + + typedef image2d<bool> I; + + I input(9, 9); + data::fill(input, false); + opt::at(input, 4, 4) = true; + + + int_u8 dmax = 18; + mln_VAR(nbh, c4()); + + int ws[] = { 0, 9, 0, 9, 0, + 9, 6, 4, 6, 9, + 0, 4, 0, 4, 0, + 9, 6, 4, 6, 9, + 0, 9, 0, 9, 0 }; + mln_VAR(w_win, make::w_window2d_int(ws)); + + + transform::internal::distance_functor<I> f; + image2d<int_u8> ref, output; + + ref = canvas::impl::generic::distance_front(input, + nbh, + w_win, + dmax, + f); + // debug::println("ref", ref); + + output = canvas::impl::distance_front_fastest(input, + nbh, + w_win, + dmax, + f); + // debug::println("output", output); + + mln_invariant(output == ref); +} Property changes on: trunk/milena/sandbox/folio/dt_old/distance_front.cc ___________________________________________________________________ Name: svn:mergeinfo + Index: trunk/milena/sandbox/folio/dt_old/naive.cc =================================================================== --- trunk/milena/sandbox/folio/dt_old/naive.cc (revision 0) +++ trunk/milena/sandbox/folio/dt_old/naive.cc (revision 3522) @@ -0,0 +1,142 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// +// 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 TODO + * + * \brief Defines a function that creates a distance map corresponding to a + * given image. + */ + +#ifndef MLN_DT_NAIVE_HH +# define MLN_DT_NAIVE_HH + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/function.hh> +# include <mln/literal/zero.hh> +# include <mln/accu/min.hh> + +namespace mln +{ + + namespace dt + { + + /*! Calculates the distance map corresponding to a given image + * + * \param[in] input_ The binary reference image. + * \param[in] fun_ The function used for distance aclculus. + * \return New distance map image. + * + * \pre \p input_ has to be initialized. + * + * \fixme Use instead of R the result type of F::operator(). + */ + template <typename I, typename F> + inline + mln_ch_value(I, mln_result(F)) + naive(const Image<I>& input_, const Function_v2v<F>& fun_); + + +# ifndef MLN_INCLUDE_ONLY + + // Facade. + + template <typename I, typename F> + inline + mln_ch_value(I, mln_result(F)) + naive(const Image<I>& input_, const Function_v2v<F>& fun_) + { + const I& input = exact(input_); + const F& fun = exact(fun_); + mln_precondition(input.is_valid()); + + mln_ch_value(I, mln_result(F)) output; + initialize(output, input); + + mln_piter(I) p(input.domain()); + for_all(p) + { + if (input(p)) + output(p) = literal::zero; + else + { + // p is in the background so the distance has to be computed. + accu::min_<mln_result(F)> min; + min.init(); + + mln_piter(I) q(input.domain()); + for_all(q) + if (input(q)) + { + // q is in the object. +// metal::vec<2, int> vp = p.to_point(), vq = q.to_point(); +// min.take(fun_(vp, vq)); + min.take(fun(p - q)); + } + output(p) = min; + } + } + + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // ! MLN_DT_NAIVE_HH + +#include <iostream> +#include <mln/debug/println.hh> +#include <mln/core/image/image2d.hh> +#include <mln/data/fill.hh> +#include <mln/fun/v2v/norm.hh> + +int main() +{ + using namespace mln; + + { + image2d<bool> ima(5,5); + bool vals[] = { 1, 1, 1, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; + + data::fill(ima, vals); + debug::println(ima); + + typedef fun::v2v::l2_norm< algebra::vec<2,float>, float > L2; + image2d<float> out = dt::naive(ima, L2()); + + std::cerr << "Distance:" << std::endl; + debug::println(out); + } +} Index: trunk/milena/sandbox/folio/dt_old/chamfer.cc =================================================================== --- trunk/milena/sandbox/folio/dt_old/chamfer.cc (revision 0) +++ trunk/milena/sandbox/folio/dt_old/chamfer.cc (revision 3522) @@ -0,0 +1,206 @@ +// 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_DT_CHAMFER_HH +# define MLN_DT_CHAMFER_HH + +# include <mln/core/concept/image.hh> +# include <mln/make/w_window.hh> + +namespace mln +{ + + namespace dt + { + + /*! Distance tranform by chamfer application. + * + * \param[in] input_ The input image. + * \param[in] chamfer The chamfer window to use for distance calcul. + * \return A pair (distance map, nearest point map). + * + * \pre \p img has to be initialized. + */ + template<typename I, typename T> + std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))> + chamfer(const Image<I>& input_, + w_window<mln_dpoint(I), T> chamfer); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + /*! Computes a pass of the chamfer DT algorithm. + * + * \param[in] p Iterator on the input image to use. + * \param[in] chamfer The chamfer window to use for distance calcul. + * \param[in] input The input image. + * \param[out] outputDistance The distance map updated. + * \param[out] outputnearest The nearest points map updated. + */ + template<typename Q, typename I, typename T> + inline + void + chamfer_pass(const w_window<mln_dpoint(I), T> chamfer, + const I& input, + mln_ch_value(I, T)& outputDistance, + mln_ch_value(I, mln_point(I))& outputNearest) + { + typedef w_window<mln_dpoint(I), T> W; + + Q p(input.domain()); + mln_qiter(W) q(chamfer, p); + for_all(p) + { + std::pair<T, mln_point(I)> min(mln_max(T), p); + + for_all(q) + if (input.has(q) && outputDistance(q) != mln_max(T)) + { + T v = outputDistance(q) + q.w(); + + if (v < min.first) + { + min.first = v; + min.second = outputNearest(q); + } + } + + if (min.first < outputDistance(p)) + { + outputDistance(p) = min.first; + outputNearest(p) = min.second; + } + } + } + + } // end of namespace mln::dt::impl + + + + // Facade. + + template<typename I, typename T> + inline + std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))> + chamfer(const Image<I>& input_, + w_window<mln_dpoint(I), T> chamfer) + { + typedef w_window<mln_dpoint(I), T> W; + + const I& input = exact(input_); + mln_precondition(input.is_valid()); + + mln_ch_value(I, T) outputDistance; + initialize(outputDistance, input); + + mln_ch_value(I, mln_point(I)) outputNearest; + initialize(outputNearest, input); + + // Initialization. + { + mln_fwd_piter(I) p(input.domain()); + for_all(p) + { + outputDistance(p) = input(p) ? literal::zero : mln_max(T); + outputNearest(p) = p; + } + } + + // First pass. + impl::chamfer_pass<mln_fwd_piter(I)> + (chamfer, input, outputDistance, outputNearest); + + chamfer.sym(); + + // Second pass. + impl::chamfer_pass<mln_bkd_piter(I)> + (chamfer, input, outputDistance, outputNearest); + + return std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))> + (outputDistance, outputNearest); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + +#endif // ! MLN_DT_CHAMFER_HH + +#include <iostream> +#include <mln/core/image/image2d.hh> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/value/int_u8.hh> + +int main() +{ + using namespace mln; + + w_window2d_int chamfer = make::mk_chamfer_3x3_int<1, 2>(); + + { +// image2d<bool> ima(5,5); +// bool vals[] = { 1, 1, 1, 0, 0, +// 0, 0, 1, 0, 0, +// 0, 0, 1, 0, 0, +// 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0 }; + +// data::fill(ima, vals); +// debug::println(ima); + +// std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out; +// for (int i = 0; i < 999; ++i) +// out = dt::chamfer(ima, chamfer); + +// std::cerr << "Distance:" << std::endl; +// debug::println(out.first); +// std::cerr << "PPP:" << std::endl; +// debug::println(out.second); + + image2d<bool> ima = io::pbm::load("../../img/c01.pbm"); + + std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out; + out = dt::chamfer(ima, chamfer); + + image2d<value::int_u8> out2(out.first.domain()); + level::stretch(out.first, out2); + + io::pgm::save(out2, "out.pgm"); + + } +} Index: trunk/milena/sandbox/folio/dt_old/distance_front_new.hh =================================================================== --- trunk/milena/sandbox/folio/dt_old/distance_front_new.hh (revision 0) +++ trunk/milena/sandbox/folio/dt_old/distance_front_new.hh (revision 3522) @@ -0,0 +1,420 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// 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_CANVAS_DISTANCE_FRONT_HH +# define MLN_CANVAS_DISTANCE_FRONT_HH + +/// \file mln/canvas/distance_front.hh +/// +/// Discrete distance canvas by front propagation. + +# include <vector> +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/core/concept/weighted_window.hh> +# include <mln/data/fill.hh> +# include <mln/accu/max.hh> +# include <mln/extension/adjust_fill.hh> + + +namespace mln +{ + + namespace canvas + { + + /// Discrete front distance canvas. + template <typename I, + typename N, typename W, typename D, + typename F> + mln_ch_value(I, D) + distance_front(const Image<I>& input, + const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, D max, + F& functor); + + + +# ifndef MLN_INCLUDE_ONLY + + + // Tests. + + namespace internal + { + + template <typename I, + typename N, typename W, typename D, + typename F> + void + distance_front_tests(const Image<I>& input_, + const Neighborhood<N>& nbh_, + const Weighted_Window<W>& w_win_, + D max, + F& functor) + { + const I& input = exact(input_); + const N& nbh = exact(nbh_); + const W& w_win = exact(w_win_); + + mln_precondition(input.is_valid()); + mln_precondition(nbh.is_valid()); + + (void) input; + (void) nbh; + (void) max; + (void) functor; + } + + + } // of namespace mln::canvas::internal + + + + // Implementations. + + namespace impl + { + + namespace generic + { + + template <typename I, + typename N, typename W, typename D, + typename F> + mln_ch_value(I, D) + distance_front(const Image<I>& input_, + const Neighborhood<N>& nbh_, + const Weighted_Window<W>& w_win_, + D max, + F& functor) + { + trace::entering("canvas::impl::generic::distance_front"); + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + const W& w_win = exact(w_win_); + + mln_precondition(input.is_valid()); + mln_precondition(w_win.is_valid()); + + typedef mln_site(I) P; + typedef std::vector<P> bucket_t; + + // Distance map. + mln_ch_value(I, D) dmap; + initialize(dmap, input); + data::fill(dmap, max); + + // Mod determination. + unsigned mod; + { + accu::max<unsigned> m; + for (unsigned i = 0; i < w_win.size(); ++i) + m.take(w_win.w(i)); + mod = unsigned(m) + 1; + } + + // Aux data. + std::vector<bucket_t> bucket(mod); + unsigned bucket_size = 0; + + // Initialization. + { + functor.init(input); // <-- init + mln_piter(I) p(input.domain()); + mln_niter(N) n(nbh, p); + for_all(p) + if (functor.inqueue_p_wrt_input_p(input(p))) // <-- inqueue_p_wrt_input_p + { + dmap(p) = 0; + for_all(n) + if (input.domain().has(n) && + functor.inqueue_p_wrt_input_n(input(n))) // <-- inqueue_p_wrt_input_n + { + bucket[0].push_back(p); + ++bucket_size; + break; + } + } + } // end of Initialization. + + // Propagation. + { + P p; + mln_qiter(W) q(w_win, p); + for (unsigned d = 0; bucket_size != 0; ++d) + { + bucket_t& bucket_d = bucket[d % mod]; + for (unsigned i = 0; i < bucket_d.size(); ++i) + { + p = bucket_d[i]; + + if (dmap(p) == max) + { + // Saturation so stop. + bucket_size = bucket_d.size(); // So at end bucket_size == 0. + break; + } + + if (dmap(p) < d) + // p has already been processed, having a distance less than d. + continue; + + for_all(q) + if (dmap.domain().has(q) && dmap(q) > d) + { + unsigned d_ = d + q.w(); + if (d_ < dmap(q)) + { + dmap(q) = d_; + functor.process(p, q); // <- process + bucket[d_ % mod].push_back(q); + ++bucket_size; + } + } + } + bucket_size -= bucket_d.size(); + bucket_d.clear(); + } + } // end of Propagation. + + trace::exiting("canvas::impl::generic::distance_front"); + return dmap; + } + + } // of namespace mln::canvas::impl::generic + + + + // Fastest version. + + template <typename I, + typename N, typename W, typename D, + typename F> + mln_ch_value(I, D) + distance_front_fastest(const Image<I>& input_, + const Neighborhood<N>& nbh_, + const Weighted_Window<W>& w_win_, + D max, F& functor) + { + trace::entering("canvas::impl::distance_front_fastest"); + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + const W& w_win = exact(w_win_); + + mln_precondition(input.is_valid()); + mln_precondition(w_win.is_valid()); + + // Handling w_win. + extension::adjust(input, w_win); + const unsigned n_ws = w_win.size(); + util::array<int> dp = offsets_wrt(input, w_win.win()); + mln_invariant(dp.nelements() == n_ws); + + // Distance map. + mln_ch_value(I, D) dmap; + initialize(dmap, input); + data::fill(dmap, max); + + // Mod determination. + unsigned mod; + { + accu::max<unsigned> m; + for (unsigned i = 0; i < w_win.size(); ++i) + m.take(w_win.w(i)); + mod = unsigned(m) + 1; + } + + // Aux data. + typedef std::vector<unsigned> bucket_t; + std::vector<bucket_t> bucket(mod); + unsigned bucket_size = 0; + + // Initialization. + { + functor.init_(input); // <-- init + + // For the extension to be ignored: + extension::fill(input, true); + extension::fill(dmap, D(0)); + + mln_pixter(const I) p(input); + mln_nixter(const I, N) n(p, nbh); + for_all(p) + if (functor.inqueue_p_wrt_input_p_(p.val())) // <-- inqueue_p_wrt_input_p + { + dmap.element(p.offset()) = 0; + for_all(n) + if (functor.inqueue_p_wrt_input_n_(n.val())) // <-- inqueue_p_wrt_input_n + { + bucket[0].push_back(p.offset()); + ++bucket_size; + break; + } + } + } // end of Initialization. + + // Propagation. + { + unsigned p; + + for (unsigned d = 0; bucket_size != 0; ++d) + { + bucket_t& bucket_d = bucket[d % mod]; + for (unsigned i = 0; i < bucket_d.size(); ++i) + { + p = bucket_d[i]; + + if (dmap.element(p) == max) + { + // Saturation so stop. + bucket_size = bucket_d.size(); // So at end bucket_size == 0. + break; + } + + if (dmap.element(p) < d) + // p has already been processed, having a distance less than d. + continue; + + for (unsigned i = 0; i < n_ws; ++i) + { + unsigned q = p + dp[i]; + if (dmap.element(q) > d) + { + unsigned d_ = d + w_win.w(i); + if (d_ < dmap.element(q)) + { + dmap.element(q) = d_; + functor.process_(p, q); // <- process + bucket[d_ % mod].push_back(q); + ++bucket_size; + } + } + } + } + bucket_size -= bucket_d.size(); + bucket_d.clear(); + } + } // end of Propagation. + + trace::exiting("canvas::impl::distance_front_fastest"); + return dmap; + } + + + } // of namespace mln::canvas::impl + + + + // Dispatch. + + namespace internal + { + + template <typename I, + typename N, typename W, typename D, + typename F> + inline + mln_ch_value(I, D) + distance_front_dispatch(metal::false_, + const Image<I>& input, + const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, + D max, F& functor) + { + return impl::generic::distance_front(input, nbh, max, w_win, functor); + } + + template <typename I, + typename N, typename W, typename D, + typename F> + inline + mln_ch_value(I, D) + distance_front_dispatch(metal::true_, + const Image<I>& input, + const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, + D max, F& functor) + { + return impl::distance_front_fastest(input, nbh, w_win, max, functor); + // return impl::generic::distance_front(input, nbh, w_win, max, functor); + } + + template <typename I, + typename N, typename W, typename D, + typename F> + inline + mln_ch_value(I, D) + distance_front_dispatch(const Image<I>& input, + const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, + D max, F& functor) + { + enum { + test = mlc_equal(mln_trait_image_speed(I), + trait::image::speed::fastest)::value + && + mln_is_simple_neighborhood(N)::value + }; + return distance_front_dispatch(metal::bool_<test>(), + input, nbh, w_win, max, functor); + } + + + } // of namespace mln::canvas::internal + + + + // Facade. + + template <typename I, + typename N, typename W, typename D, + typename F> + inline + mln_ch_value(I, D) + distance_front(const Image<I>& input, + const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, + D max, F& functor) + { + trace::entering("canvas::distance_front"); + + internal::distance_front_tests(input, nbh, w_win, max, functor); + + mln_ch_value(I,D) output; + output = internal::distance_front_dispatch(input, nbh, w_win, max, functor); + + trace::exiting("canvas::distance_front"); + return output; + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::canvas + +} // end of namespace mln + + +#endif // ! MLN_CANVAS_DISTANCE_FRONT_HH Index: trunk/milena/sandbox/folio/dt_old/dt.cc =================================================================== --- trunk/milena/sandbox/folio/dt_old/dt.cc (revision 0) +++ trunk/milena/sandbox/folio/dt_old/dt.cc (revision 3522) @@ -0,0 +1,59 @@ +/*! + * \file dt.cc + * \author ornthalas <ornthalas@gmail.com> + */ + +#include <iostream> +#include <mln/core/image/image2d.hh> +#include <mln/debug/println.hh> +#include <mln/make/win_chamfer.hh> +#include <mln/data/fill.hh> +#include <mln/core/alias/neighb2d.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/level/stretch.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/pw/value.hh> + +#include "dt.hh" + +int main() +{ + using namespace mln; + + image2d<bool> ima(5,5); + bool vals[] = { 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0}; + data::fill(ima, vals); + + image2d<bool> msk(5,5); + bool rest[] = { 1, 0, 1, 1, 1, + 1, 0, 1, 1, 1, + 1, 1, 0, 0, 0, + 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1}; + data::fill(msk, rest); + + int ws[] = { 2, 1, 2, + 1, 0, 1, + 2, 1, 2 }; + image2d<unsigned> out; + out = dt::dt(ima | pw::value(msk), make::w_window2d(ws), 50); + + debug::println(ima | pw::value(msk)); + debug::println(out); + +// image2d<bool> ima = io::pbm::load("../../img/c01.pbm"); + +// image2d<value::int_u8> out2(out.domain()); +// level::stretch(out, out2); + +// io::pgm::save(out2, "out.pgm"); +} Index: trunk/milena/sandbox/folio/dt_old/dt.spe.hh =================================================================== --- trunk/milena/sandbox/folio/dt_old/dt.spe.hh (revision 0) +++ trunk/milena/sandbox/folio/dt_old/dt.spe.hh (revision 3522) @@ -0,0 +1,123 @@ +/*! + * \file test_psn.spe.hh + * \author ornthalas <ornthalas@gmail.com> + */ + +#ifndef DT_SPE_HH +# define DT_SPE_HH + +# ifndef DT_HH +# error "Forbidden inclusion of *.spe.hh" +# endif // ! DT_HH + +# include "canevas_dt.hh" + +namespace mln +{ + + namespace dt + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt(const Image<I>& input_, const N& nbh, unsigned max); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + + // Fwd decl of the Generic version. + + namespace generic + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(const Image<I>& input_, const N& nbh, unsigned max); + + } // end of namespace mln::dt::impl::generic + + + // Fastest functor. + + template <typename I_, typename N_, typename L_> + struct dt_fasfunctor + { + typedef I_ I; + typedef N_ N; + typedef L_ L; + + const I& input; + const N& nbh; + unsigned max; + + dt_fasfunctor(const I_& input, const N_& nbh, const unsigned max) + : input(input), + nbh(nbh), + max(max) + {} + + void init() {} + }; + + + // Fastest implementation. + + namespace fastest + { + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(const I& input, const N& nbh, unsigned max) + { + trace::entering("dt::impl::dt_fas"); + + typedef dt_fasfunctor<I,N,L> F; + F f(input, nbh, max); + canvas::dt_fastest<F> run(f); + + trace::exiting("dt::impl::dt_fas"); + return run.output; + } + + } // end of namespace mln::dt::impl::fastest + + + // Disjunction between "fastest" and "not fastest". + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(trait::image::speed::any, + const I& input, const N& nbh, unsigned max) + { + return generic::dt_(input, nbh, max); + } + + template<typename I, typename N, typename L> + inline + mln_ch_value(I, L) + dt_(trait::image::speed::fastest, + const I& input, const N& nbh, unsigned max) + { + return fastest::dt_(input, nbh, max); + } + + + } // end of namespace mln::dt::impl + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::dt + +} // end of namespace mln + + +#endif // !DT_SPE_HH Index: trunk/milena/sandbox/folio/mln/histo/compute_histo_rgb.hh =================================================================== --- trunk/milena/sandbox/folio/mln/histo/compute_histo_rgb.hh (revision 0) +++ trunk/milena/sandbox/folio/mln/histo/compute_histo_rgb.hh (revision 3522) @@ -0,0 +1,36 @@ +/*! + * \file compute_histo_rgb.cc + * \author etiennefolio <ornthalas@gmail.com> + */ + +#include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> +#include <mln/value/int_u8.hh> +#include <mln/value/rgb8.hh> +#include <iostream> +namespace mln +{ + namespace histo + { + + template <typename C, typename T> + image3d<C> compute_histo_rgb(image2d<T> ima) + { + // out + typedef value::int_u8::enc enc; + image3d<C> out(mln_max(enc) + abs(mln_min(enc)) + 1, + mln_max(enc) + abs(mln_min(enc)) + 1, + mln_max(enc) + abs(mln_min(enc)) + 1); + data::fill(out, mln_min(C)); + + // count + mln_fwd_piter(image2d<T>) p(ima.domain()); + for_all(p) + ++out(point3d(ima(p).red(), ima(p).green(), ima(p).blue())); + + // return + return out; + } + + } +} Index: trunk/milena/sandbox/folio/mln/value/pipo.hh =================================================================== --- trunk/milena/sandbox/folio/mln/value/pipo.hh (revision 0) +++ trunk/milena/sandbox/folio/mln/value/pipo.hh (revision 3522) @@ -0,0 +1,107 @@ +/*! + * \file pipo.hh + * \author etiennefolio <ornthalas@gmail.com> + */ + +#ifndef PIPO_HH_ +# define PIPO_HH_ + +# include <mln/value/int_s.hh> +# include <mln/value/int_u.hh> +# include <mln/value/float01.hh> + +namespace mln +{ + + namespace value { class pipo; } + + namespace trait + { + + template <> + struct value_< mln::value::pipo > + { + enum { + dim = 3 + }; + + typedef mln::value::int_s<3> comp_0; + typedef mln::value::float01_<8> comp_1; + typedef mln::value::int_u<7> comp_2; + }; + + } // end of namespace trait + + namespace value + { + class pipo + { + public: + + int_s<3> c0; + float01_<8> c1; + int_u<7> c2; + + pipo(); + pipo(int_s<3> _c0, + float01_<8> _c1, + int_u<7> _c2); + + pipo& operator=(const pipo& rhs); + }; + +# ifndef MLN_INCLUDE_ONLY + + inline + pipo::pipo() + : c0(mln_min(int_s<3>)), + c1(mln_min(float01_<8>)), + c2(mln_min(int_u<7>)) + { + } + + inline + pipo::pipo(int_s<3> _c0, + float01_<8> _c1, + int_u<7> _c2) + : c0(_c0), + c1(_c1), + c2(_c2) + { + } + + inline + pipo& + pipo::operator=(const pipo& rhs) + { + if (& rhs == this) + return *this; + this->c0 = rhs.c0; + this->c1 = rhs.c1; + this->c2 = rhs.c2; + return *this; + } + + inline + std::ostream& operator<<(std::ostream& ostr, const pipo& v) + { + return ostr << '(' << debug::format(v.c0) + << ',' << debug::format(v.c1) + << ',' << debug::format(v.c2) + << ')'; + } + +// dunno why this doesn't compile... *_*" + +// inline +// std::istream& operator>>(std::istream& istr, pipo& c) +// { +// return istr >> c.c0 >> c.c1 >> c.c2; +// } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace value +} + +#endif /* !PIPO_HH_ */
participants (1)
-
Etienne FOLIO