Commit b8c12d45 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Fetch card and algebraic_union_find.hh from Edwin's sandbox.

	* mln/trait/accumulator/props.hh (use_none): New.
	* mln/trait/accumulators.hh
	(mln_trait_accumulator_has_setvalue): Rename as...
	(mln_trait_accumulator_has_set_value): ...this.
	* mln/morpho/attribute: New directory.
	* mln/morpho/attribute/all.hh: New.
	* sandbox/edwin/card.hh: Copy to...
	* mln/morpho/attribute/card.hh: ...this new file.
	Update.
	* mln/morpho/all.hh: Update.
	* sandbox/edwin/algebraic_union_find.hh: Copy to...
	* mln/canvas/morpho/algebraic_filter.hh: ...this new file.
	(algebraic_union_find): Rename as...
	(algebraic_filter): ...this.
	Fix.
	* mln/morpho/closing_algebraic.hh: New.
	* mln/canvas/morpho/all.hh: Update.
	* tests/morpho/attribute: New directory.
	* tests/morpho/attribute/Makefile.am: New.
	* tests/morpho/attribute/card.cc: New.
	* tests/morpho/Makefile.am: Update.
	* tests/morpho/closing_algebraic.cc: New.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@3332 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent b525f240
2009-02-10 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Fetch card and algebraic_union_find.hh from Edwin's sandbox.
* mln/trait/accumulator/props.hh (use_none): New.
* mln/trait/accumulators.hh
(mln_trait_accumulator_has_setvalue): Rename as...
(mln_trait_accumulator_has_set_value): ...this.
* mln/morpho/attribute: New directory.
* mln/morpho/attribute/all.hh: New.
* sandbox/edwin/card.hh: Copy to...
* mln/morpho/attribute/card.hh: ...this new file.
Update.
* mln/morpho/all.hh: Update.
* sandbox/edwin/algebraic_union_find.hh: Copy to...
* mln/canvas/morpho/algebraic_filter.hh: ...this new file.
(algebraic_union_find): Rename as...
(algebraic_filter): ...this.
Fix.
* mln/morpho/closing_algebraic.hh: New.
* mln/canvas/morpho/all.hh: Update.
* tests/morpho/attribute: New directory.
* tests/morpho/attribute/Makefile.am: New.
* tests/morpho/attribute/card.cc: New.
* tests/morpho/Makefile.am: Update.
* tests/morpho/closing_algebraic.cc: New.
2009-02-10 Thierry Geraud <thierry.geraud@lrde.epita.fr>
 
Fetch accumulator properties from Fred's sandbox.
// Copyright (C) 2007, 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.
#ifndef MLN_CANVAS_MORPHO_ALGEBRAIC_FILTER_HH
# define MLN_CANVAS_MORPHO_ALGEBRAIC_FILTER_HH
/// \file mln/canvas/morpho/algebraic_filter.hh
///
/// Canvas for morphological algebraic filters.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
# include <mln/core/concept/accumulator.hh>
# include <mln/data/fill.hh>
# include <mln/extension/adjust_fill.hh>
# include <mln/level/sort_psites.hh>
# include <mln/level/sort_offsets.hh>
namespace mln
{
namespace canvas
{
namespace morpho
{
template <typename I, typename N, typename A>
mln_concrete(I)
algebraic_filter(const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& accu,
const mln_result(A)& lambda,
bool increasing);
# ifndef MLN_INCLUDE_ONLY
// Implementations.
namespace impl
{
// Generic version.
namespace generic
{
template <typename I>
inline
mln_psite(I)
find_root(I& parent, const mln_psite(I)& x)
{
if (parent(x) == x)
return x;
else
return parent(x) = find_root(parent, parent(x));
}
template <typename I, typename N, typename S, typename A>
inline
mln_concrete(I)
algebraic_filter(const Image<I>& input_,
const Neighborhood<N>& nbh_,
const Accumulator<A>& accu_,
const mln_result(A)& lambda,
const Site_Set<S>& s_)
{
trace::entering("canvas::morpho::impl::generic::algebraic_filter");
// FIXME: Tests?
const I& input = exact(input_);
const N& nbh = exact(nbh_);
const S& s = exact(s_);
mln_concrete(I) output;
initialize(output, input);
// Local type.
typedef mln_psite(I) P;
// Auxiliary data.
mln_ch_value(I, bool) deja_vu;
mln_ch_value(I, bool) activity;
mln_ch_value(I, P) parent;
mln_ch_value(I, A) data;
// Initialization.
{
initialize(deja_vu, input);
mln::data::fill(deja_vu, false);
initialize(activity, input);
mln::data::fill(activity, true);
initialize(parent, input);
initialize(data, input);
}
// First pass.
{
mln_fwd_piter(S) p(s);
mln_niter(N) n(nbh, p);
for_all(p)
{
// Make-Set.
parent(p) = p;
data(p).take_as_init(p);
for_all(n)
if (input.domain().has(n) && deja_vu(n))
{
// Do-Union.
P r = find_root(parent, n);
if (r != p)
{
if (input(r) == input(p) || (activity(r) && data(r) < lambda)) // Equiv(r, p)
// Either a flat zone or the component of r is still growing.
{
/* FIXME: Same remark as above concerning the
initialization of data(p); instead of
data(p).take(data(r));
we should (or could) have
unite_data(p, r);
so as to keep the generic aspect of this canvas
(as long as the set of acceptable types for the
template parameter A is not bound). */
data(p).take(data(r));
parent(r) = p;
if (activity(r) == false)
activity(p) = false;
}
else
activity(p) = false;
}
}
deja_vu(p) = true;
}
}
// Second pass.
{
mln_bkd_piter(S) p(s);
for_all(p)
if (parent(p) == p) // p is root.
output(p) = input(p);
else
output(p) = output(parent(p));
}
/*
Change 2nd pass into:
for_all(p) if (not is_root(p)) output(p) = output(parent(p));
and add in init:
mln::data::fill(output, input);
*/
trace::exiting("canvas::morpho::impl::generic::algebraic_filter");
return output;
}
} // end of namespace mln::canvas::morpho::impl::generic
// Fastest version.
template <typename I>
inline
unsigned
find_root_fastest(I& parent, unsigned x)
{
if (parent.element(x) == 0)
return x;
else
return parent.element(x) = find_root_fastest(parent, parent.element(x));
}
template <typename I, typename N, typename A>
inline
mln_concrete(I)
algebraic_filter_fastest(const Image<I>& input_,
const Neighborhood<N>& nbh_,
const Accumulator<A>& accu_,
const mln_result(A)& lambda,
const util::array<unsigned>& s)
{
trace::entering("canvas::morpho::impl::algebraic_filter_fastest");
// FIXME: Tests?
const I& input = exact(input_);
const N& nbh = exact(nbh_);
extension::adjust(input, nbh);
mln_concrete(I) output;
initialize(output, input);
// Local type.
typedef mln_psite(I) P;
// Auxiliary data.
mln_ch_value(I, bool) deja_vu;
mln_ch_value(I, bool) activity;
mln_ch_value(I, unsigned) parent;
mln_ch_value(I, A) data;
// Initialization.
{
initialize(deja_vu, input);
mln::data::fill(deja_vu, false);
extension::fill(deja_vu, false); // So that the extension is ignored.
initialize(activity, input);
mln::data::fill(activity, true);
initialize(parent, input);
mln::data::fill(parent, 0);
initialize(data, input);
}
util::array<int> dp = offsets_wrt(input, nbh);
const unsigned n_nbhs = dp.nelements();
const unsigned n = s.nelements();
// First pass.
{
for (unsigned i = 0; i < n; ++i)
{
unsigned p = s[i]; // An offset.
// Make set.
data.element(p).take_as_init(); // FIXME: Very bad!
for (unsigned j = 0; j < n_nbhs; ++j)
{
unsigned n = p + dp[j];
if (! deja_vu.element(n))
continue;
unsigned r = find_root_fastest(parent, n);
if (r != p)
{
if (input.element(r) == input.element(p)
|| (activity.element(r) && data.element(r) < lambda))
{
data.element(p).take(data.element(r));
parent.element(r) = p;
if (activity.element(r) == false)
activity.element(p) = false;
}
else
activity.element(p) = false;
}
}
deja_vu.element(p) = true;
}
}
// Second pass.
{
for (int i = n - 1; i >= 0 ; --i)
{
unsigned p = s[i];
if (parent.element(p) == 0) // p is root.
output.element(p) = input.element(p);
else
output.element(p) = output.element(parent.element(p));
}
}
trace::exiting("canvas::morpho::impl::algebraic_filter_fastest");
return output;
}
} // end of namespace mln::canvas::morpho::impl
// Dispatch.
namespace internal
{
template <typename I, typename N, typename A>
inline
mln_concrete(I)
algebraic_filter_dispatch(metal::false_,
const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& accu,
const mln_result(A)& lambda,
bool increasing)
{
p_array<mln_psite(I)> s = increasing ?
level::sort_psites_increasing(input) :
level::sort_psites_decreasing(input);
return impl::generic::algebraic_filter(input, nbh, accu, lambda,
s);
}
template <typename I, typename N, typename A>
inline
mln_concrete(I)
algebraic_filter_dispatch(metal::true_,
const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& accu,
const mln_result(A)& lambda,
bool increasing)
{
util::array<unsigned> s = increasing ?
level::sort_offsets_increasing(input) :
level::sort_offsets_decreasing(input);
return impl::algebraic_filter_fastest(input, nbh, accu, lambda,
s);
}
template <typename I, typename N, typename A>
inline
mln_concrete(I)
algebraic_filter_dispatch(const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& accu,
const mln_result(A)& lambda,
bool increasing)
{
enum {
test = (mlc_equal(mln_trait_image_speed(I),
trait::image::speed::fastest)::value
&&
mln_is_simple_neighborhood(N)::value
&&
mlc_equal(mln_trait_accumulator_when_pix(A),
trait::accumulator::when_pix::use_none)::value)
};
return algebraic_filter_dispatch(metal::bool_<test>(),
input, nbh, accu, lambda,
increasing);
}
} // end of namespace mln::canvas::morpho::internal
// Facade.
template <typename I, typename N, typename A>
inline
mln_concrete(I)
algebraic_filter(const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& accu,
const mln_result(A)& lambda,
bool increasing)
{
return internal::algebraic_filter_dispatch(input, nbh, accu, lambda,
increasing);
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::canvas::morpho
} // end of namespace mln::canvas
} // end of namespace mln
#endif // ! MLN_CANVAS_MORPHO_ALGEBRAIC_FILTER_HH
// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
// (LRDE)
// Copyright (C) 2007, 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
......@@ -46,6 +46,7 @@ namespace mln
}
# include <mln/canvas/morpho/algebraic_filter.hh>
# include <mln/canvas/morpho/algebraic_union_find.hh>
......
// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
// (LRDE)
// Copyright (C) 2007, 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
......@@ -84,6 +84,7 @@ namespace mln
// Sub-directories.
# include <mln/morpho/attribute/all.hh>
# include <mln/morpho/elementary/all.hh>
# include <mln/morpho/tree/all.hh>
# include <mln/morpho/watershed/all.hh>
......
// Copyright (C) 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.
#ifndef MLN_MORPHO_ATTRIBUTE_ALL_HH
# define MLN_MORPHO_ATTRIBUTE_ALL_HH
/// \file mln/morpho/attribute/all.hh
///
/// File that includes all attributes used in mathematical morphology.
namespace mln
{
namespace morpho
{
/// Namespace of attributes used in mathematical morphology.
namespace attribute {}
}
}
# include <mln/morpho/attribute/card.hh>
#endif // ! MLN_MORPHO_ATTRIBUTE_ALL_HH
<
// Copyright (C) 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.
#ifndef MLN_MORPHO_ATTRIBUTE_CARD_HH
# define MLN_MORPHO_ATTRIBUTE_CARD_HH
/// \file mln/morpho/attribute/card.hh
///
/// Define an accumulator that computes the cardinality of a
/// component.
# include <mln/accu/internal/base.hh>
namespace mln
{
// Forward declaration.
namespace morpho {
namespace attribute {
template <typename I> struct card;
}
}
// Traits.
namespace trait
{
template <typename I>
struct accumulator_< morpho::attribute::card<I> >
{
typedef accumulator::has_untake::no has_untake;
typedef accumulator::has_set_value::no has_set_value;
typedef accumulator::has_stop::no has_stop;
typedef accumulator::when_pix::use_none when_pix;
};
} // end of namespace mln::trait
namespace morpho
{
namespace attribute
{
/// Cardinality accumulator class.
template <typename I>
struct card : public mln::accu::internal::base< unsigned, card<I> >
{
typedef mln_psite(I) argument;
card();
/// Manipulators.
/// \{
void init();