Commit 514b0904 authored by Guillaume Lazzara's avatar Guillaume Lazzara
Browse files

Improve influence zone geodesic.

	* mln/canvas/distance_geodesic.hh: Remove useless traces.

	* mln/transform/influence_zone_geodesic.hh: Add a specific fastest
	version and move some code...

	* mln/transform/influence_zone_geodesic_saturated.hh: ... here.

	* tests/transform/influence_zone_geodesic.cc: Update test
	according to the new interface.

	* tests/transform/Makefile.am,
	* tests/transform/influence_zone_geodesic_saturated.cc: New test.

git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@4722 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 785d4255
2009-11-18 Guillaume Lazzara <z@lrde.epita.fr>
Improve influence zone geodesic.
* mln/canvas/distance_geodesic.hh: Remove useless traces.
* mln/transform/influence_zone_geodesic.hh: Add a specific fastest
version and move some code...
* mln/transform/influence_zone_geodesic_saturated.hh: ... here.
* tests/transform/influence_zone_geodesic.cc: Update test
according to the new interface.
* tests/transform/Makefile.am,
* tests/transform/influence_zone_geodesic_saturated.cc: New test.
2009-11-09 Guillaume Lazzara <z@lrde.epita.fr>
 
Add box_runend_piter.
// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of Olena.
//
......@@ -51,8 +52,8 @@ namespace mln
template <typename I, typename N, typename D,
typename F>
mln_ch_value(I, D)
distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh, D max,
F& functor);
distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
D max, F& functor);
......@@ -67,7 +68,8 @@ namespace mln
template <typename I, typename N, typename D,
typename F>
void
distance_geodesic_tests(const Image<I>& input_, const Neighborhood<N>& nbh_, D max,
distance_geodesic_tests(const Image<I>& input_,
const Neighborhood<N>& nbh_, D max,
F& functor)
{
const I& input = exact(input_);
......@@ -98,8 +100,8 @@ namespace mln
template <typename I, typename N, typename D,
typename F>
mln_ch_value(I, D)
distance_geodesic(const Image<I>& input_, const Neighborhood<N>& nbh_, D max,
F& functor)
distance_geodesic(const Image<I>& input_, const Neighborhood<N>& nbh_,
D max, F& functor)
{
trace::entering("canvas::impl::generic::distance_geodesic");
......@@ -119,8 +121,6 @@ namespace mln
// Initialization.
{
trace::entering("initialization");
functor.init(input); // <-- init
data::fill(dmap, max);
......@@ -139,12 +139,10 @@ namespace mln
break;
}
}
trace::exiting("initialization");
}
// Propagation.
{
trace::entering("propagation");
P p;
mln_niter(N) n(nbh, p);
while (! q.is_empty())
......@@ -164,7 +162,6 @@ namespace mln
q.push(n);
}
}
trace::exiting("propagation");
}
trace::exiting("canvas::impl::generic::distance_geodesic");
......@@ -180,8 +177,10 @@ namespace mln
template <typename I, typename N, typename D,
typename F>
mln_ch_value(I, D)
distance_geodesic_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, D max,
F& functor)
distance_geodesic_fastest(const Image<I>& input_,
const Neighborhood<N>& nbh_,
D max,
F& functor)
{
trace::entering("canvas::impl::distance_geodesic_fastest");
......@@ -199,8 +198,6 @@ namespace mln
// Initialization.
{
trace::entering("initialization");
functor.init_(input); // <-- init
data::fill(dmap, max);
// For the extension to be ignored:
......@@ -221,13 +218,10 @@ namespace mln
break;
}
}
trace::exiting("initialization");
}
// Propagation.
{
trace::entering("propagation");
unsigned p;
util::array<int> dp = offsets_wrt(input, nbh);
......@@ -251,9 +245,8 @@ namespace mln
}
}
}
trace::exiting("propagation");
}
trace::exiting("canvas::impl::distance_geodesic_fastest");
return dmap;
}
......@@ -272,9 +265,10 @@ namespace mln
typename F>
inline
mln_ch_value(I, D)
distance_geodesic_dispatch(metal::false_,
const Image<I>& input, const Neighborhood<N>& nbh, D max,
F& functor)
distance_geodesic_dispatch(metal::false_,
const Image<I>& input,
const Neighborhood<N>& nbh, D max,
F& functor)
{
return impl::generic::distance_geodesic(input, nbh, max,
functor);
......@@ -284,9 +278,10 @@ namespace mln
typename F>
inline
mln_ch_value(I, D)
distance_geodesic_dispatch(metal::true_,
const Image<I>& input, const Neighborhood<N>& nbh, D max,
F& functor)
distance_geodesic_dispatch(metal::true_,
const Image<I>& input,
const Neighborhood<N>& nbh, D max,
F& functor)
{
return impl::distance_geodesic_fastest(input, nbh, max, functor);
// return impl::generic::distance_geodesic(input, nbh, max,
......@@ -297,8 +292,9 @@ namespace mln
typename F>
inline
mln_ch_value(I, D)
distance_geodesic_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, D max,
F& functor)
distance_geodesic_dispatch(const Image<I>& input,
const Neighborhood<N>& nbh, D max,
F& functor)
{
enum {
test = mlc_equal(mln_trait_image_speed(I),
......@@ -322,8 +318,8 @@ namespace mln
typename F>
inline
mln_ch_value(I, D)
distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh, D max,
F& functor)
distance_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
D max, F& functor)
{
trace::entering("canvas::distance_geodesic");
......
......@@ -30,6 +30,7 @@
///
/// Geodesic influence zone transform.
# include <mln/extension/adjust.hh>
# include <mln/canvas/distance_geodesic.hh>
# include <mln/transform/internal/influence_zone_functor.hh>
......@@ -44,26 +45,9 @@ namespace mln
///
/// \param[in] input An image.
/// \param[in] nbh A neighborhood.
/// \param[in] max The maximum influence zone distance.
/// \param[in] background_value The value used as background (i.e.
/// not propagated).
///
/// \return An image of influence zone.
//
template <typename I, typename N, typename D>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input,
const Neighborhood<N>& nbh,
const D& max, const mln_value(I)& background_value);
/// \overload
template <typename I, typename N, typename D>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input,
const Neighborhood<N>& nbh, const D& max);
/// \overload
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh);
......@@ -73,38 +57,176 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename N, typename D>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
const D& max, const mln_value(I)& background_value)
namespace internal
{
trace::entering("transform::influence_zone_geodesic");
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
template <typename I, typename N>
void
influence_zone_geodesic_tests(const Image<I>& input,
const Neighborhood<N>& nbh)
{
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
internal::influence_zone_functor<I> f(background_value);
(void) mln::canvas::distance_geodesic(input, nbh, max, f);
(void) input;
(void) nbh;
}
trace::exiting("transform::influence_zone_geodesic");
return f.output;
}
} // end of namespace mln::transform::internal
template <typename I, typename N, typename D>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh,
const D& max)
namespace impl
{
namespace generic
{
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input,
const Neighborhood<N>& nbh)
{
// FIXME: To be written...
mlc_abort(I)::check();
}
} // end of namespace mln::transform::impl::generic
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic_fastest(const Image<I>& input_,
const Neighborhood<N>& nbh_)
{
trace::entering("transform::impl::influence_zone_geodesic_fastest");
const I& input = exact(input_);
const N& nbh = exact(nbh_);
internal::influence_zone_geodesic_tests(input, nbh);
mln_precondition(input.domain().pmin() == literal::origin);
std::queue<mln_value(I)*> q;
mln_concrete(I) output;
util::array<int> dp = offsets_wrt(input, nbh);
const unsigned n_nbhs = dp.nelements();
const unsigned
ncols = input.ncols(),
first_offset = input.border() * (ncols + 2 * input.border() + 1);
// Initialization.
{
extension::adjust(input, nbh);
output = duplicate(input);
// For the extension to be ignored:
extension::fill(input, 0); // in initialization
extension::fill(output, 1); // in propagation
const unsigned nelts = input.nelements();
const mln_value(I)* p_i = & input.at_(0, 0);
mln_value(I)* p_o = & output.at_(0, 0);
for (unsigned i = first_offset; i < nelts; ++i, ++p_i, ++p_o)
{
if (*p_i == 0)
continue;
for (unsigned j = 0; j < n_nbhs; ++j)
{
const mln_value(I)* n_i = p_i + dp[j];
if (*n_i == 0)
{
q.push(p_o);
break;
}
}
}
}
// Propagation.
{
mln_value(I)* ptr;
while (! q.empty())
{
ptr = q.front();
q.pop();
mln_invariant(*ptr != 0);
for (unsigned j = 0; j < n_nbhs; ++j)
{
mln_value(I)* ntr = ptr + dp[j];
if (*ntr == 0)
{
*ntr = *ptr;
q.push(ntr);
}
}
}
}
trace::exiting("transform::impl::influence_zone_geodesic_fastest");
return output;
}
} // end of namespace mln::transform::impl
namespace internal
{
return influence_zone_geodesic(input, nbh, max, literal::zero);
}
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic_dispatch(trait::image::value_alignment::any,
trait::image::value_storage::any,
trait::image::value_access::any,
const I& input,
const N& nbh)
{
return impl::generic::influence_zone_geodesic(input, nbh);
}
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic_dispatch(trait::image::value_alignment::with_grid,
trait::image::value_storage::one_block,
trait::image::value_access::direct,
const I& input,
const N& nbh)
{
return impl::influence_zone_geodesic_fastest(input, nbh);
}
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic_dispatch(const Image<I>& input,
const Neighborhood<N>& nbh)
{
return
influence_zone_geodesic_dispatch(mln_trait_image_value_alignment(I)(),
mln_trait_image_value_storage(I)(),
mln_trait_image_value_access(I)(),
exact(input), exact(nbh));
}
} // end of namespace mln::transform::internal
template <typename I, typename N>
mln_concrete(I)
influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh)
{
return influence_zone_geodesic(input, nbh, mln_max(unsigned));
trace::entering("transform::influence_zone_geodesic");
internal::influence_zone_geodesic_tests(input, nbh);
mln_concrete(I)
output = internal::influence_zone_geodesic_dispatch(input, nbh);
trace::exiting("transform::influence_zone_geodesic");
return output;
}
# endif // ! MLN_INCLUDE_ONLY
......
// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
// Olena is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 2 of the License.
//
// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, you may use this file as part of a free
// software project 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_TRANSFORM_INFLUENCE_ZONE_GEODESIC_SATURATED_HH
# define MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_SATURATED_HH
/// \file
///
/// Geodesic influence zone transform.
# include <mln/canvas/distance_geodesic.hh>
# include <mln/transform/internal/influence_zone_functor.hh>
namespace mln
{
namespace transform
{
/// Geodesic influence zone transform.
///
/// \param[in] input An image.
/// \param[in] nbh A neighborhood.
/// \param[in] max The maximum influence zone distance.
/// \param[in] background_value The value used as background (i.e.
/// not propagated).
///
/// \return An image of influence zone.
//
template <typename I, typename N, typename D>
mln_concrete(I)
influence_zone_geodesic_saturated(const Image<I>& input,
const Neighborhood<N>& nbh,
const D& max,
const mln_value(I)& background_value);
/// \overload
template <typename I, typename N, typename D>
mln_concrete(I)
influence_zone_geodesic_saturated(const Image<I>& input,
const Neighborhood<N>& nbh,
const D& max);
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename N, typename D>
mln_concrete(I)
influence_zone_geodesic_saturated(const Image<I>& input,
const Neighborhood<N>& nbh,
const D& max,
const mln_value(I)& background_value)
{
trace::entering("transform::influence_zone_geodesic_saturated");
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
internal::influence_zone_functor<I> f(background_value);
(void) mln::canvas::distance_geodesic(input, nbh, max, f);
trace::exiting("transform::influence_zone_geodesic_saturated");
return f.output;
}
template <typename I, typename N, typename D>
mln_concrete(I)
influence_zone_geodesic_saturated(const Image<I>& input,
const Neighborhood<N>& nbh,
const D& max)
{
return influence_zone_geodesic_saturated(input, nbh, max, literal::zero);
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::transform
} // end of namespace mln
#endif // ! MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_SATURATED_HH
......@@ -25,15 +25,19 @@ check_PROGRAMS = \
distance_front \
distance_geodesic \
hough \
kht \
influence_zone_front \
influence_zone_geodesic
influence_zone_geodesic \
influence_zone_geodesic_saturated
bench_closest_point_geodesic_SOURCES = bench_closest_point_geodesic.cc
distance_and_closest_point_geodesic_SOURCES = distance_and_closest_point_geodesic.cc
distance_front_SOURCES = distance_front.cc
distance_geodesic_SOURCES = distance_geodesic.cc
hough_SOURCES = hough.cc
kht_SOURCES = kht.cc
influence_zone_front_SOURCES = influence_zone_front.cc
influence_zone_geodesic_SOURCES = influence_zone_geodesic.cc
influence_zone_geodesic_saturated_SOURCES = influence_zone_geodesic_saturated.cc
TESTS = $(check_PROGRAMS)
......@@ -39,7 +39,7 @@ int main()
int_u8 vals[] =
{ 1, 1, 0, 0, 0, 0, 3,
1, 1, 1, 0, 0, 0, 0,
1, 1, 1, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2, 0,
......@@ -47,6 +47,6 @@ int main()
0, 0, 0, 0, 0, 0, 0 };
image2d<int_u8> input = make::image2d(vals);
image2d<int_u8> output = transform::influence_zone_geodesic(input, c4(), int_u8(2));
image2d<int_u8> output = transform::influence_zone_geodesic(input, c4());
debug::println(output);
}
// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
// Olena is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 2 of the License.
//
// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, you may use this file as part of a free
// software project 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.
#include <mln/core/image/image2d.hh>
#include <mln/core/alias/neighb2d.hh>
#include <mln/value/int_u8.hh>
#include <mln/make/image2d.hh>
#include <mln/debug/println.hh>
#include <mln/transform/influence_zone_geodesic_saturated.hh>
int main()
{
using namespace mln;
using value::int_u8;
int_u8 vals[] =
{ 1, 1, 0, 0, 0, 0, 3,
1, 1, 1, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2, 0,
0, 0, 0, 0, 2, 2, 0,
0, 0, 0, 0, 0, 0, 0 };
image2d<int_u8> input = make::image2d(vals);