Commit 6494c5cb authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Complete Etienne's work.

	* folio/distance_front.cc: New.
	* folio/distance_front_new.hh: Make it compile.
	Fix missing work.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@3479 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent f4a58aac
2009-03-05 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Complete Etienne's work.
* folio/distance_front.cc: New.
* folio/distance_front_new.hh: Make it compile.
Fix missing work.
2009-03-04 Edwin Carlinet <carlinet@lrde.epita.fr>
Add methods to check attribute computing.
......
// 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/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);
}
......@@ -38,11 +38,7 @@
# include <mln/core/concept/weighted_window.hh>
# include <mln/data/fill.hh>
# include <mln/accu/max.hh>
//# include <mln/core/routine/duplicate.hh>
//# include <mln/core/site_set/p_queue_fast.hh>
//# include <queue>
//# include <mln/extension/adjust_fill.hh>
# include <mln/extension/adjust_fill.hh>
namespace mln
......@@ -75,11 +71,14 @@ namespace mln
typename F>
void
distance_front_tests(const Image<I>& input_,
const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, D max,
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());
......@@ -108,7 +107,9 @@ namespace mln
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,
const Neighborhood<N>& nbh_,
const Weighted_Window<W>& w_win_,
D max,
F& functor)
{
trace::entering("canvas::impl::generic::distance_front");
......@@ -148,61 +149,61 @@ namespace mln
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;
}
}
}
{
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)
bucket_t& bucket_d = bucket[d % mod];
for (unsigned i = 0; i < bucket_d.size(); ++i)
{
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;
}
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();
}
bucket_size -= bucket_d.size();
bucket_d.clear();
}
trace::exiting("canvas::impl::generic::distance_front");
return dmap;
}
} // end of Propagation.
trace::exiting("canvas::impl::generic::distance_front");
return dmap;
}
} // of namespace mln::canvas::impl::generic
......@@ -216,109 +217,113 @@ namespace mln
typename F>
mln_ch_value(I, D)
distance_front_fastest(const Image<I>& input_,
const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
const Neighborhood<N>& nbh_,
const Weighted_Window<W>& w_win_,
D max, F& functor)
{
trace::entering("canvas::impl::distance_front_fastest");
trace::entering("canvas::impl::distance_front_fastest");
const I& input = exact(input_);
const N& nbh = exact(nbh_);
const W& w_win = exact(w_win_);
const I& input = exact(input_);
const N& nbh = exact(nbh_);
const W& w_win = exact(w_win_);
// mln_precondition(input.is_valid()); // ?x
// mln_precondition(w_win.is_valid()); // ?x
extension::adjust(input, w_win); // ?
mln_precondition(input.is_valid());
mln_precondition(w_win.is_valid());
// typedef mln_site(I) P;
typedef std::vector<unsigned> bucket_t;
// 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);
// 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;
}
// 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;
// Aux data.
typedef std::vector<unsigned> bucket_t;
std::vector<bucket_t> bucket(mod);
unsigned bucket_size = 0;
// Initialization.
{
functor.init_(input); // <-- init
// Initialization.
{
functor.init_(input); // <-- init
// For the extension to be ignored: // ?
extension::fill(input, true); // ?
extension::fill(dmap, D(0)); // ?
// 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_(input(p))) // <-- inqueue_p_wrt_input_p
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;
}
{
bucket[0].push_back(p.offset());
++bucket_size;
break;
}
}
}
} // end of Initialization.
// Propagation.
{
unsigned p;
mln_qiter(W) q(w_win, p); // ?x-
// Propagation.
{
unsigned p;
for (unsigned d = 0; bucket_size != 0; ++d)
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;
p = bucket_d[i];
for_all(q)
{
if (dmap.domain().has(q) && dmap(q) > d)
{
unsigned d_ = d + q.w();
if (d_ < dmap(q))
if (dmap.element(p) == max)
{
dmap(q) = d_;
functor.process_(dmap.element(p), q); // <- process
bucket[d_ % mod].push_back(q);
++bucket_size;
// 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();
bucket_size -= bucket_d.size();
bucket_d.clear();
}
}
} // end of Propagation.
trace::exiting("canvas::impl::distance_front_fastest");
return dmap;
}
trace::exiting("canvas::impl::distance_front_fastest");
return dmap;
}
......@@ -355,7 +360,7 @@ namespace mln
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);
// return impl::generic::distance_front(input, nbh, w_win, max, functor);
}
template <typename I,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment