Commit 975f71e7 authored by Guillaume Lazzara's avatar Guillaume Lazzara
Browse files

Introduce distance_and_closest_point_geodesic.

	* mln/transform/closest_point_geodesic.hh: rename as...
	* mln/transform/distance_and_closest_point_geodesic.hh: ... this.
	  Now returns both dmap and closest point images.
	  Add a version returning a closest point image containing indexes.

	* mln/transform/all.hh: update includes.

	* mln/transform/internal/closest_point_functor.hh: add a new functor
	which build a closest point image containing sites.

	* tests/Makefile.am: run transform tests.

	* tests/transform/Makefile.am: update test names
	.
	* tests/transform/bench_closest_point_geodesic.cc: fix missing
	include.

	* tests/transform/closest_point_geodesic.cc: rename as...
	* tests/transform/distance_and_closest_point_geodesic.cc: ... this.
	  Update according modifications in
	  distance_and_closest_point_geodesic.hh.

git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@3467 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 3cf0592d
2009-03-02 Guillaume Lazzara <lazzara@lrde.epita.fr>
Introduce distance_and_closest_point_geodesic.
* mln/transform/closest_point_geodesic.hh: rename as...
* mln/transform/distance_and_closest_point_geodesic.hh: ... this.
Now returns both dmap and closest point images.
Add a version returning a closest point image containing indexes.
* mln/transform/all.hh: update includes.
* mln/transform/internal/closest_point_functor.hh: add a new functor
which build a closest point image containing sites.
* tests/Makefile.am: run transform tests.
* tests/transform/Makefile.am: update test names
.
* tests/transform/bench_closest_point_geodesic.cc: fix missing
include.
* tests/transform/closest_point_geodesic.cc: rename as...
* tests/transform/distance_and_closest_point_geodesic.cc: ... this.
Update according modifications in
distance_and_closest_point_geodesic.hh.
2009-03-02 Guillaume Lazzara <lazzara@lrde.epita.fr>
 
Add util::couple.
......@@ -42,7 +42,7 @@ namespace mln
} // end of namespace mln
# include <mln/transform/closest_point_geodesic.hh>
# include <mln/transform/distance_and_closest_point_geodesic.hh>
# include <mln/transform/distance_front.hh>
# include <mln/transform/distance_geodesic.hh>
# include <mln/transform/influence_zone_front.hh>
......
// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
// 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
......@@ -25,19 +25,18 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
#ifndef MLN_TRANSFORM_CLOSEST_POINT_GEODESIC_HH
# define MLN_TRANSFORM_CLOSEST_POINT_GEODESIC_HH
#ifndef MLN_TRANSFORM_DISTANCE_AND_CLOSEST_POINT_GEODESIC_HH
# define MLN_TRANSFORM_DISTANCE_AND_CLOSEST_POINT_GEODESIC_HH
/// \file mln/transform/closest_point_geodesic.hh
/// \file mln/transform/distance_and_closest_point_geodesic.hh
///
/// Geodesic closest point transform.
///
/// \todo Add a version to retrieve both distance and closest point
/// maps.
/// Distance and geodesic closest point transform.
# include <mln/canvas/distance_geodesic.hh>
# include <mln/transform/internal/closest_point_functor.hh>
# include <mln/data/fill.hh>
# include <mln/util/couple.hh>
namespace mln
......@@ -46,29 +45,92 @@ namespace mln
namespace transform
{
/// Discrete geodesic distance transform.
/// Discrete geodesic distance transform
///
/// \param[in] input Image from which the geodesic distance is computed.
/// \param[in] nbh Neighborhood
/// \param[in] max Max distance of propagation.
///
/// \return a couple of images. The first one is the distance map and the
/// second one is the closest point image. The closest point image
/// contains sites.
///
/// \post The returned images have the same domain as \p input.
template <typename I, typename N, typename D>
mln_ch_value(I, mln_psite(I))
closest_point_geodesic(const Image<I>& input, const Neighborhood<N>& nbh, D max);
util::couple<mln_ch_value(I,D), mln_ch_value(I,mln_psite(I))>
distance_and_closest_point_geodesic(const Image<I>& input,
const Neighborhood<N>& nbh,
D max);
/// Discrete geodesic distance transform
///
/// \param[in] pset an array of sites.
/// \param[in] closest_point_domain domain of the returned image.
/// \param[in] nbh neighborhood
/// \param[in] max max distance of propagation.
///
/// \return A couple of images. The first one is the distance map and the
/// second one is the closest point image. The closest point image
/// contains site indexes.
///
/// \post The returned image domains are defined on \p closest_point_domain.
template <typename P, typename N, typename D>
util::couple<mln_image_from_grid(mln_grid(P),D),
mln_image_from_grid(mln_grid(P),unsigned)>
distance_and_closest_point_geodesic(const p_array<P>& pset,
const box<P>& closest_point_domain,
const Neighborhood<N>& nbh,
D max);
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename N, typename D>
inline
mln_ch_value(I, mln_psite(I))
closest_point_geodesic(const Image<I>& input, const Neighborhood<N>& nbh, D max)
util::couple<mln_ch_value(I,D), mln_ch_value(I, mln_psite(I))>
distance_and_closest_point_geodesic(const Image<I>& input,
const Neighborhood<N>& nbh,
D max)
{
trace::entering("transform::closest_point_geodesic");
trace::entering("transform::distance_closest_point_geodesic");
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
internal::closest_point_functor<I> f;
(void) mln::canvas::distance_geodesic(input, nbh, max, f);
internal::closest_point_functor_with_sites<I> f;
mln_ch_value(I,D) dmap = mln::canvas::distance_geodesic(input, nbh,
max, f);
trace::exiting("transform::distance_and_closest_point_geodesic");
return make::couple(dmap, f.cp_ima);
}
template <typename P, typename N, typename D>
inline
util::couple<mln_image_from_grid(mln_grid(P),D), mln_image_from_grid(mln_grid(P),unsigned)>
distance_and_closest_point_geodesic(const p_array<P>& pset,
const box<P>& closest_point_domain,
const Neighborhood<N>& nbh,
D max)
{
trace::entering("transform::distance_and_closest_point_geodesic");
mln_precondition(closest_point_domain.is_valid());
mln_precondition(exact(nbh).is_valid());
mln_precondition(geom::bbox(pset) <= closest_point_domain);
typedef mln_image_from_grid(mln_grid(P), bool) I;
internal::closest_point_functor_with_indexes<I> f(pset);
I ima(closest_point_domain);
data::fill(ima, false);
data::fill((ima | pset).rw(), true);
mln_ch_value(I,D) dmap = mln::canvas::distance_geodesic(ima, nbh, max, f);
trace::exiting("transform::closest_point_geodesic");
return f.cp_ima;
trace::exiting("transform::distance_and_closest_point_geodesic");
return make::couple(dmap, f.cp_ima);
}
# endif // ! MLN_INCLUDE_ONLY
......@@ -78,4 +140,4 @@ namespace mln
} // end of namespace mln
#endif // ! MLN_TRANSFORM_CLOSEST_POINT_GEODESIC_HH
#endif // ! MLN_TRANSFORM_DISTANCE_AND_CLOSEST_POINT_GEODESIC_HH
......@@ -47,31 +47,55 @@ namespace mln
{
template <typename I>
struct closest_point_functor
struct closest_point_functor_with_indexes
{
typedef mln_value(I) V;
typedef mln_psite(I) P;
typedef mln_psite(I) P;
closest_point_functor(const p_array<P>& pset);
closest_point_functor_with_indexes(const p_array<P>& pset);
mln_ch_value(I,unsigned) cp_ima;
const p_array<P>& pset_;
/// Generic version interface.
void init(const I&);
bool inqueue_p_wrt_input_p(const V& input_p);
void init_p(const P&);
bool inqueue_p_wrt_input_n(const V& input_n);
void process(const P&, const P&);
void init_(const I& input)
{
init(input);
}
/// Fast version interface.
void init_(const I& input);
bool inqueue_p_wrt_input_p_(const V& input_p);
void init_p_(unsigned);
bool inqueue_p_wrt_input_n_(const V& input_n);
void process_(unsigned p, unsigned n);
};
template <typename I>
struct closest_point_functor_with_sites
{
typedef mln_value(I) V;
typedef mln_psite(I) P;
closest_point_functor_with_sites();
mln_ch_value(I,P) cp_ima;
bool inqueue_p_wrt_input_p_(const V& input_p) { return input_p == true; }
void init_p_(unsigned) { }//cp_ima.element(p) = pset_(cp_ima.point_at_index(p)); }
bool inqueue_p_wrt_input_n_(const V& input_n) { return input_n == false; }
void process_(unsigned p, unsigned n) { cp_ima.element(n) = cp_ima.element(p); }
/// Generic version interface.
void init(const I&);
bool inqueue_p_wrt_input_p(const V& input_p);
void init_p(const P&);
bool inqueue_p_wrt_input_n(const V& input_n);
void process(const P&, const P&);
/// Fast version interface.
void init_(const I& input);
bool inqueue_p_wrt_input_p_(const V& input_p);
void init_p_(unsigned p);
bool inqueue_p_wrt_input_n_(const V& input_n);
void process_(unsigned p, unsigned n);
};
......@@ -79,7 +103,8 @@ namespace mln
template <typename I>
inline
closest_point_functor<I>::closest_point_functor(const p_array<mln_psite(I)>& pset)
closest_point_functor_with_indexes<I>::closest_point_functor_with_indexes(
const p_array<mln_psite(I)>& pset)
: pset_(pset)
{
}
......@@ -87,20 +112,111 @@ namespace mln
template <typename I>
inline
void
closest_point_functor<I>::init(const I& input)
closest_point_functor_with_indexes<I>::init(const I& input)
{
initialize(cp_ima, input);
data::fill(cp_ima, 0u);
mln_piter(p_array<mln_psite(I)>) p(pset_);
for_all(p)
cp_ima(p) = p.index();
cp_ima(p) = cp_ima.index_of_point(p);
}
template <typename I>
inline
bool
closest_point_functor_with_indexes<I>::inqueue_p_wrt_input_p(const V& input_p)
{
return input_p == true;
}
template <typename I>
inline
void
closest_point_functor_with_indexes<I>::init_p(const P&)
{
}
template <typename I>
inline
bool
closest_point_functor_with_indexes<I>::inqueue_p_wrt_input_n(const V& input_n)
{
return input_n == false;
}
template <typename I>
inline
void closest_point_functor_with_indexes<I>::process(const P& p, const P& n)
{
cp_ima(n) = cp_ima(p);
}
template <typename I>
inline
void
closest_point_functor_with_indexes<I>::init_(const I& input)
{
init(input);
}
template <typename I>
inline
bool
closest_point_functor_with_indexes<I>::inqueue_p_wrt_input_p_(const V& input_p)
{
return input_p == true;
}
template <typename I>
inline
void closest_point_functor_with_indexes<I>::init_p_(unsigned)
{
}
template <typename I>
inline
bool
closest_point_functor_with_indexes<I>::inqueue_p_wrt_input_n_(const V& input_n)
{
return input_n == false;
}
template <typename I>
inline
void
closest_point_functor_with_indexes<I>::process_(unsigned p, unsigned n)
{
cp_ima.element(n) = cp_ima.element(p);
}
/// ///
/// closest_point_functor_with_sites ///
/// ///
template <typename I>
inline
closest_point_functor_with_sites<I>::closest_point_functor_with_sites()
{
}
template <typename I>
inline
void
closest_point_functor_with_sites<I>::init(const I& input)
{
initialize(cp_ima, input);
data::fill(cp_ima, literal::origin);
}
template <typename I>
inline
bool
closest_point_functor<I>::inqueue_p_wrt_input_p(const V& input_p)
closest_point_functor_with_sites<I>::inqueue_p_wrt_input_p(const V& input_p)
{
return input_p == true;
}
......@@ -108,26 +224,68 @@ namespace mln
template <typename I>
inline
void
closest_point_functor<I>::init_p(const P&)
closest_point_functor_with_sites<I>::init_p(const P& p)
{
// cp_ima(p) = p;
cp_ima(p) = p;
}
template <typename I>
inline
bool
closest_point_functor<I>::inqueue_p_wrt_input_n(const V& input_n)
closest_point_functor_with_sites<I>::inqueue_p_wrt_input_n(const V& input_n)
{
return input_n == false;
}
template <typename I>
inline
void closest_point_functor<I>::process(const P& p, const P& n)
void
closest_point_functor_with_sites<I>::process(const P& p, const P& n)
{
cp_ima(n) = cp_ima(p);
}
template <typename I>
inline
void
closest_point_functor_with_sites<I>::init_(const I& input)
{
init(input);
}
template <typename I>
inline
bool
closest_point_functor_with_sites<I>::inqueue_p_wrt_input_p_(const V& input_p)
{
return input_p == true;
}
template <typename I>
inline
void closest_point_functor_with_sites<I>::init_p_(unsigned p)
{
cp_ima.element(p) = cp_ima.point_at_index(p);
}
template <typename I>
inline
bool
closest_point_functor_with_sites<I>::inqueue_p_wrt_input_n_(const V& input_n)
{
return input_n == false;
}
template <typename I>
inline
void
closest_point_functor_with_sites<I>::process_(unsigned p, unsigned n)
{
cp_ima.element(n) = cp_ima.element(p);
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::transform::internal
......
......@@ -41,6 +41,7 @@ SUBDIRS = \
topo \
trace \
trait \
transform \
unit_test \
util \
value \
......
......@@ -4,14 +4,14 @@ include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
bench_closest_point_geodesic \
closest_point_geodesic \
distance_and_closest_point_geodesic \
distance_front \
distance_geodesic \
influence_zone_front \
influence_zone_geodesic
bench_closest_point_geodesic_SOURCES = bench_closest_point_geodesic.cc
closest_point_geodesic_SOURCES = 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
influence_zone_front_SOURCES = influence_zone_front.cc
......
......@@ -36,6 +36,7 @@
#include <mln/data/fill.hh>
#include <mln/opt/at.hh>
#include <mln/transform/closest_point_geodesic.hh>
#include <mln/value/int_u8.hh>
int main()
......
// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
// 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
......@@ -35,9 +36,30 @@
#include <mln/data/fill.hh>
#include <mln/debug/println.hh>
#include <mln/opt/at.hh>
#include <mln/level/compare.hh>
#include <mln/transform/closest_point_geodesic.hh>
#include <mln/transform/distance_and_closest_point_geodesic.hh>
unsigned dmap_ref[] = { 4, 4, 4, 3, 2, 3, 4, 4, 4,
4, 4, 3, 2, 1, 2, 3, 4, 4,
4, 3, 2, 1, 0, 1, 2, 3, 4,
3, 2, 1, 2, 1, 2, 3, 4, 4,
2, 1, 0, 1, 2, 3, 4, 4, 4,
3, 2, 1, 2, 3, 4, 4, 4, 4,
4, 3, 2, 3, 4, 4, 4, 4, 4,
4, 4, 3, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4 };
unsigned cp_idx_ref[] = { 0 , 0 , 82 , 82 , 82 , 82, 82, 0 , 0 ,
0 , 82 , 82 , 82 , 82 , 82, 82, 82, 0 ,
110, 82 , 82 , 82 , 82 , 82, 82, 82, 82,
110, 110, 110, 82 , 82 , 82, 82, 82, 0 ,
110, 110, 110, 110, 82 , 82, 82, 0 , 0 ,
110, 110, 110, 110, 82 , 82, 0 , 0 , 0 ,
110, 110, 110, 110, 110, 0 , 0 , 0 , 0 ,
0 , 110, 110, 110, 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 110, 0 , 0 , 0 , 0 , 0 , 0 };
int main()
{
......@@ -49,6 +71,25 @@ int main()
opt::at(input, 2, 4) = true;
opt::at(input, 4, 2) = true;
image2d<point2d> output = transform::closest_point_geodesic(input, c4(), int_u8(4));
debug::println(output);
{
typedef util::couple<image2d<int_u8>, image2d<point2d> > output_t;
output_t output = transform::distance_and_closest_point_geodesic(input,
c4(),
int_u8(4));
mln_assertion(output.first() == make::image2d(dmap_ref));
///FIXME: test the closest point image here.
}
{
p_array<point2d> arr;
arr.insert(point2d(2, 4));
arr.insert(point2d(4, 2));
typedef util::couple<image2d<int_u8>, image2d<unsigned> > output_t;
output_t output = transform::distance_and_closest_point_geodesic(arr,
input.domain(),
c4(),
int_u8(4));
mln_assertion(output.first() == make::image2d(dmap_ref));
mln_assertion(output.second() == make::image2d(cp_idx_ref));
}
}
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