https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Rename theo's sandbox.
* geraud: Rename as...
* theo: ...this.
* geraud/skel.cc,
* geraud/fllt.cc,
* geraud/test_attribute.cc,
* geraud/fllt.svg.6.cc,
* geraud/p_runs__with_dedicated_piter.hh,
* geraud/win_fun.cc,
* geraud/browsing,
* geraud/browsing/fwd.cc,
* geraud/browsing/fwd.hh,
* geraud/cs2d,
* geraud/cs2d/cs2d.cc,
* geraud/cs2d/tuto.cc,
* geraud/cs2d/kruskal.cc,
* geraud/cs2d/cs2d_utils.hh,
* geraud/cs2d/cs2d.hh,
* geraud/cs2d/dbl_neighb.hh,
* geraud/cs2d/cs2d_morpho.hh,
* geraud/dead,
* geraud/dead/inplace.hh,
* geraud/dead/instant.hh,
* geraud/fllt,
* geraud/fllt/fllt.hh,
* geraud/fllt/simple_tests.cc,
* geraud/fllt/compute_fllt.cc,
* geraud/fllt/fllt.svg.1.cc,
* geraud/fllt/fllt.svg.7.hh,
* geraud/fllt/fllt_tree_to_image.hh,
* geraud/fllt/fllt.svg.2.cc,
* geraud/fllt/fllt.svg.3.cc,
* geraud/fllt/fllt.svg.4.cc,
* geraud/fllt/fllt.svg.5.cc,
* geraud/fllt/fllt.svg.6.cc,
* geraud/fllt/connected_filters,
* geraud/fllt/connected_filters/area_filter.cc,
* geraud/fllt/connected_filters/canonize_tree.hh,
* geraud/fllt/connected_filters/pseudo_flat_zones.cc,
* geraud/fllt/connected_filters/area_filter.hh,
* geraud/fllt/fllt_test.hh,
* geraud/fllt.svg.7.hh,
* geraud/win_fun.hh,
* geraud/Rd,
* geraud/Rd/hybrid.hh,
* geraud/Rd/queue_based.hh,
* geraud/Rd/parallel.cc,
* geraud/Rd/parallel_wo.cc,
* geraud/Rd/union_find.hh,
* geraud/Rd/parallel.hh,
* geraud/Rd/diff.cc,
* geraud/Rd/sequential_bench.cc,
* geraud/Rd/sequential.cc,
* geraud/Rd/deco.cc,
* geraud/Rd/utils.hh,
* geraud/Rd/diff_pgm.cc,
* geraud/Rd/hybrid.cc,
* geraud/Rd/queue_based.cc,
* geraud/Rd/sequential_bench.hh,
* geraud/Rd/min.cc,
* geraud/Rd/sequential.hh,
* geraud/Rd/debase.union_find.hh,
* geraud/Rd/union_find.cc,
* geraud/Rd/svg.queue_based.hh,
* geraud/dmap.cc,
* geraud/compute_parent_more.hh,
* geraud/tufa_2008,
* geraud/tufa_2008/steps.0.cc,
* geraud/tufa_2008/steps.1.cc,
* geraud/tufa_2008/gradient.cc,
* geraud/tufa_2008/closing.cc,
* geraud/tufa_2008/steps.2.cc,
* geraud/tufa_2008/opening.cc,
* geraud/tufa_2008/steps.3.cc,
* geraud/tufa_2008/steps.2b.cc,
* geraud/tufa_2008/filter_n.cc,
* geraud/tufa_2008/wst_f_equal_wst_a.cc,
* geraud/tufa_2008/compute_a.cc,
* geraud/tufa_2008/wst.cc,
* geraud/tufa_2008/experiment.cc,
* geraud/tufa_2008/n_cmpt.cc,
* geraud/tufa_2008/filter.cc,
* geraud/tufa_2008/closed_gradient.cc,
* geraud/tufa_2008/fz_count.cc,
* geraud/tufa_2008/regmin_count.cc,
* geraud/estimate.hh,
* geraud/laurent,
* geraud/laurent/wst_edge.cc,
* geraud/laurent/wst2d.cc,
* geraud/laurent/classif.cc,
* geraud/laurent/wst3d.cc,
* geraud/laurent/segmentation.hh,
* geraud/irm.cc,
* geraud/color,
* geraud/color/sum_pix.hh,
* geraud/color/segment.cc,
* geraud/color/blen_pix.hh: Move into...
* theo: ...this new directory.
* laurent: New directory.
Rd/debase.union_find.hh | 165 ----
Rd/deco.cc | 71 -
Rd/diff.cc | 28
Rd/diff_pgm.cc | 43 -
Rd/hybrid.cc | 53 -
Rd/hybrid.hh | 117 --
Rd/min.cc | 42 -
Rd/parallel.cc | 54 -
Rd/parallel.hh | 85 --
Rd/parallel_wo.cc | 46 -
Rd/queue_based.cc | 51 -
Rd/queue_based.hh | 124 ---
Rd/sequential.cc | 50 -
Rd/sequential.hh | 87 --
Rd/sequential_bench.cc | 51 -
Rd/sequential_bench.hh | 100 --
Rd/svg.queue_based.hh | 118 --
Rd/union_find.cc | 52 -
Rd/union_find.hh | 166 ----
Rd/utils.hh | 269 ------
browsing/fwd.cc | 515 ------------
browsing/fwd.hh | 88 --
color/blen_pix.hh | 174 ----
color/segment.cc | 639 ---------------
color/sum_pix.hh | 162 ---
compute_parent_more.hh | 191 ----
cs2d/cs2d.cc | 110 --
cs2d/cs2d.hh | 172 ----
cs2d/cs2d_morpho.hh | 372 ---------
cs2d/cs2d_utils.hh | 251 ------
cs2d/dbl_neighb.hh | 167 ----
cs2d/kruskal.cc | 357 --------
cs2d/tuto.cc | 145 ---
dead/inplace.hh | 66 -
dead/instant.hh | 168 ----
dmap.cc | 131 ---
estimate.hh | 90 --
fllt.svg.6.cc | 1139 ----------------------------
fllt.svg.7.hh | 838 --------------------
fllt/compute_fllt.cc | 19
fllt/connected_filters/area_filter.cc | 26
fllt/connected_filters/area_filter.hh | 69 -
fllt/connected_filters/canonize_tree.hh | 51 -
fllt/connected_filters/pseudo_flat_zones.cc | 44 -
fllt/fllt.hh | 1017 -------------------------
fllt/fllt.svg.1.cc | 222 -----
fllt/fllt.svg.2.cc | 304 -------
fllt/fllt.svg.3.cc | 313 -------
fllt/fllt.svg.4.cc | 352 --------
fllt/fllt.svg.5.cc | 353 --------
fllt/fllt.svg.6.cc | 1136 ---------------------------
fllt/fllt.svg.7.hh | 913 ----------------------
fllt/fllt_test.hh | 874 ---------------------
fllt/fllt_tree_to_image.hh | 30
fllt/simple_tests.cc | 84 --
irm.cc | 178 ----
laurent/classif.cc | 419 ----------
laurent/segmentation.hh | 14
laurent/wst2d.cc | 154 ---
laurent/wst3d.cc | 79 -
laurent/wst_edge.cc | 409 ----------
p_runs__with_dedicated_piter.hh | 758 ------------------
skel.cc | 106 --
test_attribute.cc | 122 --
tufa_2008/closed_gradient.cc | 64 -
tufa_2008/closing.cc | 64 -
tufa_2008/compute_a.cc | 412 ----------
tufa_2008/experiment.cc | 138 ---
tufa_2008/filter.cc | 169 ----
tufa_2008/filter_n.cc | 341 --------
tufa_2008/fz_count.cc | 160 ---
tufa_2008/gradient.cc | 60 -
tufa_2008/n_cmpt.cc | 263 ------
tufa_2008/opening.cc | 63 -
tufa_2008/regmin_count.cc | 175 ----
tufa_2008/steps.0.cc | 171 ----
tufa_2008/steps.1.cc | 274 ------
tufa_2008/steps.2.cc | 259 ------
tufa_2008/steps.2b.cc | 185 ----
tufa_2008/steps.3.cc | 186 ----
tufa_2008/wst.cc | 69 -
tufa_2008/wst_f_equal_wst_a.cc | 140 ---
win_fun.cc | 160 ---
win_fun.hh | 160 ---
84 files changed, 19106 deletions(-)
Index: geraud/skel.cc
--- geraud/skel.cc (revision 3151)
+++ geraud/skel.cc (working copy)
@@ -1,106 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/core/site_set/p_queue_fast.hh>
-
-# include <mln/io/pbm/load.hh>
-# include <mln/io/pgm/save.hh>
-# include <mln/value/int_u8.hh>
-
-# include <mln/data/fill.hh>
-
-# include <mln/debug/println.hh>
-
-namespace mln
-{
-
- template <typename D, typename I, typename N>
- mln_ch_value(I, D)
- distance(D, const I& input, const N& nbh)
- {
- const D M = mln_max(D);
- mln_ch_value(I, D) output;
- initialize(output, input);
-
- mln_ch_value(I, bool) deja_vu;
- initialize(deja_vu, input);
- data::fill(deja_vu, input);
-
- typedef mln_site(I) P;
- p_queue_fast<P> q;
-
- // Initialization.
- {
- data::fill(output, M);
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- if (input(p) == true) // p in object
- {
- output(p) = 0;
- for_all(n)
- if (input.domain().has(n) && input(n) == false) // n in background
- {
- q.push(p);
- break;
- }
- }
- }
-
- // Propagation.
- {
- P p;
- mln_niter(N) n(nbh, p);
- while (! q.is_empty())
- {
- p = q.pop_front();
- for_all(n)
- if (input.domain().has(n) && output(n) == M)
- {
- output(n) = output(p) + 1;
- if (output(n) == M)
- {
- // Saturation so stop.
- q.clear();
- break;
- }
- q.push(n);
- deja_vu(n) = true;
- }
- }
- }
-
- return output;
- }
-
-*/
-
-
-
-} // mln
-
-
-
- void usage(char* argv[])
- {
- std::cerr << "usage: " << argv[0] << " input.pbm
output.pgm" << std::endl;
- abort();
- }
-
-
-
- int main(int argc, char* argv[])
- {
- using namespace mln;
- using value::int_u8;
-
- if (argc != 3)
- usage(argv);
-
- image2d<bool> input;
- io::pbm::load(input, argv[1]);
-
- image2d<int_u8> output = distance(int_u8(), input, c4());
- io::pgm::save(output, argv[2]);
- }
Index: geraud/fllt.cc
Index: geraud/test_attribute.cc
--- geraud/test_attribute.cc (revision 3151)
+++ geraud/test_attribute.cc (working copy)
@@ -1,122 +0,0 @@
-// 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.
-
-/// \file tests/morpho/tree/compute_attribute_image.cc
-///
-/// Tests on mln::morpho::tree::compute_attribute_image.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/level/transform.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/core/var.hh>
-#include <mln/value/int_u8.hh>
-
-#include <mln/morpho/tree/data.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-
-#include <mln/morpho/closing_area.hh>
-#include <mln/morpho/opening_area.hh>
-
-#include <mln/accu/count.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/pbm/save.hh>
-
-#include <mln/arith/min.hh>
-#include <mln/arith/diff_abs.hh>
-
-
-struct sat_t : mln::Function_v2v<sat_t>
-{
- typedef mln::value::int_u8 result;
- result operator()(unsigned u) const
- {
- return u > 255 ? 255 : u;
- }
-}
- sat;
-
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<int_u8> I;
- typedef p_array<point2d> S;
- typedef util::pix<I> Px;
-
-
- I f;
- io::pgm::load(f, "../../../img/tiny.pgm");
-
-
- image2d<unsigned> area_inc, area_dec;
- {
- S s = level::sort_psites_increasing(f);
- morpho::tree::data<I,S> t(f, s, c4());
- accu::count<Px> a;
- area_inc = morpho::tree::compute_attribute_image(a, t);
- debug::println("area_inc =", area_inc);
- }
- {
- S s = level::sort_psites_decreasing(f);
- morpho::tree::data<I,S> t(f, s, c4());
- accu::count<Px> a;
- area_dec = morpho::tree::compute_attribute_image(a, t);
- debug::println("area_dec =", area_dec);
- }
-
- io::pgm::save(level::transform(area_inc, sat), "inc.pgm");
- io::pgm::save(level::transform(area_dec, sat), "dec.pgm");
-
- image2d<unsigned> area = arith::min(area_inc, area_dec);
- io::pgm::save(level::transform(area, sat), "min.pgm");
-
- unsigned lambda = 20;
-
- {
- I clo = morpho::closing_area(f, c4(), lambda);
- io::pgm::save(clo, "clo.pgm");
-
- I ope(clo.domain());
- morpho::opening_area(f, c4(), lambda, ope);
- io::pgm::save(ope, "ope.pgm");
-
- I d_clo = arith::diff_abs(f, clo);
- io::pgm::save(d_clo, "d_clo.pgm");
-
- I d_ope = arith::diff_abs(f, ope);
- io::pgm::save(d_ope, "d_ope.pgm");
- }
-
-}
Index: geraud/fllt.svg.6.cc
--- geraud/fllt.svg.6.cc (revision 3151)
+++ geraud/fllt.svg.6.cc (working copy)
@@ -1,1139 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <iomanip>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-#include <mln/core/site_set/p_queue_fast.hh>
-#include <mln/core/image/cast_image.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/level/compare.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/labeling/regional_maxima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/util/tree.hh>
-#include <mln/util/branch_iter_ind.hh>
-#include <mln/util/branch_iter.hh>
-
-#include <mln/opt/at.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
- namespace my
- {
-
-# define fllt_tree(P, V) mln::util::tree< fllt_node_elt<P, V> >
-# define fllt_node(P, V) mln::util::tree_node< fllt_node_elt<P, V> >
-# define fllt_tree_ptr(P, V) mln::util::tree< fllt_node_elt<P, V>* >
-# define fllt_node_ptr(P, V) mln::util::tree_node< fllt_node_elt<P, V>* >
-# define fllt_branch(P, V) mln::util::branch< fllt_node_elt<P, V> >
-# define fllt_branch_iter_ind(P, V) mln::util::branch_iter_ind< fllt_node_elt<P,
V> >
-# define fllt_branch_iter(P, V) mln::util::branch_iter< fllt_node_elt<P, V>
>
-
-# define stl_to_mln_iter(T) stl_iterator< T >
-
- //Fwd declarations.
- template <typename V> struct lower;
- template <typename V> struct upper;
-
- template <typename P, typename V>
- struct fllt_node_elt
- {
- V value;
- p_array<P> points;
- p_array<P> holes;
- std::vector<fllt_node(P, V)*> hole_shapes;
- /// Tell if his parent if brighter or not. Nb : if the parent
- /// if brighter, the node come from the lower level set
- bool brighter;
- unsigned nsites;
- bool tagged;
- bool set_id;
-
- fllt_node_elt(bool set_id) : nsites(0), tagged(false), set_id(set_id) {}
- };
-
-
- template <typename C>
- class stl_iterator
- {
- public:
- stl_iterator(C& c) : container_(c) {}
- void start(){ it_ = container_.begin(); }
- void next() { it_++; }
- bool is_valid() const{ return it_ != container_.end(); }
- typename C::value_type& operator*() { return *it_; }
-
- private:
- C& container_;
- typename C::iterator it_;
- };
-
- template <typename N_t, typename G, typename Set>
- void update_gN(const N_t& N, G& gN);
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, lower<V>)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, upper<V>)
- {
- for (int g = 255; g >= 0; --g)
- {
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- }
- // if N is empty, gN is the min value.
- gN = 0;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i]->nsites() == 0)
- continue;
- std::cout << i << ": " << *N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i]->clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- mln::opt::at(output, row, col) =
- mln::opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- void save_u(const image2d<value::int_u8>& u,
- const image2d<int>& is,
- box2d R_box,
- int in_R,
- int in_N)
- {
- static int id = 0;
- std::stringstream filename;
- filename << "fllt_trace_" << std::setw(5) <<
std::setfill('0')
- << std::right << id++ << ".ppm";
-
- image2d<value::int_u8> out = duplicate(cast_image<value::int_u8>(is));
-
- mln_assertion(R_box.nsites() > 0);
- mln_piter_(box2d) p(R_box);
- for_all(p)
- if (is(p) == in_R)
- out(p) = 255;
- else if (is(p) == in_N)
- out(p) = 127;
- // else if (is(p) == in_N)
- // out(p) = literal::green;
-
- io::pgm::save(out, filename.str());
- //io::pgm::save(out, filename.str());
- }
-
- template <typename I>
- void save(const I& is, unsigned in_N, unsigned in_R, const std::string& name
= "")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- if (is(p) == in_R)
- temp(p) = literal::red;
- else if (is(p) == in_N) // N
- temp(p) = literal::green;
- else if (is(p) < in_N)
- temp(p) = literal::blue;
- else
- temp(p) = literal::white;
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter << ".ppm";
- io::ppm::save(my::enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
-
- template <typename I, typename P, typename V, typename Set>
- void blob(const Set&,
- const I& is,
- p_array<mln_point(I)>* N[256],
- unsigned in_N,
- const box2d& N_box,
- fllt_node(P, V)* current_cc)
- {
- typedef p_array<mln_point(I)> arr_t;
-
-// std::cout << ">>>>>>>enter blob. " <<
current_cc << std::endl;
- bool flower = true;
- unsigned ncc = 0;
- static image2d<unsigned> is_labeled(is.domain());
- static unsigned label = 0;
-
- if (label == 0)
- {
- data::fill(is_labeled, 0);
- label++;
- }
-
- P cur;
- mln_niter(neighb2d) n(Set::bdr_nbh()/*c8()*/, cur);
- p_queue_fast<P> qu;
- p_array<P>& holes = current_cc->elt().holes;
-
- mln_piter(I) p(N_box);
- for_all(p)
- if (is(p) == in_N)
- break;
-
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
-
-
-
- for (unsigned i = 0; i < 256; ++i)
- //for (int i = 255; i >= 0; --i)
- {
- mln_piter(arr_t) p(*N[i]);
- for_all(p)
- {
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
- }
- }
-
- ++label;
-
- // if (holes.size() == 2)
- // std::cout << holes[0] << holes[1] << std::endl;
- // std::cout << " <<<<<<<exiting blob."
<< std::endl;
- }
-
-// template <typename I, typename V>
-// void blob(const I& is,
-// p_array<mln_point(I)>* N[256],
-// unsigned in_N,
-// const box2d& N_box,
-// fllt_node(mln_point(I), V)* current_cc)
-// {
-// typedef p_array<mln_point(I)> arr_t;
-
-// // std::cout << ">>>>>>>enter blob. "
<< current_cc << std::endl;
-// bool flower = true;
-// unsigned ncc = 0;
-// static image2d<unsigned> is_labeled(is.domain());
-// static unsigned label = 0;
-
-// if (label == 0)
-// {
-// data::fill(is_labeled, 0);
-// label++;
-// }
-
-// typedef mln_psite(I) P;
-// P cur;
-// mln_niter(neighb2d) n(c8(), cur);
-// p_queue_fast<P> qu;
-// p_array<P>& holes = current_cc->elt().holes;
-
-// mln_piter(I) p(N_box);
-// for_all(p)
-// if (is(p) == in_N)
-// break;
-
-// mln_assertion(is(p) == in_N);
-// if (is_labeled(p) != label)
-// {
-// if (flower == false)
-// holes.append(p);
-// else
-// flower = false;
-// qu.push(p);
-// is_labeled(p) = label;
-// do
-// {
-// cur = qu.front();
-// qu.pop();
-// for_all(n) if (is.has(n))
-// if (is(n) == in_N && is_labeled(n) != label)
-// {
-// qu.push(n);
-// is_labeled(n) = label;
-// }
-// }
-// while (! qu.is_empty());
-// }
-
-
-
-// for (unsigned i = 0; i < 256; ++i)
-// //for (int i = 255; i >= 0; --i)
-// {
-// mln_piter(arr_t) p(*N[i]);
-// for_all(p)
-// {
-// mln_assertion(is(p) == in_N);
-// if (is_labeled(p) != label)
-// {
-// if (flower == false)
-// holes.append(p);
-// else
-// flower = false;
-// qu.push(p);
-// is_labeled(p) = label;
-// do
-// {
-// cur = qu.front();
-// qu.pop();
-// for_all(n) if (is.has(n))
-// if (is(n) == in_N && is_labeled(n) != label)
-// {
-// qu.push(n);
-// is_labeled(n) = label;
-// }
-// }
-// while (! qu.is_empty());
-// }
-// }
-// }
-
-// ++label;
-
-// // if (holes.size() == 2)
-// // std::cout << holes[0] << holes[1] << std::endl;
-// // std::cout << " <<<<<<<exiting
blob." << std::endl;
-// }
-
- template <typename P, typename V>
- void
- move_A_to_R(p_array<P>& A,
- image2d<int>& deja_vu,
- fllt_node(P, V)* current_cc,
- image2d< fllt_node(P, V)* >& smallest_shapes,
- int in_R,
- int in_N,
- const V& g,
- unsigned& n_comps)
- {
- typedef p_array<P> arr_t;
-
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(deja_vu(a) == in_N);
- mln_invariant(smallest_shapes(a) != current_cc);
-
- deja_vu(a) = in_R;
- current_cc->elt().nsites++;
- if (!smallest_shapes(a))
- {
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- if (!smallest_shapes(a)->parent())
- if (smallest_shapes(a)->elt().value == g)
- {
- fllt_node(P, V)* to_delete = smallest_shapes(a);
-
- mln_piter(arr_t) p(smallest_shapes(a)->elt().points);
- // Todo optimization here.
- for_all(p)
- smallest_shapes(p) = 0;
-
- while(!to_delete->children().empty())
- current_cc->add_child(*to_delete->children().begin());
- delete to_delete;
- n_comps--;
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- smallest_shapes(a)->set_parent(current_cc);
- // N_box is not re-computed so that we save time;
- // N_box is always growing while looping from step 3.
- }
- }
-
- // LOWER LEVEL SET : region = c4, border = c8
- template <typename V>
- struct lower
- {
- typedef upper<V> opposite;
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- {
- return u < v;
- }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>& nbh,
L& nlabels)
- {
- return labeling::regional_minima(input, nbh, nlabels);
- }
-
- static const bool parent_is_brighter = true;
- static const bool id = false;
-
- static const neighb2d& bdr_nbh() { return c8(); }
- static const neighb2d& reg_nbh() { return c4(); }
- };
-
-
- // UPPER LEVEL SET : region = c8, border = c4
- template <typename V>
- struct upper
- {
- typedef lower<V> opposite;
-
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- { return u > v; }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>& nbh,
L& nlabels)
- { return labeling::regional_maxima(input, nbh, nlabels); }
-
- static const bool parent_is_brighter = false;
- static const bool id = true;
-
- static const neighb2d& bdr_nbh() { return c4(); }
- static const neighb2d& reg_nbh() { return c8(); }
- };
-
- template <typename I, typename Set>
- fllt_tree(mln_point(I), mln_value(I))&
- level_set(const Image<I>& input_,
- image2d< fllt_node(mln_point(I), mln_value(I))* >& smallest_shapes)
- {
-
- typedef mln_point(I) P;
- typedef mln_value(I) V;
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
-
- const I& input = exact(input_);
-
- mln_assertion(input.domain() == smallest_shapes.domain());
-
- unsigned l = 0, l_max = 0;
- mln_ch_value(I, unsigned) reg_min = Set::regional_extremum(input, Set::reg_nbh(),
l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- I u = mln::duplicate(input);
- P x0;
- V g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
- data::fill(smallest_shapes, 0);
- node_type* current_cc;
-
- unsigned in_N = 1, in_R = 2;
-
- image2d<int> deja_vu(input.domain().to_larger(1));
- data::fill(deja_vu, 0);
-
- typedef p_array<P> arr_t;
- arr_t* A = new arr_t();
- arr_t* N[256];
- for (unsigned i = 0; i < 256; ++i)
- N[i] = new arr_t();
- accu::bbox<P> N_box;
-
- bool touch_border_of_image = false;
- unsigned n_step_1 = 0, n_step_3 = 0, n_comps = 0, n_holes = 0;
-
- // Step 1.
- step_1:
- {
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- ++n_comps;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- touch_border_of_image = false;
-
- }
-
- // Step 2.
- step_2:
- {
- in_N += 2;
- in_R = in_N + 1;
- // R <- 0 and N <- 0
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A->clear();
- A->append(x0);
- N_box.take(x0);
-
- deja_vu(x0) = in_R;
- smallest_shapes(x0) = current_cc;
- current_cc->elt().points.append(x0);
- current_cc->elt().nsites++;
-
- }
-
- // Step 3.
- step_3:
- {
-// save_u(u, deja_vu, N_box, in_R, in_N);
- ++n_step_3;
-
- mln_piter(arr_t) a(*A);
- mln_niter(neighb2d) x(Set::reg_nbh(), a);
-
-
- // R <- R U A
- if (A->nsites() == 0)
- goto the_end;
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- {
- if (deja_vu.has(x) && deja_vu(x) < in_N)
- {
- if (u.has(x))
- {
- N[u(x)]->append(x);
- N_box.take(x);
- }
- else
- touch_border_of_image = true;
- deja_vu(x) = in_N;
- }
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN, Set());
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (Set::compare(g, gN))
- {
- g = gN;
-
- ++n_comps;
-
- if (touch_border_of_image)
- blob(Set(), deja_vu, N, in_N, N_box.to_result().to_larger(1), current_cc);
- else
- blob(Set(), deja_vu, N, in_N, N_box, current_cc);
-
- n_holes += current_cc->elt().holes.nsites();
-
- node_type* child = current_cc;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- child->set_parent(current_cc);
-
-
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // c)
- else
- {
- // FIXME: IDEA: this change might be performed while R is constructed(?)
- mln_piter(I) r(N_box);
- for_all(r)
- if (deja_vu(r) == in_R)
- u(r) = g;
-
- goto step_1;
- }
- }
-
- the_end:
- std::cout << "l_max " << l_max << " "
<< n_step_1 << ' ' << n_step_3 << std::endl;
- std::cout << "n comps = " << n_comps << " n holes
= " << n_holes << std::endl;
-
- return *new tree_type(current_cc);
- }
-
- // F is the set in which we get the node.
- template <typename P, typename V, typename F>
- fllt_node(P, V)*
- find_hole(fllt_node(P, V)& node,
- const P p,
- const image2d<fllt_node(P, V)*>& other_reg)
- {
- fllt_node(P, V)* s = other_reg(p);
- mln_assertion(s);
- while (s->parent() && F::compare(s->parent()->elt().value,
node.elt().value))
- {
- mln_assertion(s);
- s = s->parent();
- mln_assertion(s);
- }
-// std::cout << " [Find the hole] of " << p
-// << " from " << &node
-// << " return " << s
-// << std::endl;
- return s;
- }
-
- template <typename P, typename V>
- bool shape_is_included(fllt_node(P, V)* A,
- fllt_node(P, V)* B)
- {
- return A->parent() == B || A == B;
- }
-
- template <typename P, typename V>
- void find_all_holes(fllt_tree(P, V)& lower_tree,
- fllt_tree(P, V)& upper_tree,
- const image2d<fllt_node(P, V)*>& low_reg,
- const image2d<fllt_node(P, V)*>& upp_reg)
- {
- typedef p_array<P> arr_t;
- typedef fllt_node(P, V) node_type;
-
- {
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,upper<V> >(node, P(hole),
upp_reg));
- }
- }
-
- {
- fllt_branch_iter_ind(P, V) node_(upper_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,lower<V> >(node, P(hole),
low_reg));
- }
- }
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- merge_trees(fllt_tree(mln_point(I), mln_value(I))& lower_tree,
- fllt_tree(mln_point(I), mln_value(I))& upper_tree,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& low_reg,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& upp_reg,
- const Image<I>& input_)
- {
-
- const I& input = exact(input_);
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
- typedef p_array<P> arr_t;
-
-
- find_all_holes(lower_tree, upper_tree, low_reg, upp_reg);
- std::vector<node_type*> to_fill;
-
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != lower<V>::id)
- continue;
-
- // std::cout << "Fill " << &node << std::endl;
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- // std::cout << "hole : " << hole << "
" << hole->elt().points << " " << std::endl;
- // std::cout << "child hole : " << child_hole
<< " " << child_hole->elt().points << std::endl;
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
- if (!child_has_bigger_hole)
- {
- // // std::cout << "move " << hole << " as
child of " << &node << std::endl;
- node.add_child(hole);
- to_fill.push_back(hole);
- }
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- for(typename std::vector<node_type*>::iterator node_ = to_fill.begin();
- node_ != to_fill.end();
- node_++)
- {
- node_type& node = **node_;
-
- fllt_branch_iter_ind(P, V) node_(fllt_branch(P, V)(upper_tree, node));
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != upper<V>::id)
- continue;
-
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- //if (hole->elt().points <= child_hole->elt().points)
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
-
- if (!child_has_bigger_hole)
- node.add_child(hole);
-
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- }
-
- return lower_tree;
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- fllt(const Image<I>& input_)
- {
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- const I& input = exact(input_);
-
- fllt_tree(P, V) upper_tree;
- fllt_tree(P, V) lower_tree;
- image2d<fllt_node(P, V)*> low_reg(input.domain());
- image2d<fllt_node(P, V)*> upp_reg(input.domain());
-
- std::cout << "1/ Compute the lower level
set.----------------------------------------" << std::endl;
- lower_tree = level_set<I, lower<V> >(input, low_reg);
- //draw_tree(input, lower_tree);
-
- std::cout << "2/ Compute the upper level
set.----------------------------------------" << std::endl;
- upper_tree = level_set<I, upper<V> >(input, upp_reg);
- //draw_tree(input, upper_tree);
-
- std::cout << "3/
Merge.---------------------------------------------------------------" <<
std::endl;
- fllt_tree(P, V) result_tree = merge_trees(lower_tree, upper_tree, low_reg, upp_reg,
input);
-
- return result_tree;
- }
-
- template <typename P, typename V>
- void
- draw_tree(const image2d<V>& ima,
- fllt_tree(P, V)& tree)
- {
- p_array<P> tmp;
-
- fllt_branch_iter_ind(P, V) p(tree.main_branch());
- for_all(p)
- {
- std::cout << "region mere : " << (*p).parent() <<
std::endl;
- std::cout << " ^" << std::endl;
- std::cout << " |" << std::endl;
- std::cout << "region : " << &*p
- << " value = " << (*p).elt().value << std::endl
- << " from " << ((*p).elt().set_id == lower<V>::id ?
"lower" : "upper") << " level set." <<
std::endl
- << " nsites = " << (*p).elt().nsites << std::endl
- << " holes = " << (*p).elt().holes << std::endl;
-
- std::cout << std::endl;
-
- tmp.append((*p).elt().points);
-
- fllt_branch_iter_ind(P, V) n(fllt_branch(P, V)(tree, *p));
- for_all(n)
- tmp.append((*n).elt().points);
-
- if ((*p).elt().points.nsites() > 0)
- debug::println(ima | tmp);
- tmp.clear();
-
- std::cout << std::endl;
- }
- }
-
-
- template <typename P, typename V, typename I>
- unsigned
- compute_area_rec(fllt_node(P, V)* node, I& ima)
- {
-
- if (!node)
- return 0;
-
- int area = 0;
-
- for (int i = 0; i < node->children().size();i++)
- area += compute_area_rec(node->children()[i], ima);
-
- mln_piter(p_array<P>) p(node->elt().points);
- for_all(p)
- if (!ima(P(p)))
- {
- ++area;
- ima(p) = true;
- }
-
- node->elt().nsites = area;
- return area;
- }
-
- template <typename P, typename V, typename I>
- void
- compute_area(const Image<I>& input_, fllt_tree(P, V)& tree)
- {
- const I& input = exact(input_);
-
- image2d<bool> ima(input.domain());
- data::fill(ima, false);
- compute_area_rec(tree.root(), ima);
- }
-
- void draw_shape(image2d<value::int_u8>& output,
- fllt_node(point2d, value::int_u8)* node)
- {
- typedef point2d P ;
- typedef value::int_u8 V;
-
- fllt_tree(P, V) subtree(node);
- fllt_branch_iter_ind(P, V) s(fllt_branch(P, V)(subtree, *node));
- for_all(s)
- data::fill(output | (*s).elt().points), (*s).elt().value);
- }
-
- void area_filter(image2d<value::int_u8>& output,
- fllt_node(point2d, value::int_u8)* node,
- unsigned min_area,
- unsigned max_area,
- value::int_u8 bg)
- {
- typedef point2d P ;
- typedef value::int_u8 V;
-
- data::fill(output, bg);
- fllt_tree(P, V) subtree(node);
- fllt_branch_iter_ind(P, V) s(fllt_branch(P, V)(subtree, *node));
- for_all(s)
- if ((*s).elt().nsites > min_area && (*s).elt().nsites < max_area)
- draw_shape(output, &*s);
- }
-
- void area_filter_min(image2d<value::int_u8>& output,
- fllt_node(point2d, value::int_u8)* node,
- unsigned min_area,
- value::int_u8 g,
- unsigned accu)
- {
-// if ((*node).elt().nsites >= min_area)
- if (accu > min_area)
- {
- accu = 0;
- g = (*node).elt().value;
- }
-
- accu += (*node).elt().nsites;
- data::fill(output | (*node).elt().points), g);
-
- for (int i = 0; i < node->children().size();i++)
- area_filter_min(output, node->children()[i], min_area, g, accu);
- }
-
- } // end of namespace mln::my
-
-} // end of namespace mln
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using namespace mln::my;
- using value::int_u8;
-
- typedef fllt_tree(point2d, int_u8) tree_type;
-
-
-
-// if (argc != 2)
-// {
-// std::cerr << "usage: " << argv[0] << "
filename" << std::endl;
-// return 1;
-// }
-
- image2d<int_u8> lena;
- io::pgm::load(lena, argv[1]);
-
-
-// int vs[8][9] = { {0,0,0,0,0,0,0,0,0},
-// {0,0,0,0,0,0,0,0,0},
-// {0,1,1,1,1,1,1,1,0},
-// {0,1,0,0,1,3,3,1,0},
-// {0,1,0,0,1,3,4,1,0},
-// {0,1,0,0,1,3,3,1,0},
-// {0,1,1,1,1,1,1,1,0},
-// {0,0,0,0,0,0,0,0,0} };
-
-
-
-// int vs[8][9] = { {6,6,6,6,6,6,6,6,6},
-// {6,6,6,6,6,6,6,6,6},
-// {6,5,5,5,5,5,5,5,6},
-// {6,5,6,6,5,3,3,5,6},
-// {6,5,6,6,5,3,0,5,6},
-// {6,5,6,6,5,3,3,5,6},
-// {6,5,5,5,5,5,5,5,6},
-// {6,6,6,6,6,6,6,6,6} };
-
-// int vs[8][9] = { {2,2,2,2,2,2,2,2,2},
-// {2,2,2,2,2,2,2,2,2},
-// {2,1,1,1,1,1,1,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,1,1,1,1,1,1,2},
-// {2,2,2,2,2,2,2,2,2} };
-
-
- int vs[8][9] = { {2,2,2,2,2,2,2,2,2},
- {2,2,2,2,2,2,2,2,2},
- {2,1,1,1,1,1,1,1,2},
- {2,1,2,2,1,0,0,1,2},
- {2,1,2,2,1,0,4,1,2},
- {2,1,2,2,1,0,0,1,2},
- {2,1,1,1,1,1,1,1,2},
- {2,2,2,2,2,2,2,2,2} };
-
-// int vs[10][13] = { {1,1,1,1, 1,1,1,1, 1,1,1,1,1},
-// {1,2,2,2,2,2,2,2,2,2,2,2,1},
-// {1,2,2,2,2,2,2,2,2,2,2,2,1},
-// {1,2,2,2,3,3,3,3,3,3,3,2,1},
-// {1,2,2,2,3,3,3,2,2,2,3,2,1},
-// {1,2,2,2,3,4,3,2,4,4,3,2,1},
-
-// {1,2,2,2,3,3,3,2,2,2,3,2,1},
-// {1,2,2,2,3,3,3,3,3,3,3,2,1},
-// {1,2,2,2,2,2,2,2,2,2,2,2,1},
-// {1,1,1,1,1,1,1,1,1,1,1,1,1}};
-
-
-// image2d<int> lena_(make::image2d(vs));
-// image2d<int_u8> lena(lena_.domain());
-// data::fill(lena, lena_);
-
- tree_type tree = my::fllt(lena);
- compute_area(lena, tree);
-
- image2d<value::int_u8> output (lena.domain ());
-// area_filter_min(output, tree.root(), atoi(argv[2]), 0, 0);
- area_filter(output, tree.root(), atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
- io::pgm::save(output, "out.pgm");
-
- // draw_tree(lena, tree);
-}
Index: geraud/p_runs__with_dedicated_piter.hh
--- geraud/p_runs__with_dedicated_piter.hh (revision 3151)
+++ geraud/p_runs__with_dedicated_piter.hh (working copy)
@@ -1,758 +0,0 @@
-// Copyright (C) 2007, 2008 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_CORE_SITE_SET_P_RUNS_HH
-# define MLN_CORE_SITE_SET_P_RUNS_HH
-
-/*! \file mln/core/p_runs.hh
- *
- * \brief Definition of a set of point runs.
- */
-
-# include <mln/accu/bbox.hh>
-# include <mln/core/site_set/p_run.hh>
-# include <mln/core/p_double.hh>
-# include <mln/core/internal/piter_adaptor.hh>
-# include <mln/util/set.hh>
-
-
-
-namespace mln
-{
-
- // Forward declarations.
- template <typename P> class p_runs;
- template <typename P> class p_runs_psite;
- template <typename P> class p_runs_fwd_piter_;
- template <typename P> class p_runs_bkd_piter_;
-
-
- namespace trait
- {
-
- template <typename P>
- struct site_set_< p_runs<P> >
- {
- typedef trait::site_set::nsites::known nsites;
- typedef trait::site_set::bbox::known bbox;
- typedef trait::site_set::contents::growing contents;
- typedef trait::site_set::arity::unique arity;
- };
-
- } // end of namespace trait
-
-
-
- /*! \brief p_runs is a site set composed of runs.
- *
- * Parameter \c P is the type of the image point.
- */
- template <typename P>
- class p_runs : public internal::site_set_base_< P, p_runs<P> >
- {
- typedef p_runs<P> self_;
- public:
-
- /// Element associated type.
- typedef p_run<P> element;
-
-
- /// Psite associated type.
- typedef p_runs_psite<P> psite;
-
- /// Forward Site_Iterator associated type.
- typedef p_runs_fwd_piter_<P> fwd_piter;
-
- /// Backward Site_Iterator associated type.
- typedef p_runs_bkd_piter_<P> bkd_piter;
-
- /// Site_Iterator associated type.
- typedef fwd_piter piter;
-
-
- /// Constructor without arguments.
- p_runs();
-
-
- /// Test if \p p belongs to this point set.
- bool has(const psite&) const;
-
- /// Test if this set of runs is valid.
- bool is_valid() const;
-
-
- /// Box associated type.
- typedef const mln::box<P>& q_box;
-
- /// Give the exact bounding box.
- const box<P>& bbox() const;
-
-
- /// Give the number of points.
- unsigned nsites() const;
-
- /// Give the number of runs.
- unsigned nruns() const;
-
- /// Give the compression ratio: FIXME: explain...
- float zratio() const;
-
-
- /// Insertion element associated type.
- typedef p_run<P> i_element;
-
- /// Insert a run \p r.
- void insert(const p_run<P>& r);
-
- /// Insert a run from \p start to \p end.
- void insert(const P& start, const P& end);
-
- /// Insert a run defined by \p start with length \p len.
- void insert(const P& start, unsigned short len);
-
- /// Insert another set of runs.
- void insert(const p_runs<P>& other);
-
-
- /// Clear this set.
- void clear();
-
-
- /// Return the i-th run.
- const p_run<P>& run(unsigned i) const;
-
- /// Return the size of this site set in memory.
- std::size_t memory_size() const;
-
- /// Hook to the set of runs.
- const util::set< p_run<P> >& hook_() const;
-
-
- protected:
-
- /// Number of points.
- unsigned nsites_;
-
- /// Bounding box accumulator.
- accu::bbox<P> b_;
-
- /// Set of runs.
- util::set< p_run<P> > run_;
- };
-
-
-
- template <typename P>
- std::ostream& operator<<(std::ostream& ostr, const p_runs<P>&
r);
-
-
- namespace util
- {
-
- template <typename P>
- struct less< p_runs<P> >
- {
- bool operator()(const p_runs<P>& lhs,
- const p_runs<P>& rhs) const;
- };
-
- } // end of namespace mln::util
-
-
-
- // p_runs_psite<P>
-
- template <typename P>
- class p_runs_psite : public internal::pseudo_site_base_< const P&,
- p_runs_psite<P> >
- {
- typedef p_runs_psite<P> self;
- typedef internal::pseudo_site_base_<const P&, self> super;
-
- public:
-
- // This associated type is important to know that this particular
- // pseudo site knows the site set it refers to.
- typedef p_runs<P> target;
-
- p_runs_psite();
-
- // As a Proxy:
- const P& subj_();
-
- const p_runs<P>* target_() const;
- void change_target(const p_runs<P>& new_target);
-
- bool is_valid() const;
-
- short index_in_run() const;
- void set_index_in_run(short i);
- void inc_index_in_run();
- void dec_index_in_run();
-
- unsigned run_index() const;
- void goto_run_start(unsigned r);
- void goto_run_end(unsigned r);
-
- unsigned run_length() const;
-
- private:
-
- const p_runs<P>* s_;
- unsigned r_;
- short i_;
- mutable P p_;
- };
-
-
- // p_runs_fwd_piter_
-
- template <typename P>
- class p_runs_fwd_piter_
- :
- public internal::site_set_iterator_base< p_runs<P>,
- p_runs_fwd_piter_<P> >
- {
- typedef p_runs_fwd_piter_<P> self_;
- typedef internal::site_set_iterator_base< p_runs<P>, self_ > super_;
- public:
-
- /// Constructor without arguments.
- p_runs_fwd_piter_();
-
- /// Constructor.
- p_runs_fwd_piter_(const p_runs<P>& r);
-
- /// Test if the iterator is valid.
- bool is_valid_() const;
-
- /// Invalidate the iterator.
- void invalidate_();
-
- /// Start an iteration.
- void start_();
-
- /// Go to the next point.
- void next_();
-
- protected:
- using super_::p_;
- using super_::s_;
- unsigned short len_;
- };
-
-
-
- // p_runs_bkd_piter_
-
- template <typename P>
- class p_runs_bkd_piter_
- :
- public internal::site_set_iterator_base< p_runs<P>,
- p_runs_bkd_piter_<P> >
- {
- typedef p_runs_bkd_piter_<P> self_;
- typedef internal::site_set_iterator_base< p_runs<P>, self_ > super_;
- public:
-
- /// Constructor without arguments.
- p_runs_bkd_piter_();
-
- /// Constructor.
- p_runs_bkd_piter_(const p_runs<P>& r);
-
- /// Test if the iterator is valid.
- bool is_valid_() const;
-
- /// Invalidate the iterator.
- void invalidate_();
-
- /// Start an iteration.
- void start_();
-
- /// Go to the next point.
- void next_();
-
- protected:
- using super_::p_;
- using super_::s_;
- };
-
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-
- // p_runs
-
- template <typename P>
- inline
- p_runs<P>::p_runs()
- :
- nsites_(0)
- {
- }
-
- template <typename P>
- inline
- bool
- p_runs<P>::has(const p_runs_psite<P>& p) const
- {
- mln_precondition(p.target_() == this); // FIXME: Refine.
- if (p.run_index() >= nruns() ||
- p.index_in_run() < 0 ||
- p.index_in_run() >= run_[p.run_index()].length())
- return false;
- // The type of rhs below is mln_site(p_run<P>).
- mln_invariant(p.to_site() == run_[p.run_index()][p.index_in_run()]);
- return true;
- }
-
- template <typename P>
- inline
- bool
- p_runs<P>::is_valid() const
- {
- // FIXME: A run of this set can be invalid...
- return true;
- }
-
- template <typename P>
- inline
- const box<P>&
- p_runs<P>::bbox() const
- {
- return b_.to_result();
- }
-
- template <typename P>
- inline
- unsigned
- p_runs<P>::nsites() const
- {
- return nsites_;
- }
-
- template <typename P>
- inline
- void
- p_runs<P>::insert(const p_runs<P>& other)
- {
- if (other.nsites() == 0)
- // No-op.
- return;
- nsites_ += other.nsites();
- b_.take(other.bbox());
- run_.insert(other.run_);
- }
-
- template <typename P>
- inline
- void
- p_runs<P>::insert(const p_run<P>& r)
- {
- nsites_ += r.nsites();
- b_.take(r.bbox());
- run_.insert(r);
- }
-
-
-// Previous code of 'insert' was:
-//
-// {
-// typename std::vector<p_run<P> >::const_iterator iter =
con_.vect().begin();
-// while (iter != con_.vect().end() && iter->first() < pr.first())
-// ++iter;
-
-// if (iter != con_.vect().begin())
-// {
-// typename std::vector<p_run<P> >::const_iterator prec = iter;
-// --prec;
-// bool equal = true;
-// for (int i = P::dim - 2; i >= 0; --i)
-// if (!(equal = equal && (prec->first()[i] == pr.first()[i])))
-// break;
-// if (equal)
-// mln_assertion(prec->first()[P::dim - 1] + (signed)prec->length()
-// <= pr.first()[P::dim - 1]);
-// }
-
-// if (iter != con_.vect().end())
-// {
-// bool equal = true;
-// for (int i = P::dim - 2; i >= 0; --i)
-// if (!(equal = equal && ((*iter).first()[i] == pr.first()[i])))
-// break;
-// if (equal)
-// mln_assertion(pr.first()[P::dim - 1] + (signed)pr.length()
-// <= iter->first()[P::dim - 1]);
-// }
-// con_.insert(pr);
-
-// // update box
-// fb_.take(pr.bbox().pmin());
-// fb_.take(pr.bbox().pmax());
-// // update size
-// nsites_ += pr.nsites();
-// }
-
-
- template <typename P>
- inline
- void
- p_runs<P>::insert(const P& start, const P& end)
- {
- mln_precondition(cut_(end) == cut_(start));
- mln_precondition(end.last_coord() >= start.last_coord());
- p_run<P> r(start, end);
- this->insert(r);
- }
-
- template <typename P>
- inline
- void
- p_runs<P>::insert(const P& start, unsigned short len)
- {
- mln_precondition(len != 0);
- p_run<P> r(start, len);
- this->insert(r);
- }
-
- template <typename P>
- inline
- void
- p_runs<P>::clear()
- {
- nsites_ = 0;
- b_.init();
- run_.clear();
- }
-
- template <typename P>
- inline
- unsigned
- p_runs<P>::nruns() const
- {
- return run_.nelements();
- }
-
- template <typename P>
- inline
- const p_run<P>&
- p_runs<P>::run(unsigned i) const
- {
- mln_precondition(i < nruns());
- return run_[i];
- }
-
- template <typename P>
- inline
- std::size_t
- p_runs<P>::memory_size() const
- {
- return run_.memory_size() + sizeof(nsites_) + sizeof(b_);
- }
-
- template <typename P>
- inline
- float
- p_runs<P>::zratio() const
- {
- return
- float(memory_size()) /
- float(b_.to_result().nsites() * sizeof(P));
- }
-
- template <typename P>
- inline
- const util::set< p_run<P> >&
- p_runs<P>::hook_() const
- {
- return run_;
- }
-
-
- template <typename P>
- std::ostream& operator<<(std::ostream& ostr, const p_runs<P>&
r)
- {
- return ostr << r.hook_();
- }
-
-
- namespace util
- {
-
- template <typename P>
- inline
- bool
- less< p_runs<P> >::operator()(const p_runs<P>& lhs,
- const p_runs<P>& rhs) const
- {
- return op_less(lhs.run(0), rhs.run(0));
- }
-
- } // end of namespace mln::util
-
-
-
- // p_runs_psite<P>
-
- template <typename P>
- inline
- p_runs_psite<P>::p_runs_psite()
- {
- s_ = 0;
- }
-
- template <typename P>
- inline
- const P&
- p_runs_psite<P>::subj_()
- {
- return p_;
- }
-
- template <typename P>
- inline
- const p_runs<P>*
- p_runs_psite<P>::target_() const
- {
- return s_;
- }
-
- template <typename P>
- inline
- void
- p_runs_psite<P>::change_target(const p_runs<P>& new_target)
- {
- s_ = & new_target;
- goto_run_start(0);
- }
-
- template <typename P>
- inline
- bool
- p_runs_psite<P>::is_valid() const
- {
- return
- s_ != 0 &&
- r_ < s_->nruns() &&
- i_ >= 0 && i_ < s_->run(r_).length();
- }
-
- template <typename P>
- inline
- short
- p_runs_psite<P>::index_in_run() const
- {
- return i_;
- }
-
- template <typename P>
- inline
- void
- p_runs_psite<P>::set_index_in_run(short i)
- {
- p_.last_coord() += (i - i_);
- i_ = i;
- }
-
- template <typename P>
- inline
- void
- p_runs_psite<P>::inc_index_in_run()
- {
- ++i_;
- p_.last_coord() += 1;
- }
-
- template <typename P>
- inline
- void
- p_runs_psite<P>::dec_index_in_run()
- {
- --i_;
- p_.last_coord() -= 1;
- }
-
- template <typename P>
- inline
- unsigned
- p_runs_psite<P>::run_index() const
- {
- return r_;
- }
-
- template <typename P>
- inline
- void
- p_runs_psite<P>::goto_run_start(unsigned r)
- {
- r_ = r;
- if (r_ < s_->nruns())
- {
- i_ = 0;
- p_ = s_->run(r).start();
- }
- }
-
- template <typename P>
- inline
- void
- p_runs_psite<P>::goto_run_end(unsigned r)
- {
- r_ = r;
- if (r_ < s_->nruns())
- {
- i_ = s_->run(r).length() - 1;
- p_ = s_->run(r).end();
- }
- }
-
- template <typename P>
- inline
- unsigned
- p_runs_psite<P>::run_length() const
- {
- if (s_ == 0 || r_ >= s_->nruns())
- return 0;
- else
- return s_->run(r_).length();
- }
-
-
- // p_runs_fwd_piter_<P>
-
- template <typename P>
- inline
- p_runs_fwd_piter_<P>::p_runs_fwd_piter_()
- {
- }
-
- template <typename P>
- inline
- p_runs_fwd_piter_<P>::p_runs_fwd_piter_(const p_runs<P>& r)
- {
- this->change_target(r);
- }
-
- template <typename P>
- inline
- bool
- p_runs_fwd_piter_<P>::is_valid_() const
- {
- return len_ != 0;
- }
-
- template <typename P>
- inline
- void
- p_runs_fwd_piter_<P>::invalidate_()
- {
- len_ = 0;
- }
-
- template <typename P>
- inline
- void
- p_runs_fwd_piter_<P>::start_()
- {
- p_.goto_run_start(0);
- len_ = p_.run_length();
- }
-
- template <typename P>
- inline
- void
- p_runs_fwd_piter_<P>::next_()
- {
- p_.inc_index_in_run();
- if (p_.index_in_run() == short(len_))
- {
- p_.goto_run_start(p_.run_index() + 1);
- len_ = p_.run_length();
- // len_ is null when p_ is invalid.
- }
- }
-
-
- // p_runs_bkd_piter_<P>
-
- template <typename P>
- inline
- p_runs_bkd_piter_<P>::p_runs_bkd_piter_()
- {
- }
-
- template <typename P>
- inline
- p_runs_bkd_piter_<P>::p_runs_bkd_piter_(const p_runs<P>& r)
- {
- this->change_target(r);
- }
-
- template <typename P>
- inline
- bool
- p_runs_bkd_piter_<P>::is_valid_() const
- {
- return p_.index_in_run() != -1;
- }
-
- template <typename P>
- inline
- void
- p_runs_bkd_piter_<P>::invalidate_()
- {
- p_.set_index_in_run(-1);
- }
-
- template <typename P>
- inline
- void
- p_runs_bkd_piter_<P>::start_()
- {
- p_.goto_run_end(s_->nruns() - 1);
- }
-
- template <typename P>
- inline
- void
- p_runs_bkd_piter_<P>::next_()
- {
- p_.dec_index_in_run();
- if (p_.index_in_run() == -1)
- p_.goto_run_end(p_.run_index() - 1);
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of namespace mln
-
-
-#endif // ! MLN_CORE_SITE_SET_P_RUNS_HH
Index: geraud/win_fun.cc
--- geraud/win_fun.cc (revision 3151)
+++ geraud/win_fun.cc (working copy)
@@ -1,160 +0,0 @@
-# include <mln/core/image/image2d.hh>
-# include <mln/core/alias/window2d.hh>
-# include <mln/win/rectangle2d.hh>
-# include <mln/win/fun.hh>
-
-# include <mln/debug/iota.hh>
-# include <mln/debug/println.hh>
-
-
-// # include <mln/morpho/gradient.bis.hh>
-// # include <mln/morpho/erosion.bis.hh>
-
-// # include <mln/value/int_u8.hh>
-// # include <mln/io/pgm/load.hh>
-// # include <mln/io/pgm/save.hh>
-
-
-template <typename I, typename W, typename P>
-void picture(const I& ima, const W& win, const P& p)
-{
- std::cout << ima(p) << ": ";
- mln_qiter(W) q(win, p);
- for_all(q)
- if (ima.has(q))
- std::cout << ima(q) << ' ';
- else
- std::cout << "- ";
- std::cout << std::endl;
-}
-
-
-
-struct uni_t
-{
- typedef mln::window2d result;
- mln::window2d win_;
- uni_t() { win_.insert(-1,0).insert(0,-1); }
- const mln::window2d& operator()(const mln::point2d& p) const { return win_; }
-} uni;
-
-
-struct bi_t
-{
- typedef mln::window2d result;
- mln::window2d win1_, win2_;
- bi_t() {
- win1_.insert(-1,0).insert(0,-1);
- win2_.insert( 1,0).insert(0, 1);
- }
- const mln::window2d& operator()(const mln::point2d& p) const {
- return p.col() % 2 ? win1_ : win2_;
- }
-} bi;
-
-
-struct bi_rect_t
-{
- typedef mln::win::rectangle2d result;
- result *win1_, *win2_;
- bi_rect_t() {
- win1_ = new result(1,3);
- win2_ = new result(3,1);
- }
- const result& operator()(const mln::point2d& p) const {
- return p.row() % 2 ? *win1_ : *win2_;
- }
-} bi_rect;
-
-
-// template <typename T>
-// struct grad_t
-// {
-// typedef mln::win::rectangle2d result;
-// mln::image2d<T> grad_;
-// std::vector<result*> win_;
-
-// grad_t(const mln::image2d<T>& gr)
-// {
-// grad_ = gr;
-// for (unsigned i = 0; i < 10; ++i)
-// {
-// unsigned l = i % 2 ? i : i + 1;
-// win_.push_back(new result(l, l));
-// }
-// }
-// const result& operator()(const mln::point2d& p) const {
-// float s = 1.f - grad_(p) / 256.f;
-// s *= s * s;
-// return * win_[unsigned(s * 9)];
-// }
-// };
-
-
-
-
-int main()
-{
- using namespace mln;
-
- typedef image2d<unsigned> I;
- I ima(2, 3, 0); // no border
- debug::iota(ima);
- debug::println(ima);
-
-
- {
- win::fun<uni_t> win(uni);
- mln_fwd_piter_(I) p(ima.domain());
- for_all(p)
- picture(ima, win, p);
- std::cout << std::endl;
- }
-
- {
- win::fun<bi_t> win(bi);
- mln_fwd_piter_(I) p(ima.domain());
- for_all(p)
- picture(ima, win, p);
- std::cout << std::endl;
- }
-
- {
- win::rectangle2d rect(3, 3);
- mln_fwd_piter_(I) p(ima.domain());
- for_all(p)
- picture(ima, rect, p);
- std::cout << std::endl;
- }
-
- {
- win::fun<bi_rect_t> win(bi_rect);
- mln_fwd_piter_(I) p(ima.domain());
- for_all(p)
- picture(ima, win, p);
- std::cout << std::endl;
- }
-
-
-
-// {
-// using value::int_u8;
-// image2d<int_u8> ima(2, 2);
-// // io::pgm::load(ima, "small.pgm");
-
-// window2d c4p;
-// c4p.insert(-1,0).insert(0,-1).insert(0,0).insert(0,1).insert(1,0);
-
-// grad_t<int_u8> f(morpho::gradient(ima, c4p));
-// win::fun< grad_t<int_u8> > win(f);
-
-// image2d<int_u8> ero = morpho::erosion(ima, win);
-// // io::pgm::save(ero, "ero.pgm");
-
-// mln_fwd_piter_(I) p(ima.domain());
-// for_all(p)
-// picture(ima, win, p);
-// std::cout << std::endl;
-// }
-
-}
Index: geraud/browsing/fwd.cc
--- geraud/browsing/fwd.cc (revision 3151)
+++ geraud/browsing/fwd.cc (working copy)
@@ -1,515 +0,0 @@
-# include <mln/core/image/image2d.hh>
-# include <mln/core/alias/window2d.hh>
-# include <mln/value/int_u8.hh>
-# include <mln/accu/min_h.hh>
-# include <mln/accu/max_h.hh>
-# include <mln/opt/at.hh>
-
-# include <mln/debug/println.hh>
-# include <mln/debug/iota.hh>
-
-# include "fwd.hh"
-
-
-struct base
-{
- void init() {}
- void final() {}
-
- void next() {}
-
- void begin() {}
- void end() {}
-};
-
-
-
-template <typename I_>
-struct iota : base
-{
- typedef I_ I;
-
- I input;
- mln_psite(I) p;
-
- unsigned c;
-
- void init()
- {
- c = 0;
- }
-
- void next()
- {
- input(p) = ++c;
- }
-};
-
-
-
-template <typename I_, typename A, typename W>
-struct accu_win : base
-{
- typedef I_ I;
-
- I input;
- W win;
- mln_psite(I) p;
- mln_qiter(W) q;
-
- mln_accu_with(A, mln_value(I)) a;
-
- accu_win(const I& input,
- const W& win)
- : input(input),
- win(win),
- p(),
- q(win, p)
- {
- }
-
- void next()
- {
- a.init();
- for_all(q) if (input.has(q))
- a.take(input(q));
- std::cout << a << ' ';
- }
-
- void final()
- {
- std::cout << std::endl;
- }
-};
-
-
-// generic(accu, ima)
-
-
-namespace mln
-{
-
- // template <typename I>
- // void line_inc(const I& ima, unsigned half)
- // {
- // box2d b = ima.domain();
- // unsigned nrows = b.nrows(), ncols = b.ncols();
-
- // for (unsigned row = 0; row < nrows; ++row)
- // {
- // unsigned col = 0;
-
- // std::cout << std::endl
- // << "START : "
- // << std::endl
- // << std::endl;
-
- // for (unsigned c = 0; c <= half; ++c)
- // std::cout << " take " << opt::at(ima, row, c) <<
" ";
- // std::cout << std::endl;
-
- // std::cout << " --> OK at " << opt::at(ima, row, col)
<< std::endl;
- // // ok (row, col) at line start
-
-
- // std::cout << std::endl
- // << "BEGIN : "
- // << std::endl
- // << std::endl;
-
- // unsigned col_plus = half;
-
- // while (col < half)
- // {
- // ++col;
- // ++col_plus;
- // std::cout << " take " << opt::at(ima, row, col_plus)
<< " ";
- // std::cout << " --> OK at " << opt::at(ima, row, col)
<< std::endl;
- // }
-
- // std::cout << std::endl
- // << "MIDDLE : "
- // << std::endl
- // << std::endl;
-
- // int col_minus = -1;
-
- // while (col < ncols - half - 1)
- // {
- // ++col;
- // ++col_plus;
- // ++col_minus;
- // std::cout << " take " << opt::at(ima, row, col_plus)
<< " ";
- // std::cout << " untake " << opt::at(ima, row, col_minus)
<< " ";
- // std::cout << " --> OK at " << opt::at(ima, row, col)
<< std::endl;
- // // ok (row, col) at line middle
- // }
- // std::cout << std::endl;
-
-
- // std::cout << std::endl
- // << "END : "
- // << std::endl
- // << std::endl;
-
- // while (col < ncols - 1)
- // {
- // ++col;
- // ++col_minus;
- // std::cout << " untake " << opt::at(ima, row, col_minus)
<< " ";
- // std::cout << " --> OK at " << opt::at(ima, row, col)
<< std::endl;
- // }
- // std::cout << std::endl;
-
- // abort();
- // }
- // }
-
-
-
- /*
-
- template <typename I>
- void line_inc(const I& ima,
- const mln_site(I)& pstart, unsigned len,
- unsigned half)
- {
- unsigned row = pstart.row();
- const unsigned col_start = pstart.col();
- const unsigned col_last = col_start + len - 1;
-
- std::cout << std::endl
- << "START : "
- << std::endl
- << std::endl;
-
- unsigned col = col_start;
-
- for (unsigned c = 0; c <= half && c < len; ++c)
- std::cout << " take " << opt::at(ima, row, col + c) <<
" ";
- std::cout << std::endl;
-
- std::cout << " --> OK at " << opt::at(ima, row, col)
<< std::endl;
- // ok (row, col) at line start
-
- if (col == col_last)
- return;
-
- std::cout << std::endl
- << "BEGIN : "
- << std::endl
- << std::endl;
-
- unsigned col_plus = col_start + half;
-
- while (col < col_start + half && col < col_last)
- {
- ++col;
- ++col_plus;
- if (col_plus <= col_last)
- std::cout << " take " << opt::at(ima, row, col_plus) <<
" ";
- std::cout << " --> OK at " << opt::at(ima, row, col) <<
std::endl;
- }
-
- if (col == col_last)
- return;
-
- std::cout << std::endl
- << "MIDDLE : "
- << std::endl
- << std::endl;
-
- int col_minus = col_start - 1;
-
-
- while (col < col_last - half)
- {
- ++col;
- ++col_plus;
- ++col_minus;
- mln_invariant(col_plus >= col_start && col_plus <= col_last);
- std::cout << " take " << opt::at(ima, row, col_plus) <<
" ";
- mln_invariant(col_minus >= col_start && col_minus <= col_last);
- std::cout << " untake " << opt::at(ima, row, col_minus) <<
" ";
- std::cout << " --> OK at " << opt::at(ima, row, col) <<
std::endl;
- // ok (row, col) at line middle
- }
- std::cout << std::endl;
-
- if (col == col_last)
- return;
-
- std::cout << std::endl
- << "END : "
- << std::endl
- << std::endl;
-
- while (col < col_last)
- {
- ++col;
- ++col_minus;
- mln_invariant(col_minus >= col_start && col_minus <= col_last);
- std::cout << " untake " << opt::at(ima, row, col_minus) <<
" ";
- std::cout << " --> OK at " << opt::at(ima, row, col) <<
std::endl;
- }
- std::cout << std::endl;
-
- }
-
- */
-
-
-
- /*
-
- template <typename I>
- void line_inc(unsigned dir,
- const I& ima,
- const mln_site(I)& p_start, unsigned len,
- unsigned half)
- {
- typedef mln_site(I) P;
- const unsigned start = p_start[dir];
- const unsigned last = start + len - 1;
-
- std::cout << std::endl
- << "START : "
- << std::endl
- << std::endl;
-
- P p = p_start;
-
- P q = p;
- for (unsigned c = 0; c <= half && c < len; ++c)
- {
- std::cout << " take " << ima(q) << " ";
- ++q[dir];
- }
- std::cout << std::endl;
-
- std::cout << " --> OK at " << ima(p) << std::endl;
-
- def::coord& cur = p[dir];
- if (cur == last)
- return;
-
- std::cout << std::endl
- << "BEGIN : "
- << std::endl
- << std::endl;
-
- P p_plus = p_start;
- def::coord& plus = p_plus[dir];
- plus += half;
-
- while (cur < start + half && cur < last)
- {
- ++cur;
- ++plus;
- if (plus <= last)
- std::cout << " take " << ima(p_plus) << " ";
- std::cout << " --> OK at " << ima(p) << std::endl;
- }
-
- if (cur == last)
- return;
-
- std::cout << std::endl
- << "MIDDLE : "
- << std::endl
- << std::endl;
-
- P p_minus = p_start;
- def::coord& minus = p_minus[dir];
- --minus;
-
- while (cur < last - half)
- {
- ++cur;
- ++plus;
- ++minus;
- mln_invariant(plus >= start && plus <= last);
- std::cout << " take " << ima(p_plus) << " ";
- mln_invariant(minus >= start && minus <= last);
- std::cout << " untake " << ima(p_minus) << " ";
- std::cout << " --> OK at " << ima(p) << std::endl;
- // ok (row, cur) at line middle
- }
- std::cout << std::endl;
-
- if (cur == last)
- return;
-
- std::cout << std::endl
- << "END : "
- << std::endl
- << std::endl;
-
- while (cur < last)
- {
- ++cur;
- ++minus;
- mln_invariant(minus >= start && minus <= last);
- std::cout << " untake " << ima(p_minus) << " ";
- std::cout << " --> OK at " << ima(p) << std::endl;
- }
- std::cout << std::endl;
-
- }
-
-*/
-
-
- template <typename I, typename A, typename O>
- void line_inc(unsigned dir,
- const I& input,
- const mln_site(I)& p_start, unsigned len,
- A a, unsigned half,
- O& output)
- {
- typedef mln_site(I) P;
- const unsigned start = p_start[dir];
- const unsigned last = start + len - 1;
-
- std::cout << std::endl
- << "START : "
- << std::endl
- << std::endl;
-
- P p = p_start;
- a.init();
-
- P q = p;
- for (unsigned c = 0; c <= half && c < len; ++c)
- {
- a.take(input(q));
- std::cout << " take " << debug::format(input(q)) << "
";
- ++q[dir];
- }
- std::cout << std::endl;
-
- std::cout << " --> OK at " << debug::format(input(p))
<< std::endl;
- output(p) = a;
-
- def::coord& cur = p[dir];
- if (cur == last)
- return;
-
- std::cout << std::endl
- << "BEGIN : "
- << std::endl
- << std::endl;
-
- P p_plus = p_start;
- def::coord& plus = p_plus[dir];
- plus += half;
-
- while (cur < start + half && cur < last)
- {
- ++cur;
- ++plus;
- if (plus <= last)
- {
- a.take(input(p_plus));
- std::cout << " take " << debug::format(input(p_plus)) <<
" ";
- }
- std::cout << " --> OK at " << debug::format(input(p)) <<
std::endl;
- output(p) = a;
- }
-
- if (cur == last)
- return;
-
- std::cout << std::endl
- << "MIDDLE : "
- << std::endl
- << std::endl;
-
- P p_minus = p_start;
- def::coord& minus = p_minus[dir];
- --minus;
-
- while (cur < last - half)
- {
- ++cur;
- ++plus;
- ++minus;
- mln_invariant(plus >= start && plus <= last);
- a.take(input(p_plus));
- std::cout << " take " << debug::format(input(p_plus)) <<
" ";
- mln_invariant(minus >= start && minus <= last);
- a.untake(input(p_minus));
- std::cout << " untake " << debug::format(input(p_minus)) <<
" ";
- std::cout << " --> OK at " << debug::format(input(p)) <<
std::endl;
- output(p) = a;
- // ok (row, cur) at line middle
- }
- std::cout << std::endl;
-
- if (cur == last)
- return;
-
- std::cout << std::endl
- << "END : "
- << std::endl
- << std::endl;
-
- while (cur < last)
- {
- ++cur;
- ++minus;
- mln_invariant(minus >= start && minus <= last);
- a.untake(input(p_minus));
- std::cout << " untake " << debug::format(input(p_minus)) <<
" ";
- std::cout << " --> OK at " << debug::format(input(p)) <<
std::endl;
- output(p) = a;
- }
- std::cout << std::endl;
-
- }
-
-
-
-} // mln
-
-
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<int_u8> I;
- I ima(12, 12);
- debug::iota(ima);
- debug::println(ima);
-
-
- I out(12, 12);
- point2d p_start(0, 0);
- line_inc(0, // dir
- ima, p_start, ima.ncols(),
- accu::min_h<int_u8>(), 4, // half
- out);
-
- debug::println(out);
-
-
-// typedef window2d W;
-// W win;
-// win.insert(dpoint2d(0,-1));
-// win.insert(dpoint2d(0, 0));
-// win.insert(dpoint2d(0, 1));
-
-// accu_win<I, accu::min, W> f(ima, win);
-// canvas::browsing::fwd(f);
-
-// canvas::browsing::row_fwd(f);
-
-// iota<I> f;
-// f.input = ima;
-// canvas::browsing::col_fwd(f);
-// debug::println(ima);
-
-}
Index: geraud/browsing/fwd.hh
--- geraud/browsing/fwd.hh (revision 3151)
+++ geraud/browsing/fwd.hh (working copy)
@@ -1,88 +0,0 @@
-
-
-namespace mln
-{
-
- namespace canvas
- {
-
- namespace browsing
- {
-
- template <typename F>
- void fwd(F& f)
- {
- trace::entering("canvas::browsing::fwd");
- mln_precondition(f.input.is_valid());
- typedef typename F::I I;
- mln_fwd_piter(I) p(f.input.domain());
- f.init();
- for_all(p)
- {
- f.p = p;
- f.next();
- }
- f.final();
- trace::exiting("canvas::browsing::fwd");
- }
-
-
- template <typename F>
- void row_fwd(F& f)
- {
- trace::entering("canvas::browsing::row_fwd");
- mln_precondition(f.input.is_valid());
- box2d b = f.input.domain();
- unsigned nrows = b.nrows(), ncols = b.ncols();
- def::coord& row = f.p.row();
- def::coord& col = f.p.col();
-
- f.init();
- for (row = 0; row < nrows; ++row)
- {
- col = 0;
- f.begin();
- while (col < ncols)
- {
- f.next();
- ++col;
- }
- f.end();
- }
- f.final();
- trace::exiting("canvas::browsing::row_fwd");
- }
-
-
- template <typename F>
- void col_fwd(F& f)
- {
- trace::entering("canvas::browsing::col_fwd");
- mln_precondition(f.input.is_valid());
- box2d b = f.input.domain();
- unsigned nrows = b.nrows(), ncols = b.ncols();
- def::coord& row = f.p.row();
- def::coord& col = f.p.col();
-
- f.init();
- for (col = 0; col < ncols; ++col)
- {
- row = 0;
- f.begin();
- while (row < nrows)
- {
- f.next();
- ++row;
- }
- f.end(); // FIXME: p invalid...
- }
- f.final();
- trace::exiting("canvas::browsing::col_fwd");
- }
-
-
- } // end of namespace mln::canvas::browsing
-
- } // end of namespace mln::canvas
-
-} // end of namespace mln
Index: geraud/cs2d/cs2d.cc
--- geraud/cs2d/cs2d.cc (revision 3151)
+++ geraud/cs2d/cs2d.cc (working copy)
@@ -1,110 +0,0 @@
-# include "cs2d.hh"
-# include "cs2d_morpho.hh"
-# include "dbl_neighb.hh"
-
-# include <mln/debug/println.hh>
-
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-
-# include <mln/morpho/dilation.hh>
-# include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/closing_area.hh>
-
-# include <mln/logical/not.hh>
-# include <mln/labeling/blobs.hh>
-# include <mln/accu/mean.hh>
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
lambda output.pgm" << std::endl;
- abort();
-}
-
-
-struct is_row_odd_t
-{
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2;
- }
-} is_row_odd;
-
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 4)
- usage(argv);
-
-
- using namespace mln;
- using value::int_u8;
-
- // trace::quiet = false;
-
- cmorpho::dbl_neighb2d nbh_e;
- nbh_e
- .insert_even(dpoint2d(-1,-1))
- .insert_even(dpoint2d(-1,+1))
- .insert_even(dpoint2d( 0,-2))
- .insert_odd(dpoint2d(-2, 0))
- .insert_odd(dpoint2d(-1,-1))
- .insert_odd(dpoint2d(-1,+1));
-
- // display_masks(make::box2d(2,3));
-
- image2d<int_u8> lena;
- io::pgm::load(lena, argv[1]);
-
- cs2d<int_u8, int_u8, int_u8> cs(lena.domain());
-
- fill_cells_with(cs, lena);
- data::fill(cs.vertex, 0);
-
- cmorpho::dbl_neighb2d nbh_g;
- nbh_g.insert_odd(up).insert_even(left);
- data::paste(cmorpho::gradient(cs.edge, nbh_g),
- cs.edge);
- // io::pgm::save(cs.impl, "grad.pgm");
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- if (lambda != 0)
- data::paste(morpho::closing_area(cs.edge, nbh_e, lambda), cs.edge);
-
- cs2d<int_u8, bool, bool> cs_(lena.domain());
- data::fill(cs_.impl, false);
- fill_cells_with(cs_, lena);
-
- unsigned l;
- data::fill(cs_.edge,
- pw::value(cmorpho::meyer_wst(cs.edge, nbh_e, l)) == pw::cst(0));
- std::cout << "l = " << l << std::endl;
-
- data::paste(morpho::dilation(cs_.vertex,
- convert::to_window(c4())),
- cs_.vertex);
-
- unsigned L;
- // debug::println(cs_.impl);
- image2d<unsigned> label = labeling::blobs(logical::not_(cs_.impl), c4(), L);
- // debug::println(label);
- mln_invariant(L == l);
-
- std::vector<int_u8> v(l + 1);
- accu::compute<accu::mean>(cs_.cell, label, v);
-
- data::fill(cs_.cell, level::transform(label, v));
- io::pgm::save(cell_image(cs_), argv[3]);
-
-// io::ppm::save(pack(cs_, colorize, 7), "log.ppm");
-}
Index: geraud/cs2d/tuto.cc
--- geraud/cs2d/tuto.cc (revision 3151)
+++ geraud/cs2d/tuto.cc (working copy)
@@ -1,145 +0,0 @@
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/core/alias/window2d.hh>
-# include <mln/convert/to_window.hh>
-
-# include <mln/debug/println.hh>
-# include <mln/fun/p2v/iota.hh>
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/morpho/dilation.hh>
-
-
-
- struct is_cell_t : mln::Function_p2b<is_cell_t>
- {
- typedef bool result;
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2 == 0 && p.col() % 2 == 0;
- }
- }
- is_cell;
-
- struct is_edge_t : mln::Function_p2b<is_edge_t>
- {
- typedef bool result;
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2 + p.col() % 2 == 1;
- }
- }
- is_edge;
-
- struct is_point_t : mln::Function_p2b<is_point_t>
- {
- typedef bool result;
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2 && p.col() % 2;
- }
- }
- is_point;
-
-
-
-int main()
-{
- using namespace mln;
-
- window2d c4 = convert::to_window(mln::c4());
-
- {
- image2d<char> ima(3, 5);
-
- data::fill(ima, 'o');
-
- debug::println(ima);
- // o o o o o
- // o o o o o
- // o o o o o
-
- debug::println(ima | is_cell);
- // o o o
- //
- // o o o
-
- data::fill((ima | is_cell).rw(), 'c');
- data::fill((ima | is_edge).rw(), 'e');
- data::fill((ima | is_point).rw(), 'p');
-
- debug::println(ima);
- // c e c e c
- // e p e p e
- // c e c e c
- }
-
- {
- image2d<int> ima(3, 5);
-
- data::fill(ima, 0);
- debug::println(ima);
- // 0 0 0 0 0
- // 0 0 0 0 0
- // 0 0 0 0 0
-
- data::fill((ima | is_cell).rw(), fun::p2v::iota);
- debug::println(ima | is_cell);
- // 1 2 3
- //
- // 4 5 6
-
- // --- for the record:
- // debug::println(morpho::dilation(ima, win::square(3)));
-
- debug::println(ima);
- // 1 0 2 0 3
- // 0 0 0 0 0
- // 4 0 5 0 6
-
- debug::println(ima | is_edge);
- // 0 0
- // 0 0 0
- // 0 0
-
- debug::println(morpho::dilation(ima | is_edge, c4));
- // 2 3
- // 4 5 6
- // 5 6
-
- // Attention : les traitements ne travaillent généralement pas en
- // place ; l'entrée n'est pas modifiée, une nouvelle image est
- // retournée. Dans le code ci-dessus, l'image dilatée est envoyée
- // à la routine d'affichage puis, n'étant plus utilisée, elle est
- // automatiquement désallouée.
-
- // On peut vérifier que 'ima' n'a pas été modifié :
-
- debug::println(ima);
- // 1 0 2 0 3
- // 0 0 0 0 0
- // 4 0 5 0 6
-
- // En revanche, rien n'empêche de "coller" le résultat d'un
- // traitement dans l'image d'entrée :
-
- data::paste(morpho::dilation(ima | is_edge, c4), ima);
-
- // Maintenant, le dilaté de "ima restreint à edge" est collé dans
- // 'ima' :
-
- debug::println(ima);
- // 1 2 2 3 3
- // 4 0 5 0 6
- // 4 5 5 6 6
-
- data::paste(morpho::dilation(ima | is_point, c4), ima);
- debug::println(ima);
- // 1 2 2 3 3
- // 4 5 5 6 6
- // 4 5 5 6 6
- }
-
-}
Index: geraud/cs2d/kruskal.cc
--- geraud/cs2d/kruskal.cc (revision 3151)
+++ geraud/cs2d/kruskal.cc (working copy)
@@ -1,357 +0,0 @@
-# include <vector>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/sub_image.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image_if_value.hh>
-
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/core/alias/window2d.hh>
-# include <mln/convert/to_window.hh>
-
-# include <mln/debug/println.hh>
-# include <mln/debug/iota.hh>
-# include <mln/fun/p2v/iota.hh>
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/morpho/gradient.hh>
-# include <mln/morpho/meyer_wst.hh>
-
-# include <mln/level/sort_points.hh>
-
-# include <mln/io/pgm/load.hh>
-# include <mln/io/ppm/save.hh>
-# include <mln/value/int_u8.hh>
-# include <mln/pw/all.hh>
-# include <mln/win/rectangle2d.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/literal/black.hh>
-# include <mln/literal/white.hh>
-# include <mln/literal/colors.hh>
-
-# include <mln/labeling/regional_minima.hh>
-
-# include "dbl_neighb.hh"
-
-
-
-// KRUSKAL-MST(G, w)
-// T := Ø
-// for each vertex u in V
-// MAKE-SET(DS, u)
-// end for
-// for each edge (u,v) in E in order of nondecreasing weight
-// if FIND-SET(DS, u) != FIND-SET(DS, v)
-// UNION-SET(DS, u, v)
-// T := T U {(u,v)}
-// end for
-// return T
-
-
-
-struct is_cell_t : mln::Function_p2b<is_cell_t>
-{
- typedef bool result;
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2 == 0 && p.col() % 2 == 0;
- }
-}
- is_cell;
-
-struct is_edge_t : mln::Function_p2b<is_edge_t>
-{
- typedef bool result;
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2 + p.col() % 2 == 1;
- }
-}
- is_edge;
-
-struct is_point_t : mln::Function_p2b<is_point_t>
-{
- typedef bool result;
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2 && p.col() % 2;
- }
-}
- is_point;
-
-
-struct is_row_odd_t
- {
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2;
- }
- } is_row_odd;
-
-
-template<typename T_t>
-struct is_tree_t : mln::Function_p2b< is_tree_t<T_t> >
-{
- typedef bool result;
- bool operator()(const mln::point2d& p) const
- {
- return p.row() % 2 + p.col() % 2 == 1 && T(p) == true;
- }
- T_t T;
-};
-
-namespace mln
-{
-
- template <typename E>
- image2d<value::rgb8> show_edge(const E& edge,
- unsigned nrows,unsigned ncols,
- unsigned clen)
- {
- mln_precondition(clen % 2); // oddity
-
- typedef win::hline2d H;
- H hline(clen);
-
- typedef win::vline2d V;
- V vline(clen);
-
- box2d b(nrows * clen + 3 * (nrows - 1),
- ncols * clen + 3 * (ncols - 1));
- image2d<value::rgb8> output(b);
- data::fill(output, literal::black);
-
-
- // 0 1 2 3 4
- // 0 c e c e c
- // 1 e x e x e
- // 2 c e c e c
-
- // 0 1 2 3 4 5 6 7 8 9 10
-
- // 0 c c c . e . c c c . e . c c c
- // 1 c c c . e . c c c . e . c c c
- // 2 c c c . e . c c c . e . c c c
- // 3 . . . . . . . . . . . . . . .
- // 4 e e e . x . e e e . x . e e e
- // 5 . . . . . . . . . . . . . . .
- // 6 c c c . e . c c c . e . c c c
- // 7 c c c . e . c c c . e . c c c
- // 8 c c c . e . c c c . e . c c c
-
- // Edges.
- mln_piter(E) e(edge.domain());
- for_all(e)
- {
- value::rgb8 v;
- if (edge(e))
- v = literal::red;
- else
- v = literal::black;
- point2d e_ = e, p_;
- if (e_.row() % 2) // Odd => horizontal.
- {
- p_.row() = clen + 1 + (clen + 3) * (e_.row() / 2); // vertex-like
- p_.col() = clen / 2 + (clen + 3) * (e_.col() / 2); // cell-like
- mln_qiter(V) q(hline, p_);
- for_all(q) if (output.has(q))
- output(q) = v;
- }
- else // Even => vertical.
- {
- p_.row() = clen / 2 + (clen + 3) * (e_.row() / 2); // cell-like
- p_.col() = clen + 1 + (clen + 3) * (e_.col() / 2); // vertex-like
- mln_qiter(H) q(vline, p_);
- for_all(q) if (output.has(q))
- output(q) = v;
- }
- }
-
- return output;
- }
-
-} // mln
-
-
-#define mln_VAR(Var, Expr) typeof(Expr) Var = Expr;
-
-
-template <typename DS_t, typename U>
-void make_set(DS_t& DS, const U& u)
-{
- DS(u) = u;
-}
-
-
-template <typename DS_t, typename U>
-U find_set(DS_t& DS, U u)
-{
- if (DS(u) == u) // is root
- return u;
- return DS(u) = find_set(DS, DS(u));
-}
-
-
-template <typename DS_t, typename U>
-void union_set(DS_t& DS, const U& u, const U& v)
-{
- U ru = find_set(DS, u),
- rv = find_set(DS, v);
- mln_precondition(ru != rv);
- if (rv > ru)
- DS(ru) = rv;
- else
- DS(rv) = ru;
-}
-
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- window2d c4 = convert::to_window(mln::c4());
-
-
- typedef dbl_neighb_<dpoint2d, is_row_odd_t> nbh_t;
- nbh_t nbh_e2c, win_p_e2c, nbh_e2e;
-
- {
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
-
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
- nbh_e2c
- .when_true (make::neighb2d(e2c_h))
- .when_false(make::neighb2d(e2c_v));
-
- win_p_e2c = nbh_e2c;
- win_p_e2c
- .insert_true(dpoint2d(0,0))
- .insert_false(dpoint2d(0,0));
-
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
-
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- nbh_e2e
- .when_true (make::neighb2d(e2e_h))
- .when_false(make::neighb2d(e2e_v));
- }
-
- typedef image2d<int_u8> I;
-
- image2d<int_u8> input;
- io::pgm::load(input, "fly.pgm");
-
- image2d<int_u8> ima(input.nrows() * 2 - 1,
- input.ncols() * 2 - 1, 0);
-
- mln_VAR(cell, ima | is_cell);
- typedef typeof(cell) cell_t;
- debug::println(cell);
-
- {
- mln_fwd_piter_(I) pi(input.domain());
- mln_fwd_piter_(cell_t) pc(cell.domain());
- for_all_2(pi, pc)
- cell(pc) = input(pi);
- }
-
- mln_VAR(edge, ima | is_edge);
- data::paste(morpho::gradient(edge, nbh_e2c), edge);
- // ^^^^^^^
- // edge -> neighboring cells
-
- debug::println(edge);
-
- typedef typeof(edge) edge_t;
-
- typedef p_array<point2d> Arr;
- Arr E = level::sort_points_increasing(edge);
-
- // Aux data.
- mln_ch_value_(edge_t, bool) T;
- initialize(T, edge);
- data::fill(T, false);
-
- mln_ch_value_(cell_t, point2d) DS;
- initialize(DS, cell);
-
- {
- mln_piter_(cell_t) u(cell.domain());
- for_all(u) // in V
- make_set(DS, u);
- }
-
- {
- mln_fwd_piter_(Arr) uv(E);
- for_all(uv)
- {
- point2d
- uv_ = uv.to_point(),
- u, v;
- if (uv_.row() % 2)
- u = uv_ + up, v = uv_ + down;
- else
- u = uv_ + left, v = uv_ + right;
- if (find_set(DS, u) != find_set(DS, v))
- {
- union_set(DS, u, v);
- T(uv) = true;
- }
- }
- }
-
- debug::println(T);
-
- mln_VAR(is_T, pw::value(T) == pw::cst(true));
-
- mln_VAR(dom, (T | is_T).domain());
- typedef typeof(dom) dom_t;
-
- io::ppm::save(show_edge(T, input.nrows(), input.ncols(), 7),
- "edge.ppm");
-
-
- typedef typeof(T) T_t;
- is_tree_t<T_t> is_tree;
- is_tree.T = T;
- // [*] See EOF.
-
- unsigned nbasins;
- mln_VAR(wst, morpho::meyer_wst(ima | is_tree, nbh_e2e, nbasins) );
- std::cout << "nbasins : " << nbasins << std::endl;
-
- {
- mln_piter_(dom_t) e(dom);
- mln_niter_(nbh_t) n(nbh_e2c, e);
- for_all(e)
- if (wst(e) != 0)
- for_all(n)
- cell(n) = wst(e);
- debug::println(cell);
- }
-
-}
-
-// [*] FIXME: "edge | is_T" does not properly work because of
-// initialization failure of the predicate function (pw expr do not
-// have ctor without arg so the init cannot be delayed). As a
-// consequence, we cannot have the following code:
-//
-// mln_VAR(tree, edge | is_T);
-// typedef typeof(tree) tree_t;
-// morpho::meyer_wst(tree, nbh_e2e, nbasins);
Index: geraud/cs2d/cs2d_utils.hh
--- geraud/cs2d/cs2d_utils.hh (revision 3151)
+++ geraud/cs2d/cs2d_utils.hh (working copy)
@@ -1,251 +0,0 @@
-# include <mln/value/rgb8.hh>
-# include <mln/value/int_u8.hh>
-# include <mln/literal/black.hh>
-# include <mln/literal/white.hh>
-# include <mln/literal/colors.hh>
-# include <mln/win/rectangle2d.hh>
-# include <mln/data/fill.hh>
-
-
-namespace mln
-{
-
- // 0 1 2
- // 0 c c c
- // 1 c c c
-
- // 0 1 2 3 4
- // 0 c e c e c
- // 1 e x e x e
- // 2 c e c e c
-
-
- struct is_cell_t : Function_p2b<is_cell_t>
- {
- typedef bool result;
- bool operator()(const point2d& p) const
- {
- return p.row() % 2 == 0 && p.col() % 2 == 0;
- }
- }
- is_cell;
-
-
- struct is_edge_t : Function_p2b<is_edge_t>
- {
- typedef bool result;
- bool operator()(const point2d& p) const
- {
- return p.row() % 2 + p.col() % 2 == 1;
- }
- }
- is_edge;
-
-
- struct is_vertex_t : Function_p2b<is_vertex_t>
- {
- typedef bool result;
- bool operator()(const point2d& p) const
- {
- return p.row() % 2 && p.col() % 2;
- }
- }
- is_vertex;
-
-
-
- void display_masks(box2d b)
- {
- box2d b_(2 * b.nrows() - 1, 2 * b.ncols() - 1);
- image2d<char> tmp(b_);
- mln_piter_(box2d) p(b_);
- for_all(p)
- if (is_cell(p))
- {
- mln_invariant(! is_edge(p) && ! is_vertex(p));
- tmp(p) = 'O';
- }
- else if (is_edge(p))
- {
- mln_invariant(! is_cell(p) && ! is_vertex(p));
- tmp(p) = p.to_point().row() % 2 ? '-' : '|';
- }
- else if (is_vertex(p))
- {
- mln_invariant(! is_edge(p) && ! is_cell(p));
- tmp(p) = '+';
- }
- else
- mln_invariant(0);
- debug::println(tmp);
- }
-
-
- struct colorize_t
- {
- typedef value::rgb8 result;
- result operator()(value::int_u8 i) const
- {
- return result(i,i,i);
- }
- result operator()(bool b) const
- {
- if (b)
- return literal::red;
- else
- return literal::black;
- }
- }
- colorize;
-
-
- template <typename Cs, typename F>
- image2d<mln_result(F)> pack(const Cs& cs, F f)
- {
- image2d<mln_result(F)> output(cs.b);
- mln_piter(box2d) p(cs.b);
- for_all(p)
- if (is_cell(p))
- output(p) = f(cs.cell(p));
- else if (is_edge(p))
- output(p) = f(cs.edge(p));
- else
- output(p) = f(cs.vertex(p));
- return output;
- }
-
-
- template <typename Cs, typename F>
- image2d<mln_result(F)> pack(const Cs& cs, F f, unsigned clen)
- {
- typedef mln_result(F) R;
-
- mln_precondition(clen % 2); // oddity
-
- typedef win::rectangle2d Sqr;
- Sqr sqr(clen, clen);
-
- typedef win::hline2d H;
- H hline(clen);
-
- typedef win::vline2d V;
- V vline(clen);
-
- // 0 1 2 3 4
- // 0 c e c e c
- // 1 e x e x e
- // 2 c e c e c
-
- // 0 1 2 3 4 5 6 7 8 9 10
-
- // 0 c c c . e . c c c . e . c c c
- // 1 c c c . e . c c c . e . c c c
- // 2 c c c . e . c c c . e . c c c
- // 3 . . . . . . . . . . . . . . .
- // 4 e e e . x . e e e . x . e e e
- // 5 . . . . . . . . . . . . . . .
- // 6 c c c . e . c c c . e . c c c
- // 7 c c c . e . c c c . e . c c c
- // 8 c c c . e . c c c . e . c c c
-
- box2d b(cs.nrows() * clen + 3 * (cs.nrows() - 1),
- cs.ncols() * clen + 3 * (cs.ncols() - 1));
- image2d<R> output(b);
- data::fill(output, literal::black);
-
- // Cells.
- mln_piter(Cs::cell_t) c(cs.cell.domain());
- for_all(c)
- {
- R v = f(cs.cell(c));
- point2d c_ = c.to_point(), p_;
- p_.row() = clen / 2 + (clen + 3) * (c_.row() / 2);
- p_.col() = clen / 2 + (clen + 3) * (c_.col() / 2);
- mln_qiter(Sqr) q(sqr, p_);
- for_all(q)
- output(q) = v;
- }
-
- // Points.
- mln_piter(Cs::vertex_t) x(cs.vertex.domain());
- for_all(x)
- {
- point2d x_ = x, q;
- q.row() = clen + 1 + (clen + 3) * (x_.row() / 2);
- q.col() = clen + 1 + (clen + 3) * (x_.col() / 2);
- output(q) = f(cs.vertex(x));
- }
-
-
- // 0 1 2 3 4
- // 0 c e c e c
- // 1 e x e x e
- // 2 c e c e c
-
- // 0 1 2 3 4 5 6 7 8 9 10
-
- // 0 c c c . e . c c c . e . c c c
- // 1 c c c . e . c c c . e . c c c
- // 2 c c c . e . c c c . e . c c c
- // 3 . . . . . . . . . . . . . . .
- // 4 e e e . x . e e e . x . e e e
- // 5 . . . . . . . . . . . . . . .
- // 6 c c c . e . c c c . e . c c c
- // 7 c c c . e . c c c . e . c c c
- // 8 c c c . e . c c c . e . c c c
-
-
- // Edges.
- mln_piter(Cs::edge_t) e(cs.edge.domain());
- for_all(e)
- {
- R v = f(cs.edge(e));
- point2d e_ = e, p_;
- if (e_.row() % 2) // Odd => horizontal.
- {
- p_.row() = clen + 1 + (clen + 3) * (e_.row() / 2); // vertex-like
- p_.col() = clen / 2 + (clen + 3) * (e_.col() / 2); // cell-like
- mln_qiter(V) q(hline, p_);
- for_all(q) if (output.has(q))
- output(q) = v;
- }
- else // Even => vertical.
- {
- p_.row() = clen / 2 + (clen + 3) * (e_.row() / 2); // cell-like
- p_.col() = clen + 1 + (clen + 3) * (e_.col() / 2); // vertex-like
- mln_qiter(H) q(vline, p_);
- for_all(q) if (output.has(q))
- output(q) = v;
- }
- }
-
- return output;
- }
-
-
-
- template <typename Cs, typename T>
- void fill_cells_with(Cs& cs, const image2d<T>& input)
- {
- mlc_equal(T, typename Cs::cell_value)::check();
- mln_piter(box2d) p(input.domain());
- mln_piter(Cs::cell_t) c(cs.cell.domain());
- for_all_2(p, c)
- cs.cell(c) = input(p);
- }
-
- template <typename Cs>
- image2d<typename Cs::cell_value>
- cell_image(const Cs& cs)
- {
- image2d<typename Cs::cell_value> output(cs.nrows(), cs.ncols());
- mln_piter(box2d) p(output.domain());
- mln_piter(Cs::cell_t) c(cs.cell.domain());
- for_all_2(p, c)
- output(p) = cs.cell(c);
- return output;
- }
-
-} // mln
-
-
Index: geraud/cs2d/cs2d.hh
--- geraud/cs2d/cs2d.hh (revision 3151)
+++ geraud/cs2d/cs2d.hh (working copy)
@@ -1,172 +0,0 @@
-# include <mln/core/image/image2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/core/alias/window2d.hh>
-# include <mln/convert/to_window.hh>
-
-# include <mln/core/image/image_if.hh>
-# include <mln/debug/println.hh>
-
-
-# include "cs2d_utils.hh"
-
-
-namespace mln
-{
-
-
- template <typename C, typename E, typename X>
- struct cs2d
- {
- typedef C cell_value;
- typedef E edge_value;
- typedef X vertex_value;
-
- cs2d(unsigned nrows, unsigned ncols)
- {
- init(nrows, ncols);
- }
-
- cs2d(const box2d& b)
- {
- init(b.nrows(), b.ncols());
- }
-
- void init(unsigned nrows, unsigned ncols)
- {
- mln_precondition(nrows && ncols);
-
- // Raw data (impl).
- b = make::box2d(2 * nrows - 1, 2 * ncols - 1);
- cimpl = image2d<C>(b, 0);
- eimpl = image2d<E>(b, 0);
- ximpl = image2d<X>(b, 0);
-
- // Images.
- cell = cimpl | is_cell;
- edge = eimpl | is_edge;
- vertex = ximpl | is_vertex;
- }
-
- unsigned nrows() const { return (b.nrows() + 1) / 2; }
- unsigned ncols() const { return (b.ncols() + 1) / 2; }
-
- box2d b;
- image2d<C> cimpl;
- image2d<E> eimpl;
- image2d<X> ximpl;
-
- typedef image_if< image2d<C>, is_cell_t > cell_t;
- cell_t cell;
-
- typedef image_if< image2d<E>, is_edge_t > edge_t;
- edge_t edge;
-
- typedef image_if< image2d<X>, is_vertex_t > vertex_t;
- vertex_t vertex;
- };
-
-
-
-
- template <typename T>
- struct cs2d< T, T, T>
- {
- typedef T cell_value;
- typedef T edge_value;
- typedef T vertex_value;
-
- cs2d(unsigned nrows, unsigned ncols)
- {
- init(nrows, ncols);
- }
-
- cs2d(const box2d& b)
- {
- init(b.nrows(), b.ncols());
- }
-
- void init(unsigned nrows, unsigned ncols)
- {
- mln_precondition(nrows && ncols);
-
- // Raw data (impl).
- b = make::box2d(2 * nrows - 1, 2 * ncols - 1);
- impl = image2d<T>(b, 0);
-
- // Images.
- cell = impl | is_cell;
- edge = impl | is_edge;
- vertex = impl | is_vertex;
- }
-
- unsigned nrows() const { return (b.nrows() + 1) / 2; }
- unsigned ncols() const { return (b.ncols() + 1) / 2; }
-
- box2d b;
- image2d<T> impl;
-
- typedef image_if< image2d<T>, is_cell_t > cell_t;
- cell_t cell;
-
- typedef image_if< image2d<T>, is_edge_t > edge_t;
- edge_t edge;
-
- typedef image_if< image2d<T>, is_vertex_t > vertex_t;
- vertex_t vertex;
- };
-
-
-
-
-
- template <typename C, typename T>
- struct cs2d< C, T, T>
- {
- typedef C cell_value;
- typedef T edge_value;
- typedef T vertex_value;
-
- cs2d(unsigned nrows, unsigned ncols)
- {
- init(nrows, ncols);
- }
-
- cs2d(const box2d& b)
- {
- init(b.nrows(), b.ncols());
- }
-
- void init(unsigned nrows, unsigned ncols)
- {
- mln_precondition(nrows && ncols);
-
- // Raw data (impl).
- b = make::box2d(2 * nrows - 1, 2 * ncols - 1);
- cimpl = image2d<C>(b, 0);
- impl = image2d<T>(b, 0);
-
- // Images.
- cell = cimpl | is_cell;
- edge = impl | is_edge;
- vertex = impl | is_vertex;
- }
-
- unsigned nrows() const { return (b.nrows() + 1) / 2; }
- unsigned ncols() const { return (b.ncols() + 1) / 2; }
-
- box2d b;
- image2d<C> cimpl;
- image2d<T> impl;
-
- typedef image_if< image2d<C>, is_cell_t > cell_t;
- cell_t cell;
-
- typedef image_if< image2d<T>, is_edge_t > edge_t;
- edge_t edge;
-
- typedef image_if< image2d<T>, is_vertex_t > vertex_t;
- vertex_t vertex;
- };
-
-
-} // mln
Index: geraud/cs2d/dbl_neighb.hh
--- geraud/cs2d/dbl_neighb.hh (revision 3151)
+++ geraud/cs2d/dbl_neighb.hh (working copy)
@@ -1,167 +0,0 @@
-# include <mln/core/concept/neighborhood.hh>
-
-
-namespace mln
-{
-
-
- // Fwd decl.
- template <typename D, typename F> class dbl_niter_;
-
-
- template <typename D, typename F>
- struct dbl_neighb_ : public Neighborhood< dbl_neighb_<D,F> >
- {
- typedef D dpoint;
- typedef mln_point(D) point;
-
- typedef dbl_niter_<D,F> fwd_niter;
- typedef dbl_niter_<D,F> bkd_niter;
- typedef dbl_niter_<D,F> niter;
-
- dbl_neighb_(F f)
- : f(f)
- {
- }
-
- dbl_neighb_()
- : f()
- {
- }
-
- bool is_empty() const
- {
- return trues.size() == 0 && falses.size() == 0;
- }
-
- dbl_neighb_& insert_true(const D& dp)
- {
- trues.push_back(dp);
- trues.push_back(-dp);
- return *this;
- }
-
- dbl_neighb_& insert_false(const D& dp)
- {
- falses.push_back(dp);
- falses.push_back(-dp);
- return *this;
- }
-
- template <typename N>
- dbl_neighb_& when_true(const Neighborhood<N>& nbh_)
- {
- const N& nbh = exact(nbh_);
- for (unsigned i = 0; i < nbh.size(); ++i)
- trues.push_back(nbh.dp(i));
- return *this;
- }
-
- template <typename N>
- dbl_neighb_& when_false(const Neighborhood<N>& nbh_)
- {
- const N& nbh = exact(nbh_);
- for (unsigned i = 0; i < nbh.size(); ++i)
- falses.push_back(nbh.dp(i));
- return *this;
- }
-
- std::vector<D> trues, falses;
- F f;
- };
-
-
-
- template <typename D, typename F>
- class dbl_niter_
- : public internal::point_iterator_base_< mln_point(D), dbl_niter_<D,F> >
- {
- public:
-
- typedef mln_point(D) point;
-
- template <typename Pref>
- dbl_niter_(const Neighborhood< dbl_neighb_<D,F> >& nbh,
- const Point_Site<Pref>& p_ref) :
- dps_true(exact(nbh).trues),
- dps_false(exact(nbh).falses),
- p_ref_(exact(p_ref).to_point()),
- f(exact(nbh).f)
- {
- invalidate();
- }
-
- /// Conversion to point.
- operator point () const
- {
- mln_precondition(is_valid());
- return p_;
- }
-
- /// Reference to the corresponding point.
- const point& to_point() const
- {
- return p_;
- }
-
- /// Test the iterator validity.
- bool is_valid() const
- {
- return i_ != dps_true.size();
- }
-
- /// Invalidate the iterator.
- void invalidate()
- {
- i_ = dps_true.size();
- }
-
- /// Start an iteration.
- void start()
- {
- i_ = 0;
- update();
- }
-
- /// Go to the next point.
- void next_()
- {
- ++i_;
- update();
- }
-
- /// Give the i-th coordinate.
- int operator[](unsigned i) const
- {
- mln_precondition(is_valid());
- return p_[i];
- }
-
- /// The point around which this iterator moves.
- const point& center_point() const
- {
- return p_ref_;
- }
-
- /// Force this iterator to update its location to take into
- /// account that its center point may have moved.
- void update()
- {
- if (is_valid())
- p_ = p_ref_ + (f(p_ref_) ? dps_true[i_] : dps_false[i_]);
- }
-
- protected:
-
- const std::vector<D>& dps_true, dps_false;
- const point& p_ref_; // reference point (or "center point")
- F f;
-
- unsigned i_;
- point p_; // location of this iterator; p_ makes this iterator be
- // itself a potential center point.
- };
-
-
-
-} // mln
Index: geraud/cs2d/cs2d_morpho.hh
--- geraud/cs2d/cs2d_morpho.hh (revision 3151)
+++ geraud/cs2d/cs2d_morpho.hh (working copy)
@@ -1,372 +0,0 @@
-# include <mln/accu/max.hh>
-# include <mln/accu/min_max.hh>
-# include <mln/labeling/regional_minima.hh>
-
-# include <mln/core/site_set/p_queue_fast.hh>
-
-
-namespace mln
-{
-
- namespace cmorpho
- {
-
- template <typename T>
- T abs_diff(T t1, T t2)
- {
- return t1 > t2 ? t1 - t2 : t2 - t1;
- }
-
- template <typename I>
- void gradient(I& input)
- {
- mln_piter(I) p(input.domain());
- for_all(p)
- {
- mln_psite(I) p_ = p;
- input(p) =
- p_.row() % 2 ?
- // Odd so horizontal edge and vertical cells.
- abs_diff(input(p_ + left), input(p_ + right)) :
- // Otherwise
- abs_diff(input(p_ + up), input(p_ + down));
- }
- }
-
-
- template <typename I, typename N>
- inline
- mln_concrete(I) gradient(const Image<I>& input_,
- const Neighborhood<N>& nbh_)
- {
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
-
- mln_concrete(I) output;
- initialize(output, input);
-
- accu::min_max<mln_value(I)> m;
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- m.init();
- for_all(n) if (input.has(n))
- m.take(input(n));
- output(p) = m.second() - m.first();
- }
- return output;
- }
-
-
- class dbl_niter;
-
- struct dbl_neighb2d : public Neighborhood< dbl_neighb2d >
- {
- typedef dpoint2d dpoint;
- typedef point2d point;
-
- typedef dbl_niter fwd_niter;
- typedef dbl_niter bkd_niter;
- typedef dbl_niter niter;
-
- dbl_neighb2d()
- {
- }
-
- dbl_neighb2d& insert_odd(const dpoint2d& dp)
- {
- odds.push_back(dp);
- odds.push_back(-dp);
- return *this;
- }
- dbl_neighb2d& insert_even(const dpoint2d& dp)
- {
- evens.push_back(dp);
- evens.push_back(-dp);
- return *this;
- }
-
- std::vector<dpoint2d> odds, evens;
- };
-
-
- class dbl_niter
- : public internal::point_iterator_base_< point2d, dbl_niter >
- {
- public:
-
- typedef dpoint2d D;
-
- template <typename N, typename Pref>
- dbl_niter(const N& nbh, const Point_Site<Pref>& p_ref) :
- dps_odd(exact(nbh).odds),
- dps_even(exact(nbh).evens),
- p_ref_(exact(p_ref).to_point())
- {
-
- invalidate();
- }
-
- /// Conversion to point.
- operator point2d () const
- {
- mln_precondition(is_valid());
- return p_;
- }
-
- /// Reference to the corresponding point.
- const point2d& to_point() const
- {
- return p_;
- }
-
- /// Test the iterator validity.
- bool is_valid() const
- {
- return i_ != dps_odd.size();
- }
-
- /// Invalidate the iterator.
- void invalidate()
- {
- i_ = dps_odd.size();
- }
-
- /// Start an iteration.
- void start()
- {
- i_ = 0;
- update();
- }
-
- /// Go to the next point.
- void next_()
- {
- ++i_;
- update();
- }
-
- /// Give the i-th coordinate.
- int operator[](unsigned i) const
- {
- mln_precondition(is_valid());
- return p_[i];
- }
-
- /// The point around which this iterator moves.
- const point2d& center_point() const
- {
- return p_ref_;
- }
-
- /// Force this iterator to update its location to take into
- /// account that its center point may have moved.
- void update()
- {
- if (is_valid())
- p_ = p_ref_ + (p_ref_.row() % 2 ? dps_odd[i_] : dps_even[i_]);
- }
-
- protected:
-
- const std::vector<dpoint2d>& dps_odd, dps_even;
- const point2d& p_ref_; // reference point (or "center point")
-
- unsigned i_;
- point2d p_; // location of this iterator; p_ makes this iterator be
- // itself a potential center point.
- };
-
-
- template <typename L, typename I, typename N>
- mln_ch_value(I, L)
- meyer_wst(const Image<I>& input_, const Neighborhood<N>& nbh_,
- L& nbasins)
- {
- trace::entering("morpho::meyer_wst");
-
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
-
- /* FIXME: Ensure the input image has scalar values. */
-
- const L unmarked = 0;
-
- // Initialize the output with the markers (minima components).
- mln_ch_value(I, L) output;
- output = labeling::regional_minima(input, nbh, nbasins);
-
- // Ordered queue.
- std::vector< p_queue_fast<mln_psite(I)> > qu(256);
- unsigned qu_size = 0;
-
- // Insert every neighbor P of every marked area in a
- // hierarchical queue, with a priority level corresponding to
- // the grey level input(P).
- {
- mln_piter(I) p(output.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- if (output(p) == unmarked)
- for_all(n)
- if (output.has(n) && output(n) != unmarked)
- {
- qu[input(p)].push_force(p);
- ++qu_size;
- break;
- }
- }
-
- /* Until the queue is empty, extract a psite p from the
- hierarchical queue, at the highest priority level, that is,
- the lowest level. */
- mln_psite(I) p;
- mln_niter(N) n(nbh, p);
-
- while (qu_size != 0)
- {
-
- for (unsigned l = 0; l < 256; ++l)
- if (! qu[l].is_empty())
- {
- p = qu[l].pop_front();
- // qu[l].pop();
- break;
- }
- --qu_size;
-
- // Last seen marker adjacent to P.
- L adjacent_marker = unmarked;
- // Has P a single adjacent marker?
- bool single_adjacent_marker_p = true;
- for_all(n)
- if (output.has(n) && output(n) != unmarked)
- {
- if (adjacent_marker == unmarked)
- {
- adjacent_marker = output(n);
- single_adjacent_marker_p = true;
- }
- else
- if (adjacent_marker != output(n))
- {
- single_adjacent_marker_p = false;
- break;
- }
- }
-
- /* If the neighborhood of P contains only psites with the
- same label, then P is marked with this label, and its
- neighbors that are not yet marked are put into the
- hierarchical queue. */
- if (single_adjacent_marker_p)
- {
- output(p) = adjacent_marker;
- for_all(n)
- if (output.has(n) && output(n) == unmarked)
- {
- qu[input(n)].push_force(n);
- ++qu_size;
- }
- }
- }
-
- trace::exiting("morpho::meyer_wst");
- return output;
- }
-
- } // mln::cmorpho
-
-
- namespace accu
- {
-
- template <typename A_, typename I, typename L>
- inline
- std::vector<mln_accu_with(A_, mln_value(I))::result>
- compute(const Image<I>& input_,
- const Image<L>& label_,
- mln_value(L) n)
- {
- mlc_is_a(A_, Meta_Accumulator)::check();
-
- trace::entering("accu::compute");
-
- const I& input = exact(input_);
- const L& label = exact(label_);
-
- typedef mln_accu_with(A_, mln_value(I)) A;
- std::vector<A> a(n + 1);
-
- mln_piter(I) p(input.domain());
- for_all(p)
- a[label(p)].take(input(p));
-
- typedef typename A::result R;
- std::vector<R> v(n + 1);
- for (unsigned l = 1; l <= n; ++l)
- v[l] = a[l].to_result();
-
- trace::exiting("accu::compute");
- return v;
- }
-
-
- template <typename A_, typename I, typename L, typename R>
- inline
- void
- compute(const Image<I>& input_,
- const Image<L>& label_,
- std::vector<R>& v)
- {
- mlc_is_a(A_, Meta_Accumulator)::check();
-
- trace::entering("accu::compute");
-
- const I& input = exact(input_);
- const L& label = exact(label_);
-
- typedef mln_accu_with(A_, mln_value(I)) A;
- const unsigned n = v.size();
- std::vector<A> a(n);
-
- mln_piter(I) p(input.domain());
- for_all(p)
- a[label(p)].take(input(p));
-
- for (unsigned l = 1; l < n; ++l)
- v[l] = a[l].to_result();
-
- trace::exiting("accu::compute");
- }
-
- } // mln::accu
-
-
- namespace level
- {
-
- template<typename I, typename R>
- mln_ch_value(I, R)
- transform(const Image<I>& input_, const std::vector<R>& v)
- {
- trace::entering("level::transform");
- const I& input = exact(input_);
-
- mln_ch_value(I, R) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- for_all(p)
- output(p) = v[input(p)];
-
- trace::exiting("level::transform");
- return output;
- }
-
- } // mln::level
-
-
-} // mln
Index: geraud/dead/inplace.hh
--- geraud/dead/inplace.hh (revision 3151)
+++ geraud/dead/inplace.hh (working copy)
@@ -1,66 +0,0 @@
-// 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_CORE_IMAGE_INPLACE_HH
-# define MLN_CORE_IMAGE_INPLACE_HH
-
-/*! \file mln/core/image/inplace.hh
- *
- * \brief Definition of routine that make temporary objects become
- * mutable.
- */
-
-# include <mln/core/routine/exact.hh>
-
-
-namespace mln
-{
-
- /*! \brief Routine to make temporary objects become mutable.
- *
- * \warning This routine is not safe! FIXME: Explain.
- */
- template <typename E>
- E& inplace(const Object<E>& temp);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename E>
- inline
- E& inplace(const Object<E>& temp)
- {
- return const_cast<E&>( exact(temp) );
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of namespace mln
-
-
-#endif // ! MLN_CORE_IMAGE_INPLACE_HH
Index: geraud/dead/instant.hh
--- geraud/dead/instant.hh (revision 3151)
+++ geraud/dead/instant.hh (working copy)
@@ -1,168 +0,0 @@
-// Copyright (C) 2008 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_CORE_IMAGE_INSTANT_HH
-# define MLN_CORE_IMAGE_INSTANT_HH
-
-/*! \file mln/core/image/instant.hh
- *
- * \brief Definition of a morpher that prevent an image from sharing
- * his data.
- *
- * \todo Fix FIXME; see todo in image_identity...
- */
-
-# include <mln/core/internal/image_identity.hh>
-# include <mln/metal/is_not_const.hh>
-
-
-
-namespace mln
-{
-
- // Forward declaration.
- template <typename I> struct instant_;
-
-
- namespace trait
- {
-
- template <typename I>
- struct image_< instant_<I> > : image_< I > // Same as I except...
- {
- // ...this change.
- typedef trait::image::category::identity_morpher category;
- };
-
- } // end of namespace mln::trait
-
-
-
- namespace internal
- {
-
- /// Data structure for \c mln::instant_<I>.
- template <typename I>
- struct data< instant_<I> >
- {
- data(const I& ima);
- I ima_;
- };
-
- } // end of namespace mln::internal
-
-
-
-
-
- /*! \brief FIXME
- *
- */
- template <typename I>
- struct instant_
-
- : public mln::internal::image_identity< I, mln_pset(I), instant_<I> >,
- private mlc_is_not_const(I)::check_t
- {
-
- /// Skeleton.
- typedef tag::image_<I> skeleton; // Remove the "instant" envelope.
-
- /// Constructor.
- instant_(I& ima);
-
- /// Deferred initialization.
- void init_(I& ima);
-
- /// Remove the "instant" envelope.
- I& un_instant_();
- I& un_instant_() const;
- };
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- namespace internal
- {
-
- // internal::data< instant_<I> >
-
- template <typename I>
- inline
- data< instant_<I> >::data(const I& ima)
- : ima_(ima)
- {
- }
-
- } // end of namespace mln::internal
-
-
- // instant_<I>
-
- template <typename I>
- inline
- instant_<I>::instant_(I& ima)
- {
- mln_precondition(ima.is_valid());
- this->init_(ima);
- this->data_ = new internal::data< instant_<I> >(ima);
- }
-
- template <typename I>
- inline
- void
- instant_<I>::init_(I& ima)
- {
- mln_precondition(ima.is_valid());
- this->data_ = new internal::data< instant_<I> >(ima);
- }
-
- template <typename I>
- inline
- I&
- instant_<I>::un_instant_()
- {
- mln_precondition(this->is_valid());
- return this->data_->ima_;
- }
-
- template <typename I>
- inline
- I&
- instant_<I>::un_instant_() const
- {
- mln_precondition(this->is_valid());
- return const_cast<I&>(this->data_->ima_);
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of namespace mln
-
-
-#endif // ! MLN_CORE_IMAGE_INSTANT_HH
Index: geraud/fllt/fllt.hh
--- geraud/fllt/fllt.hh (revision 3151)
+++ geraud/fllt/fllt.hh (working copy)
@@ -1,1017 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <iomanip>
-#include <set>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-#include <mln/core/site_set/p_queue_fast.hh>
-#include <mln/core/image/cast_image.hh>
-#include <mln/opt/at.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/data/paste.hh>
-#include <mln/level/stretch.hh>
-#include <mln/level/compare.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/labeling/regional_maxima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/util/tree.hh>
-#include <mln/util/branch_iter_ind.hh>
-#include <mln/util/branch_iter.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
-# define fllt_tree(P, V) mln::util::tree< fllt_node_elt<P, V> >
-# define fllt_node(P, V) mln::util::tree_node< fllt_node_elt<P, V> >
-# define fllt_tree_ptr(P, V) mln::util::tree< fllt_node_elt<P, V>* >
-# define fllt_node_ptr(P, V) mln::util::tree_node< fllt_node_elt<P, V>* >
-# define fllt_branch(P, V) mln::util::branch< fllt_node_elt<P, V> >
-# define fllt_branch_iter_ind(P, V) mln::util::branch_iter_ind< fllt_node_elt<P,
V> >
-# define fllt_branch_iter(P, V) mln::util::branch_iter< fllt_node_elt<P, V>
>
-
-# define stl_to_mln_iter(T) stl_iterator< T >
-
- //Fwd declarations.
- template <typename V> struct lower;
- template <typename V> struct upper;
-
- template <typename P, typename V>
- struct fllt_node_elt
- {
- V value;
- p_array<P> points;
- p_array<P> holes;
- std::vector<fllt_node(P, V)*> hole_shapes;
- /// Tell if his parent if brighter or not. Nb : if the parent
- /// if brighter, the node come from the lower level set
- bool brighter;
- unsigned nsites;
- bool tagged;
- bool set_id;
- std::vector<p_array<P>*> N;
- fllt_node(P, V)* root;
- unsigned root_version;
- unsigned deja_vu;
-
- fllt_node_elt(bool set_id) : nsites(0),
- tagged(false),
- set_id(set_id),
- root(0) {}
- };
-
-
- template <typename C>
- class stl_iterator
- {
- public:
- stl_iterator(C& c) : container_(c) {}
- void start(){ it_ = container_.begin(); }
- void next() { it_++; }
- bool is_valid() const{ return it_ != container_.end(); }
- typename C::value_type& operator*() { return *it_; }
-
- private:
- C& container_;
- typename C::iterator it_;
- };
-
- template <typename N_t, typename G, typename Set>
- void update_gN(const N_t& N, G& gN);
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, lower<V>)
- {
- // gN is the min.
- for (unsigned g = 0; g < 256; ++g)
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, upper<V>)
- {
- // gN is the max.
- for (int g = 255; g >= 0; --g)
- {
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- }
- // if N is empty, gN is the min value.
- gN = 0;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 257; ++i)
- {
- if (N[i]->nsites() == 0)
- continue;
- std::cout << i << ": " << *N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 257; ++i)
- N[i]->clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- opt::at(output, row, col) = opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- void save_u(const image2d<value::int_u8>& u,
- const image2d<int>& is,
- box2d R_box,
- int in_R,
- int in_N)
- {
- static int id = 0;
- std::stringstream filename, is_filename;
- filename << "fllt_trace_" << std::setw(5) <<
std::setfill('0')
- << std::right << id++ << ".ppm";
- is_filename << "is_" << std::setw(5) <<
std::setfill('0')
- << std::right << id << ".pgm";
-
- //std::cout << " Save in " << filename.str() <<
std::endl;
- image2d<value::int_u8> out(is.domain());// =
duplicate(cast_image<value::int_u8>(is));
- data::fill(out, 0);
- mln_assertion(R_box.nsites() > 0);
- mln_piter_(box2d) p(R_box);
- for_all(p)
- if (is(p) == in_R)
- out(p) = 255;
- else if (is(p) == in_N)
- out(p) = 127;
- // else if (is(p) == in_N)
- // out(p) = literal::green;
-
- io::pgm::save(out, filename.str());
-
- //save is
- image2d<value::int_u8> is_out(is.domain());
- level::stretch(cast_image<value::int_u8>(is), is_out);
- io::pgm::save(is_out, is_filename.str());
- //io::pgm::save(out, filename.str());
- }
-
- template <typename I>
- void save(const I& is, unsigned in_N, unsigned in_R, const std::string& name =
"")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- if (is(p) == in_R)
- temp(p) = literal::red;
- else if (is(p) == in_N) // N
- temp(p) = literal::green;
- else if (is(p) < in_N)
- temp(p) = literal::blue;
- else
- temp(p) = literal::white;
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter <<
".ppm";
- io::ppm::save(enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
- template <typename I, typename P, typename V, typename Set>
- void blob(const Set&,
- const I& is,
- p_array<mln_point(I)>* N[257],
- unsigned in_N,
- const box2d& N_box,
- fllt_node(P, V)* current_cc)
- {
- typedef p_array<mln_point(I)> arr_t;
-
- // std::cout << ">>>>>>>enter blob. "
<< current_cc << std::endl;
- bool flower = true;
- unsigned ncc = 0;
- static image2d<unsigned> is_labeled(is.domain());
- static unsigned label = 0;
-
- if (label == 0)
- {
- data::fill(is_labeled, 0);
- label++;
- }
-
- P cur;
- mln_niter(neighb2d) n(Set::bdr_nbh(), cur);
- p_queue_fast<P> qu;
- p_array<P>& holes = current_cc->elt().holes;
-
- mln_piter(I) p(N_box);
- for_all(p)
- if (is(p) == in_N)
- break;
-
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
-
-
-
- for (unsigned i = 0; i < 256; ++i)
- //for (int i = 255; i >= 0; --i)
- {
- mln_piter(arr_t) p(*N[i]);
- for_all(p)
- {
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
- }
- }
-
- ++label;
-
- // if (holes.size() == 2)
- // std::cout << holes[0] << holes[1] << std::endl;
- // std::cout << " <<<<<<<exiting blob."
<< std::endl;
- }
-
- template <typename P, typename V>
- fllt_node(P, V)* find_root(fllt_node(P, V)* shape, unsigned in_R)
- {
- if (shape->elt().root_version == in_R)
- return shape->elt().root;
-
- fllt_node(P, V)* root = shape;
-
- shape->elt().root_version = in_R;
-
- while(root->parent())
- {
- mln_assertion(root->parent() != root);
- root = root->parent();
- mln_assertion(root);
- }
-
- shape->elt().root = root;
- return root;
- }
-
- template <typename P, typename V>
- fllt_node(P, V)* find_root(fllt_node(P, V)* shape)
- {
- fllt_node(P, V)* root = shape;
-
- while(root->parent())
- {
- mln_assertion(root->parent() != root);
- root = root->parent();
- mln_assertion(root);
- }
-
-// shape->elt().root = root;
- return root;
- }
-
- template <typename I, typename P, typename V, typename Set>
- void
- move_A_to_R(const Set&,
- p_array<P>& A,
- image2d<int>& deja_vu,
- const I& u,
- fllt_node(P, V)* current_cc,
- image2d< fllt_node(P, V)* >& smallest_shapes,
- int in_R,
- int in_N,
- accu::bbox<P>& N_box,
- p_array<P>* N[257],
- const V& g,
- unsigned& n_comps)
- {
- typedef p_array<P> arr_t;
-
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
- std::set<fllt_node(P, V)*> to_merge;
-
- // Add points of A to R.
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- if (smallest_shapes(a) && find_root(smallest_shapes(a)) == current_cc)
- continue;
- mln_invariant(deja_vu(a) == in_N);
- // mln_invariant(u(a) == g);
- mln_invariant(smallest_shapes(a) != current_cc);
-
- if (!smallest_shapes(a))
- {
- smallest_shapes(a) = current_cc;
- mln_assertion(!current_cc->elt().points.has(a));
- current_cc->elt().points.append(a);
- }
- else
- {
- mln_assertion(smallest_shapes(a)->elt().value == g ||
- Set::compare(smallest_shapes(a)->elt().value, g));
-
- to_merge.insert(smallest_shapes(a));
-
- smallest_shapes(a) = current_cc;
- mln_assertion(!current_cc->elt().points.has(a));
- current_cc->elt().points.append(a);
- }
- }
-
- // Add alreardy computed coponents to R, and also their neighborhood to N.
- typename std::set<fllt_node(P, V)*>::iterator shape_;
- for (shape_ = to_merge.begin();
- shape_ != to_merge.end();
- shape_++)
- {
- fllt_node(P, V)* to_delete = find_root(*shape_);
-
- if (to_delete == current_cc)
- continue;
-
- // Add the neighborhood of to_delete to the current one.
- //std::cout << "Merge into " << current_cc << "
to_delete :" << to_delete << std::endl;
- // std::cout << to_delete->elt().N.size() << " "
<< to_delete << std::endl;
- mln_assertion(to_delete->elt().N.size() == 257);
- for (unsigned i = 0; i < 257; ++i)
- {
- if (!to_delete->elt().N[i])
- continue;
- mln_piter(p_array<P>) p(*to_delete->elt().N[i]);
- for_all(p)
- {
- if (deja_vu(p) != in_N &&
- (!smallest_shapes(p) || find_root(smallest_shapes(p)) != current_cc))
- {
- mln_assertion(! N[i]->has(p));
- N[i]->append(p);
- deja_vu(p) = in_N;
- N_box.take(p);
- }
- }
- delete to_delete->elt().N[i];
- }
- to_delete->elt().N.clear();
-
- // the shape containing a cannot have a parent in this case.
- mln_assertion(!to_delete->parent());
- // Add points of to_delete to current_cc.
-// if (to_delete->elt().value == g)
-// {
-// mln_piter(arr_t) p(to_delete->elt().points);
-// for_all(p)
-// {
-// if (smallest_shapes(p) != current_cc)
-// {
-// mln_assertion(!current_cc->elt().points.has(p));
-// current_cc->elt().points.append(p);
-// smallest_shapes(p) = current_cc;
-// }
-// mln_postcondition(smallest_shapes(p) == current_cc);
-// }
-// }
-
-// if (to_delete->elt().value == g)
-// {
-// while(!to_delete->children().empty())
-// {
- // mln_assertion(!(*to_delete->children().begin())->elt().root ||
-// (*to_delete->children().begin())->elt().root == to_delete);
-// (*to_delete->children().begin())->elt().root = current_cc;
-// current_cc->add_child(*(to_delete->children().begin()));
-
-// }
-// delete to_delete;
-// n_comps--;
-// }
-// else
-// {
- mln_assertion(Set::compare(to_delete->elt().value, g));
- to_delete->set_parent(current_cc);
- to_delete->elt().root = current_cc;
-// }
- }
- }
-
- // LOWER LEVEL SET : region = c4, border = c8
- template <typename V>
- struct lower
- {
- typedef upper<V> opposite;
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- {
- return u < v;
- }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>&
nbh, L& nlabels)
- {
- return labeling::regional_minima(input, nbh, nlabels);
- }
-
- static const bool parent_is_brighter = true;
- static const bool id = false;
- static const V e() { return mln_max(V); }
-
-
- static const neighb2d& bdr_nbh() { return c8(); }
- static const neighb2d& reg_nbh() { return c4(); }
- };
-
-
- // UPPER LEVEL SET : region = c8, border = c4
- template <typename V>
- struct upper
- {
- typedef lower<V> opposite;
-
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- { return u > v; }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>&
nbh, L& nlabels)
- { return labeling::regional_maxima(input, nbh, nlabels); }
-
- static const bool parent_is_brighter = false;
- static const bool id = true;
- static const V e() { return mln_min(V); }
-
- static const neighb2d& bdr_nbh() { return c4(); }
- static const neighb2d& reg_nbh() { return c8(); }
- };
-
- template <typename I, typename Set>
- fllt_tree(mln_point(I), mln_value(I))&
- level_set(const Image<I>& input_,
- image2d< fllt_node(mln_point(I), mln_value(I))* >& smallest_shapes)
- {
-
- typedef mln_point(I) P;
- typedef mln_value(I) V;
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
-
- const I& input = exact(input_);
-
- mln_assertion(input.domain() == smallest_shapes.domain());
-
- unsigned l = 0, l_max = 0;
- mln_ch_value(I, unsigned) reg_min = Set::regional_extremum(input, Set::reg_nbh(),
l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- P x0;
- V g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
- data::fill(smallest_shapes, 0);
- node_type* current_cc;
-
- unsigned in_N = 1, in_R = 2;
-
- image2d<int> deja_vu(input.domain().to_larger(1));
- data::fill(deja_vu, 0);
-
- typedef p_array<P> arr_t;
- arr_t* A = new arr_t();
- arr_t* N[257];
- for (unsigned i = 0; i < 257; ++i)
- N[i] = new arr_t();
- accu::bbox<P> N_box;
-
- unsigned n_step_1 = 0, n_step_3 = 0, n_step_4c = 0, sum4c = 0,
- n_comps = 0, n_holes = 0, n_browsed = 0, n_find_root = 0,
- n_neighb = 0, n_pass = 0;
-
- // Step 1.
- step_1:
- {
- // std::cout << " step 1" << std::endl;
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- ++n_comps;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
-
- // std::cout << " new cc " << current_cc
- // << " value " << g << " point " <<
p << std::endl;
-
- }
-
- // Step 2.
- step_2:
- {
- in_N += 2;
- in_R = in_N + 1;
- // R <- 0 and N <- 0
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A->clear();
- A->append(x0);
- N_box.take(x0);
-
-// deja_vu(x0) = in_R;
- smallest_shapes(x0) = current_cc;
- current_cc->elt().points.append(x0);
- current_cc->elt().nsites++;
-
- }
-
- // Step 3.
- step_3:
- {
- //std::cout << " step 3" << std::endl;
-// save_u(input, deja_vu, N_box, in_R, in_N);
- ++n_step_3;
-
- mln_piter(arr_t) a(*A);
- mln_niter(neighb2d) x(Set::reg_nbh(), a);
-
-
- // R <- R U A
- if (A->nsites() == 0)
- goto the_end;
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- {
- n_browsed++;
- for_all(x)
- {
- if (deja_vu.has(x) && deja_vu(x) < in_N && smallest_shapes(x) !=
current_cc)
- {
- //std::cout << x << std::endl;
- if (input.has(x))
- {
- n_neighb++;
- short vx;
- if (smallest_shapes(x))
- {
- n_find_root++;
- if (smallest_shapes(x)->elt().deja_vu == in_R)
- continue;
-
- smallest_shapes(x)->elt().deja_vu = in_R;
- fllt_node(P,V)* r = find_root(smallest_shapes(x), in_R);
- if (r == current_cc)
- {
- n_pass++;
- continue;
- }
- vx = r->elt().value;
- }
- else
- vx = input(x);
- mln_assertion(! N[vx]->has(x));
- N[vx]->append(x);
- }
- else
- {
- mln_assertion(!smallest_shapes(x));
- mln_assertion(! N[256]->has(x));
- N[256]->append(x);
- }
- N_box.take(x);
- deja_vu(x) = in_N;
- }
- }
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN, Set());
- //save_u(u, deja_vu, N_box, in_R, in_N);
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (Set::compare(g, gN))
- {
- // std::cout << " step 4a" << std::endl;
- g = gN;
-
- ++n_comps;
-
- //save_u(u, deja_vu, N_box, in_R, in_N);
- blob(Set(), deja_vu, N, in_N, N_box, current_cc);
-
- n_holes += current_cc->elt().holes.nsites();
-
- node_type* child = current_cc;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- child->set_parent(current_cc);
- child->elt().root = current_cc;
- // std::cout << " new cc " << current_cc
- // << " value " << g << std::endl;
-
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(Set(), *A, deja_vu, input, current_cc, smallest_shapes, in_R, in_N, N_box,
N, g, n_comps);
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- //std::cout << " step 4b" << std::endl;
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(Set(), *A, deja_vu, input, current_cc, smallest_shapes, in_R, in_N, N_box,
N, g, n_comps);
- goto step_3;
- }
- // c)
- else
- {
- //std::cout << " step 4c " << current_cc <<
std::endl;
- n_step_4c++;
-
- current_cc->elt().N.resize(257);
- for (unsigned i = 0; i < 257; ++i)
- {
- if (N[i]->nsites() > 0)
- {
- current_cc->elt().N[i] = N[i];
- N[i] = new arr_t();
- }
- else
- current_cc->elt().N[i] = 0;
- }
- goto step_1;
- }
- }
-
- the_end:
- std::cout << " n_step1=" << n_step_1 << "
n_step3=" << n_step_3
- << " n_browsed=" << n_browsed
- << " n_browsed/nsites=" << n_browsed /
input.domain().nsites()
- << " n_find_root=" << n_find_root
- << " n_neighb=" << n_neighb
- << " n_pass=" << n_pass
- << std::endl;
- std::cout << "n comps = " << n_comps << " n holes =
" << n_holes << std::endl;
-
- return *new tree_type(current_cc);
- }
-
- template <typename P>
- void swap_p_arrays(p_array<P>*& a, p_array<P>*& b)
- {
- p_array<P>* tmp = a;
- a = b;
- b = tmp;
- }
-
- // F is the set in which we get the node.
- template <typename P, typename V, typename F>
- fllt_node(P, V)*
- find_hole(fllt_node(P, V)& node,
- const P p,
- const image2d<fllt_node(P, V)*>& other_reg)
- {
- fllt_node(P, V)* s = other_reg(p);
- mln_assertion(s);
- while (s->parent() && F::compare(s->parent()->elt().value,
node.elt().value))
- {
- mln_assertion(s);
- s = s->parent();
- mln_assertion(s);
- }
- // std::cout << " [Find the hole] of " << p
- // << " from " << &node
- // << " return " << s
- // << std::endl;
- return s;
- }
-
- template <typename P, typename V>
- bool shape_is_included(fllt_node(P, V)* A,
- fllt_node(P, V)* B)
- {
- return A->parent() == B || A == B;
- }
-
- template <typename P, typename V>
- void find_all_holes(fllt_tree(P, V)& lower_tree,
- fllt_tree(P, V)& upper_tree,
- const image2d<fllt_node(P, V)*>& low_reg,
- const image2d<fllt_node(P, V)*>& upp_reg)
- {
- typedef p_array<P> arr_t;
- typedef fllt_node(P, V) node_type;
-
- {
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,upper<V> >(node, P(hole),
upp_reg));
- }
- }
-
- {
- fllt_branch_iter_ind(P, V) node_(upper_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,lower<V> >(node, P(hole),
low_reg));
- }
- }
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- merge_trees(fllt_tree(mln_point(I), mln_value(I))& lower_tree,
- fllt_tree(mln_point(I), mln_value(I))& upper_tree,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& low_reg,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& upp_reg,
- const Image<I>& input_)
- {
-
- const I& input = exact(input_);
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
- typedef p_array<P> arr_t;
-
-
- find_all_holes(lower_tree, upper_tree, low_reg, upp_reg);
- std::vector<node_type*> to_fill;
-
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != lower<V>::id)
- continue;
-
- // std::cout << "Fill " << &node << std::endl;
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- // std::cout << "hole : " << hole << "
" << hole->elt().points << " " << std::endl;
- // std::cout << "child hole : " << child_hole <<
" " << child_hole->elt().points << std::endl;
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
- if (!child_has_bigger_hole)
- {
- // // std::cout << "move " << hole << " as child
of " << &node << std::endl;
- node.add_child(hole);
- to_fill.push_back(hole);
- }
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- for(typename std::vector<node_type*>::iterator node_ = to_fill.begin();
- node_ != to_fill.end();
- node_++)
- {
- node_type& node = **node_;
-
- fllt_branch_iter_ind(P, V) node_(fllt_branch(P, V)(upper_tree, node));
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != upper<V>::id)
- continue;
-
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
-
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- //if (hole->elt().points <= child_hole->elt().points)
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
-
- if (!child_has_bigger_hole)
- node.add_child(hole);
-
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- }
-
- return lower_tree;
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- fllt(const Image<I>& input_)
- {
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- const I& input = exact(input_);
-
- fllt_tree(P, V) upper_tree;
- fllt_tree(P, V) lower_tree;
- image2d<fllt_node(P, V)*> low_reg(input.domain());
- image2d<fllt_node(P, V)*> upp_reg(input.domain());
-
- std::cout << "1/ Compute the lower level
set.----------------------------------------" << std::endl;
- lower_tree = level_set<I, lower<V> >(input, low_reg);
-
- std::cout << "2/ Compute the upper level
set.----------------------------------------" << std::endl;
- upper_tree = level_set<I, upper<V> >(input, upp_reg);
-
- std::cout << "3/
Merge.---------------------------------------------------------------" <<
std::endl;
- fllt_tree(P, V) result_tree = merge_trees(lower_tree, upper_tree, low_reg, upp_reg,
input);
-
- return result_tree;
- }
-
-} // end of namespace mln
Index: geraud/fllt/simple_tests.cc
--- geraud/fllt/simple_tests.cc (revision 3151)
+++ geraud/fllt/simple_tests.cc (working copy)
@@ -1,84 +0,0 @@
-#include "fllt_test.hh"
-
-namespace mln
-{
- template <typename P, typename V>
- void
- draw_tree(const image2d<V>& ima,
- fllt_tree(P, V)& tree)
- {
- p_array<P> tmp;
-
- fllt_branch_iter_ind(P, V) p(tree.main_branch());
- for_all(p)
- {
- std::cout << "region mere : " << (*p).parent() <<
std::endl;
- std::cout << " ^" << std::endl;
- std::cout << " |" << std::endl;
- std::cout << "region : " << &*p
- << " value = " << (*p).elt().value << std::endl
- << " from " << ((*p).elt().set_id == lower<V>::id ?
- "lower" : "upper") << " level set."
- << std::endl
- << " nsites = " << (*p).elt().nsites << std::endl
- << " holes = " << (*p).elt().holes << std::endl;
-
- std::cout << std::endl;
-
- tmp.append((*p).elt().points);
-
- fllt_branch_iter_ind(P, V) n(fllt_branch(P, V)(tree, *p));
- for_all(n)
- tmp.append((*n).elt().points);
-
- if ((*p).elt().points.nsites() > 0)
- debug::println(ima | tmp);
- tmp.clear();
-
- std::cout << std::endl;
- }
- }
-
-} // End of namespace mln.
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- typedef fllt_tree(point2d, int_u8) tree_type;
-
-// int vs[8][9] = { {2,2,2,2,2,2,2,2,2},
-// {2,2,2,2,2,2,2,2,2},
-// {2,1,1,1,1,1,1,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,2,2,1,0,4,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,1,1,1,1,1,1,2},
-// {2,2,2,2,2,2,2,2,2} };
-
-
-// int vs[3][4] = { {1,8,2,4},
-// {5,6,3,8},
-// {9,14,0,12} };
-
- int vs[3][4] = { {1,1,2,1},
- {1,1,2,2},
- {1,1,2,1} };
-
-// int vs[8][9] = { {0,0,0,0,0,0,0,0,0},
-// {0,0,0,0,0,0,0,0,0},
-// {0,1,1,1,1,1,1,1,0},
-// {0,1,0,0,1,5,5,1,1},
-// {0,1,0,0,1,5,5,1,0},
-// {0,1,0,0,1,5,5,1,0},
-// {0,1,1,1,1,1,1,1,0},
-// {0,0,0,0,0,0,0,0,0} };
-
- image2d<int> lena_(make::image2d(vs));
- image2d<int_u8> lena(lena_.domain());
- data::fill(lena, lena_);
-
- tree_type tree = fllt(lena);
- draw_tree(lena, tree);
-}
Index: geraud/fllt/compute_fllt.cc
--- geraud/fllt/compute_fllt.cc (revision 3151)
+++ geraud/fllt/compute_fllt.cc (working copy)
@@ -1,19 +0,0 @@
-#include "fllt.hh"
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- typedef fllt_tree(point2d, int_u8) tree_type;
-
- if (argc != 2)
- {
- std::cerr << "usage: " << argv[0] << "
filename" << std::endl;
- return 1;
- }
-
- image2d<int_u8> lena;
- io::pgm::load(lena, argv[1]);
- tree_type tree = fllt(lena);
-}
Index: geraud/fllt/fllt.svg.1.cc
--- geraud/fllt/fllt.svg.1.cc (revision 3151)
+++ geraud/fllt/fllt.svg.1.cc (working copy)
@@ -1,222 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-
-#include <mln/value/int_u8.hh>
-# include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/accu/bbox.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
- namespace my
- {
-
- template <typename N_t>
- unsigned compute_gN(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- if (N[i].nsites() != 0)
- return i;
- mln_invariant(0);
- return 0;
- }
-
-
- template <typename I, typename A_t>
- void save(const I& is, const A_t& A)
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- switch (is(p)) {
- case 1: // R
- temp(p) = literal::red;
- break;
- case 2: // N
- temp(p) = literal::green;
- break;
- }
-
- mln_piter(A_t) a(A);
- for_all(a) // A
- temp(a) = literal::blue;
-
- std::stringstream filename;
- filename << "./temp_" << ++counter <<
".ppm";
- io::ppm::save(temp, filename.str());
- }
-
-
- template <typename I, typename Nbh>
- void fllt(const Image<I>& input_, const Neighborhood<Nbh>& nbh_)
- {
- const I& input = exact(input_);
- const Nbh& nbh = exact(nbh_);
-
- unsigned l = 0, l_max;
- mln_ch_value(I, unsigned) reg_min = labeling::regional_minima(input, nbh, l_max);
-
- // Variables.
- I u = mln::duplicate(input);
- mln_point(I) x0;
- mln_value(I) g, gN;
- image2d<unsigned char> is(input.domain());
- const unsigned in_R = 1, in_N = 2, in_O = 0;
-
- typedef p_array<mln_point(I)> arr_t;
- arr_t A;
- arr_t N[256];
-
- accu::bbox<mln_point(I)> R_box;
-
-
- // Step 1.
- step_1:
- {
- if (l == l_max)
- return;
- l += 1;
- mln_piter(I) p(input.domain());
- for_all(p)
- if (reg_min(p) == l)
- break;
- x0 = p;
- g = input(x0);
- }
-
- // Step 2.
- step_2:
- {
- R_box.init();
- data::fill(is, in_O);
- A.append(x0);
- }
-
- // Step 3.
- step_3:
- {
- mln_piter(arr_t) a(A);
- mln_niter(Nbh) x(nbh, a);
-
- my::save(is, A);
-
- // R <- R U A
- for_all(a)
- is(a) = in_R;
- R_box.take(A.bbox());
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- if (u.has(x) && is(x) == in_O)
- {
- N[u(x)].append(x);
- is(x) = in_N;
- }
- // gN = min u(x) for all x in N
- gN = compute_gN(N);
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (g < gN)
- {
- // FIXME: DO the hole thing.
- A = N[g];
- N[g].clear();
- g = gN;
- gN = compute_gN(N);
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- A = N[g];
- N[g].clear();
- g = gN;
- gN = compute_gN(N);
- goto step_3;
- }
- // c)
- else
- {
- mln_piter(box_<mln_point(I)>) p(R_box);
- for_all(p)
- if (is(p) == in_R)
- u(p) = g;
- goto step_1;
- }
- }
-
- }
-
- } // end of namespace mln::my
-
-} // end of namespace mln
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- image2d<int_u8> lena;
- io::pgm::load(lena, "../../img/tiny.pgm");
-
- my::fllt(lena, c4());
- io::pgm::save(lena, "./out.pgm");
-
-}
Index: geraud/fllt/fllt.svg.7.hh
--- geraud/fllt/fllt.svg.7.hh (revision 3151)
+++ geraud/fllt/fllt.svg.7.hh (working copy)
@@ -1,913 +0,0 @@
-// Copyright (C) 2008 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_FLLT_HH
-# define MLN_FLLT_HH
-
-#include <iomanip>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-#include <mln/core/site_set/p_queue_fast.hh>
-#include <mln/core/image/cast_image.hh>
-
-#include <mln/opt/at.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/level/compare.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/labeling/regional_maxima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/util/tree.hh>
-#include <mln/util/branch_iter_ind.hh>
-#include <mln/util/branch_iter.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
-# define fllt_tree(P, V) mln::util::tree< fllt_node_elt<P, V> >
-# define fllt_node(P, V) mln::util::tree_node< fllt_node_elt<P, V> >
-# define fllt_tree_ptr(P, V) mln::util::tree< fllt_node_elt<P, V>* >
-# define fllt_node_ptr(P, V) mln::util::tree_node< fllt_node_elt<P, V>* >
-# define fllt_branch(P, V) mln::util::branch< fllt_node_elt<P, V> >
-# define fllt_branch_iter_ind(P, V) mln::util::branch_iter_ind< fllt_node_elt<P,
V> >
-# define fllt_branch_iter(P, V) mln::util::branch_iter< fllt_node_elt<P, V>
>
-
-# define stl_to_mln_iter(T) stl_iterator< T >
-
- //Fwd declarations.
- template <typename V> struct lower;
- template <typename V> struct upper;
-
- template <typename P, typename V>
- struct fllt_node_elt
- {
- V value;
- p_array<P> points;
- p_array<P> holes;
- std::vector<fllt_node(P, V)*> hole_shapes;
- /// Tell if his parent if brighter or not. Nb : if the parent
- /// if brighter, the node come from the lower level set
- bool brighter;
- unsigned nsites;
- bool tagged;
- bool set_id;
-
- fllt_node_elt(bool set_id) : nsites(0), tagged(false), set_id(set_id) {}
- };
-
-
- template <typename C>
- class stl_iterator
- {
- public:
- stl_iterator(C& c) : container_(c) {}
- void start(){ it_ = container_.begin(); }
- void next() { it_++; }
- bool is_valid() const{ return it_ != container_.end(); }
- typename C::value_type& operator*() { return *it_; }
-
- private:
- C& container_;
- typename C::iterator it_;
- };
-
- template <typename N_t, typename G, typename Set>
- void update_gN(const N_t& N, G& gN);
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, lower<V>)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, upper<V>)
- {
- for (int g = 255; g >= 0; --g)
- {
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- }
- // if N is empty, gN is the min value.
- gN = 0;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i]->nsites() == 0)
- continue;
- std::cout << i << ": " << *N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i]->clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- opt::at(output, row, col) = opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- void save_u(const image2d<value::int_u8>& u,
- const image2d<int>& is,
- box2d R_box,
- int in_R,
- int in_N)
- {
- static int id = 0;
- std::stringstream filename;
- filename << "fllt_trace_" << std::setw(5) <<
std::setfill('0')
- << std::right << id++ << ".ppm";
-
- image2d<value::int_u8> out = duplicate(cast_image<value::int_u8>(is));
-
- mln_assertion(R_box.nsites() > 0);
- mln_piter_(box2d) p(R_box);
- for_all(p)
- if (is(p) == in_R)
- out(p) = 255;
- else if (is(p) == in_N)
- out(p) = 127;
- // else if (is(p) == in_N)
- // out(p) = literal::green;
-
- io::pgm::save(out, filename.str());
- //io::pgm::save(out, filename.str());
- }
-
- template <typename I>
- void save(const I& is, unsigned in_N, unsigned in_R, const std::string& name =
"")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- if (is(p) == in_R)
- temp(p) = literal::red;
- else if (is(p) == in_N) // N
- temp(p) = literal::green;
- else if (is(p) < in_N)
- temp(p) = literal::blue;
- else
- temp(p) = literal::white;
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter <<
".ppm";
- io::ppm::save(enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
- template <typename I, typename P, typename V, typename Set>
- void blob(const Set&,
- const I& is,
- p_array<mln_point(I)>* N[256],
- unsigned in_N,
- const box2d& N_box,
- fllt_node(P, V)* current_cc)
- {
- typedef p_array<mln_point(I)> arr_t;
-
- // std::cout << ">>>>>>>enter blob. "
<< current_cc << std::endl;
- bool flower = true;
- unsigned ncc = 0;
- static image2d<unsigned> is_labeled(is.domain());
- static unsigned label = 0;
-
- if (label == 0)
- {
- data::fill(is_labeled, 0);
- label++;
- }
-
- P cur;
- mln_niter(neighb2d) n(Set::bdr_nbh(), cur);
- p_queue_fast<P> qu;
- p_array<P>& holes = current_cc->elt().holes;
-
- mln_piter(I) p(N_box);
- for_all(p)
- if (is(p) == in_N)
- break;
-
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
-
-
-
- for (unsigned i = 0; i < 256; ++i)
- //for (int i = 255; i >= 0; --i)
- {
- mln_piter(arr_t) p(*N[i]);
- for_all(p)
- {
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
- }
- }
-
- ++label;
-
- }
-
- template <typename P, typename V>
- void
- move_A_to_R(p_array<P>& A,
- image2d<int>& deja_vu,
- fllt_node(P, V)* current_cc,
- image2d< fllt_node(P, V)* >& smallest_shapes,
- int in_R,
- int in_N,
- const V& g,
- unsigned& n_comps)
- {
- typedef p_array<P> arr_t;
-
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(deja_vu(a) == in_N);
- mln_invariant(smallest_shapes(a) != current_cc);
- // if (smallest_shapes(a) == current_cc)
- // continue;
-
- deja_vu(a) = in_R;
- if (!smallest_shapes(a))
- {
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- if (!smallest_shapes(a)->parent())
- if (smallest_shapes(a)->elt().value == g)
- {
- fllt_node(P, V)* to_delete = smallest_shapes(a);
-
- // current_cc->elt().points.append(smallest_shapes(a)->elt().points);
- // A.append(smallest_shapes(a)->elt().points);
-
- mln_piter(arr_t) p(smallest_shapes(a)->elt().points);
- // Todo optimization here.
- for_all(p)
- {
- smallest_shapes(p) = 0;
- // deja_vu(p) = in_R;
- //smallest_shapes(p) = current_cc;
- }
-
- while(!to_delete->children().empty())
- current_cc->add_child(*to_delete->children().begin());
- delete to_delete;
- n_comps--;
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- smallest_shapes(a)->set_parent(current_cc);
- }
- }
-
- // LOWER LEVEL SET information to compute the max tree.
- // -> region = c4, border = c8
- template <typename V>
- struct lower
- {
- typedef upper<V> opposite;
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- {
- return u < v;
- }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>&
nbh, L& nlabels)
- {
- return labeling::regional_minima(input, nbh, nlabels);
- }
-
- static const bool parent_is_brighter = true;
- static const bool id = false;
-
- static const neighb2d& bdr_nbh() { return c8(); }
- static const neighb2d& reg_nbh() { return c4(); }
- };
-
-
- // UPPER LEVEL SET information to compute the max tree.
- // -> region = c8, border = c4
- template <typename V>
- struct upper
- {
- typedef lower<V> opposite;
-
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- { return u > v; }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>&
nbh, L& nlabels)
- { return labeling::regional_maxima(input, nbh, nlabels); }
-
- static const bool parent_is_brighter = false;
- static const bool id = true;
-
- static const neighb2d& bdr_nbh() { return c4(); }
- static const neighb2d& reg_nbh() { return c8(); }
- };
-
- /*! Fast computation of a min/max tree.
- *
- * \param[in] input_ An input image.
- * \param[out] smallest_shapes We stock in this image, for each point, a pointer
- * to the smallest shape containing it.
- * \return The min/max tree built.
- *
- */
- template <typename I, typename Set>
- fllt_tree(mln_point(I), mln_value(I))&
- level_set(const Image<I>& input_,
- image2d< fllt_node(mln_point(I), mln_value(I))* >& smallest_shapes)
- {
-
- typedef mln_point(I) P;
- typedef mln_value(I) V;
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
-
- const I& input = exact(input_);
-
- mln_assertion(input.domain() == smallest_shapes.domain());
-
- unsigned l = 0, l_max = 0;
- mln_ch_value(I, unsigned) reg_min = Set::regional_extremum(input, Set::reg_nbh(),
l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- I u = mln::duplicate(input);
- P x0;
- V g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
- data::fill(smallest_shapes, 0);
- node_type* current_cc;
-
- unsigned in_N = 1, in_R = 2;
-
- image2d<int> deja_vu(input.domain().to_larger(1));
- data::fill(deja_vu, 0);
-
- typedef p_array<P> arr_t;
- arr_t* A = new arr_t();
- arr_t* N[256];
- for (unsigned i = 0; i < 256; ++i)
- N[i] = new arr_t();
- accu::bbox<P> N_box;
-
- bool touch_border_of_image = false;
- unsigned n_step_1 = 0, n_step_3 = 0, n_step_4c = 0, n_comps = 0, n_holes = 0;
-
- // Step 1.
- step_1:
- {
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- ++n_comps;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- touch_border_of_image = false;
-
- }
-
- // Step 2.
- step_2:
- {
- in_N += 2;
- in_R = in_N + 1;
- // R <- 0 and N <- 0
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A->clear();
- A->append(x0);
- N_box.take(x0);
-
- deja_vu(x0) = in_R;
- smallest_shapes(x0) = current_cc;
- current_cc->elt().points.append(x0);
- current_cc->elt().nsites++;
-
- }
-
- // Step 3.
- step_3:
- {
- // save_u(u, deja_vu, N_box, in_R, in_N);
- ++n_step_3;
-
- mln_piter(arr_t) a(*A);
- mln_niter(neighb2d) x(Set::reg_nbh(), a);
-
-
- // R <- R U A
- if (A->nsites() == 0)
- goto the_end;
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- {
- if (deja_vu.has(x) && deja_vu(x) < in_N)
- {
- if (u.has(x))
- {
- N[u(x)]->append(x);
- N_box.take(x);
- }
- else
- touch_border_of_image = true;
- deja_vu(x) = in_N;
- }
- }
- // gN <- min u(x) for all x in N
- update_gN(N, gN, Set());
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (Set::compare(g, gN))
- {
- g = gN;
-
- ++n_comps;
-
- if (touch_border_of_image)
- blob(Set(), deja_vu, N, in_N, N_box.to_result().to_larger(1), current_cc);
- else
- blob(Set(), deja_vu, N, in_N, N_box, current_cc);
-
- n_holes += current_cc->elt().holes.nsites();
-
- node_type* child = current_cc;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- child->set_parent(current_cc);
-
-
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // c)
- else
- {
- n_step_4c++;
- mln_piter(I) r(N_box);
- for_all(r)
- if (deja_vu(r) == in_R)
- u(r) = g;
-
- goto step_1;
- }
- }
-
- the_end:
- std::cout << " n_step1 : " << n_step_1 << "
n_step3 : " << n_step_3 << " n_step4c : " << n_step_4c
<< std::endl;
- std::cout << "n comps = " << n_comps << " n holes =
" << n_holes << std::endl;
-
- return *new tree_type(current_cc);
- }
-
- /*! Get the hole of a shape which contains a given point.
- *
- * \param[in] node a shape.
- * \param[in] p a point.
- * \param[in] other_reg The map which associate a point with its smallest shape
- * of the oposite tree.
- * \return true if A is included in B.
- *
- */
- // F is the set in which we get the node.
- template <typename P, typename V, typename F>
- fllt_node(P, V)*
- find_hole(fllt_node(P, V)& node,
- const P p,
- const image2d<fllt_node(P, V)*>& other_reg)
- {
- fllt_node(P, V)* s = other_reg(p);
- mln_assertion(s);
- // Go up the tree.
- while (s->parent() && F::compare(s->parent()->elt().value,
node.elt().value))
- {
- mln_assertion(s);
- s = s->parent();
- mln_assertion(s);
- }
- // std::cout << " [Find the hole] of " << p
- // << " from " << &node
- // << " return " << s
- // << std::endl;
- return s;
- }
-
- /*! Test the inclusion of two shapes of the same tree
- *
- * \param[in] A a shape.
- * \param[in] B a shape.
- * \return true if A is included in B.
- *
- * \pre The shapes have to come from the same tree.
- */
- template <typename P, typename V>
- bool shape_is_included(fllt_node(P, V)* A,
- fllt_node(P, V)* B)
- {
- return A->parent() == B || A == B;
- }
-
- /*! Associated the points of the holes of the min/max tree's shapes.
- *
- * \param[in] lower_tree The min tree.
- * \param[in] upper_tree The max tree.
- * \param[in] low_reg The map which associate a point with its smallest shape
- * of the min tree.
- * \param[in] upp_reg The map which associate a point with its smallest shape
- * of the max tree.
- * \return The merged tree.
- *
- */
- template <typename P, typename V>
- void find_all_holes(fllt_tree(P, V)& lower_tree,
- fllt_tree(P, V)& upper_tree,
- const image2d<fllt_node(P, V)*>& low_reg,
- const image2d<fllt_node(P, V)*>& upp_reg)
- {
- typedef p_array<P> arr_t;
- typedef fllt_node(P, V) node_type;
-
- // Get the holes of the min tree
- {
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,upper<V> >(node, P(hole),
upp_reg));
- }
- }
-
- // Get the holes of the max tree
- {
- fllt_branch_iter_ind(P, V) node_(upper_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,lower<V> >(node, P(hole),
low_reg));
- }
- }
- }
-
- /*! Merge the Min and the max tree.
- *
- * \param[in] lower_tree The min tree.
- * \param[in] upper_tree The max tree.
- * \param[in] low_reg The map which associate a point with its smallest shape
- * of the min tree.
- * \param[in] upp_reg The map which associate a point with its smallest shape
- * of the max tree.
- * \return The merged tree.
- *
- */
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- merge_trees(fllt_tree(mln_point(I), mln_value(I))& lower_tree,
- fllt_tree(mln_point(I), mln_value(I))& upper_tree,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& low_reg,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& upp_reg,
- const Image<I>& input_)
- {
-
- const I& input = exact(input_);
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
- typedef p_array<P> arr_t;
-
-
- // Here, a hole of a shape of the max or min tree is represented
- // by a point belonging to this hole. We need to associate each of
- // these points with its shape in the oposite tree.
- find_all_holes(lower_tree, upper_tree, low_reg, upp_reg);
- std::vector<node_type*> to_fill;
-
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- // Browse the shapes of the min_tree, in order to put as child of
- // min tree's shapes the shapes of the max tree corresponding to
- // their holes.
- for_all(node_)
- {
- node_type& node = *node_;
- // If the node was not in the min tree at the begining, we ignore it.
- if (node.elt().set_id != lower<V>::id)
- continue;
-
- // Browse the holes of the shape.
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- // Check if hole_ is contained by a hole of the children of node.
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
-
- // If no, move the shape of the max tree previously associated to this hole.
- // as child of node.
- if (!child_has_bigger_hole)
- {
- // // std::cout << "move " << hole << " as child
of " << &node << std::endl;
- node.add_child(hole);
- to_fill.push_back(hole);
- }
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- // At this step, we have filled all the holes of the min
- // tree. But, by filling these holes, we introduced somes holes of
- // the max tree in the result tree. We need to fill them.
-
- // Thus, we browse the shapes of the max tree previously merged in
- // the min tree, in order to check their holes.
- for(typename std::vector<node_type*>::iterator node_ = to_fill.begin();
- node_ != to_fill.end();
- node_++)
- {
- node_type& node = **node_;
-
- fllt_branch_iter_ind(P, V) node_(fllt_branch(P, V)(upper_tree, node));
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != upper<V>::id)
- continue;
-
- // Check if hole_ is contained by a hole of the children of node.
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
-
- // If no, move the shape of the max tree previously associated to this hole.
- // as child of node.
- if (!child_has_bigger_hole)
- node.add_child(hole);
-
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- }
-
- return lower_tree;
- }
-
- /*! This function compute the fllt tree of an image.
- *
- * \param[in] input_ An input image.
- * \return The computed tree.
- *
- */
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- fllt(const Image<I>& input_)
- {
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- const I& input = exact(input_);
-
- fllt_tree(P, V) upper_tree;
- fllt_tree(P, V) lower_tree;
- image2d<fllt_node(P, V)*> low_reg(input.domain());
- image2d<fllt_node(P, V)*> upp_reg(input.domain());
-
- // Compute the Min tree.
- std::cout << "1/ Compute the lower level
set.----------------------------------------" << std::endl;
- lower_tree = level_set<I, lower<V> >(input, low_reg);
-
- // Compute the Max tree.
- std::cout << "2/ Compute the upper level
set.----------------------------------------" << std::endl;
- upper_tree = level_set<I, upper<V> >(input, upp_reg);
-
- // Merge the two trees.
- std::cout << "3/
Merge.---------------------------------------------------------------" <<
std::endl;
- fllt_tree(P, V) result_tree = merge_trees(lower_tree, upper_tree, low_reg, upp_reg,
input);
-
- return result_tree;
- }
-
-} // end of namespace mln
-
-#endif // ! MLN_FLLT_HH
Index: geraud/fllt/fllt_tree_to_image.hh
--- geraud/fllt/fllt_tree_to_image.hh (revision 3151)
+++ geraud/fllt/fllt_tree_to_image.hh (working copy)
@@ -1,30 +0,0 @@
-#ifndef MLN_FLLT_TREE_TO_IMAGE_HH
-# define MLN_FLLT_TREE_TO_IMAGE_HH
-
-#include "fllt.svg.7.hh"
-
-namespace mln
-{
- template <typename I>
- void fllt_tree_to_image_(I& output,
- fllt_node(point2d, value::int_u8)* node)
- {
- data::fill((output | node->elt().points).rw(), node->elt().value);
-
- for (int i = 0; i < node->children().size(); i++)
- fllt_tree_to_image_(output, node->children()[i]);
- }
-
- template <typename I>
- I fllt_tree_to_image(const I& input,
- fllt_tree(point2d, value::int_u8)& tree)
- {
- I output;
- initialize(output, input);
- fllt_tree_to_image_(output, tree.root());
- return output;
- }
-
-}
-
-#endif // ! MLN_FLLT_TREE_TO_IMAGE_HH
Index: geraud/fllt/fllt.svg.2.cc
--- geraud/fllt/fllt.svg.2.cc (revision 3151)
+++ geraud/fllt/fllt.svg.2.cc (working copy)
@@ -1,304 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-
-#include <mln/value/int_u8.hh>
-# include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/opt/at.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
- namespace my
- {
-
- template <typename N_t, typename G>
- void update_gN(const N_t& N, G& gN)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g].nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i].nsites() == 0)
- continue;
- std::cout << i << ": " << N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i].clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- opt::at(output, row, col) =
- mln::opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- template <typename I>
- void save(const I& is, const std::string& name = "")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- switch (is(p)) {
- case 1: // R
- temp(p) = literal::red;
- break;
- case 2: // N
- temp(p) = literal::green;
- break;
- case 3: // A
- temp(p) = literal::blue;
- break;
- }
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter << ".ppm";
- io::ppm::save(my::enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
- template <typename I, typename Nbh>
- void fllt(const Image<I>& input_, const Neighborhood<Nbh>& nbh_)
- {
- const I& input = exact(input_);
- const Nbh& nbh = exact(nbh_);
-
- unsigned l = 0, l_max;
- mln_ch_value(I, unsigned) reg_min = labeling::regional_minima(input, nbh, l_max);
-
- // Variables.
- I u = mln::duplicate(input);
- mln_point(I) x0;
- mln_value(I) g, gN;
- image2d<unsigned char> is(input.domain());
- const unsigned in_R = 1, in_N = 2, in_A = 3, in_O = 0;
-
- typedef p_array<mln_point(I)> arr_t;
- arr_t A, R;
- R.reserve(input.nsites());
- arr_t N[256];
-
- accu::bbox<mln_point(I)> R_box;
-
- unsigned n_step_1 = 0, n_step_3 = 0;
-
- // Step 1.
- step_1:
- {
- if (l == l_max)
- goto the_end;
-
- ++n_step_1;
-
- l += 1;
- mln_piter(I) p(input.domain());
- for_all(p)
- if (reg_min(p) == l)
- break;
- x0 = p;
- g = input(x0);
- }
-
- // Step 2.
- step_2:
- {
- data::fill(is, in_O);
- // R <- 0
- R_box.init();
- R.clear();
- // A <- { x0 }
- A.clear();
- A.append(x0);
- is(x0) = in_A;
- // N <- 0
- clear_N(N);
- }
-
- // Step 3.
- step_3:
- {
- ++n_step_3;
-
- mln_piter(arr_t) a(A);
- mln_niter(Nbh) x(nbh, a);
-
-
- my::save(is);
-
-
- // R <- R U A
- if (A.nsites() == 0)
- goto the_end;
-
- R.append(A);
- for_all(a)
- {
- mln_invariant(is(a) == in_A);
- is(a) = in_R;
- }
- mln_invariant(R.nsites() == (is | in_R).nsites());
- R_box.take(A.bbox());
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- if (u.has(x) && is(x) == in_O)
- {
- N[u(x)].append(x);
- is(x) = in_N;
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN);
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (g < gN)
- {
- g = gN;
- // FIXME: DO the hole thing.
- A = N[g];
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(is(a) == in_N);
- is(a) = in_A;
- }
- N[g].clear();
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- A = N[g];
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(is(a) == in_N);
- is(a) = in_A;
- }
- N[g].clear();
- goto step_3;
- }
- // c)
- else
- {
- mln_invariant(R_box.to_result() == geom::bbox(is | in_R));
- mln_piter(arr_t) r(R);
- for_all(r)
- u(r) = g;
- goto step_1;
- }
- }
-
- the_end:
- std::cout << n_step_1 << ' ' << n_step_3 <<
std::endl;
-
- }
-
- } // end of namespace mln::my
-
-} // end of namespace mln
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- image2d<int_u8> lena;
- io::pgm::load(lena, "../../img/tiny.pgm");
-
- my::fllt(lena, c4());
- io::pgm::save(lena, "./out.pgm");
-
-}
Index: geraud/fllt/fllt.svg.3.cc
--- geraud/fllt/fllt.svg.3.cc (revision 3151)
+++ geraud/fllt/fllt.svg.3.cc (working copy)
@@ -1,313 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-
-#include <mln/value/int_u8.hh>
-# include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/opt/at.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
- namespace my
- {
-
- template <typename N_t, typename G>
- void update_gN(const N_t& N, G& gN)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g].nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i].nsites() == 0)
- continue;
- std::cout << i << ": " << N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i].clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- mln::opt::at(output, row, col) =
- mln::opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- template <typename I>
- void save(const I& is, const std::string& name = "")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- switch (is(p)) {
- case 1: // R
- temp(p) = literal::red;
- break;
- case 2: // N
- temp(p) = literal::green;
- break;
- case 3: // A
- temp(p) = literal::blue;
- break;
- }
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter << ".ppm";
- io::ppm::save(my::enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
- template <typename I, typename Nbh>
- void fllt(const Image<I>& input_, const Neighborhood<Nbh>& nbh_)
- {
- const I& input = exact(input_);
- const Nbh& nbh = exact(nbh_);
-
- unsigned l = 0, l_max;
- mln_ch_value(I, unsigned) reg_min = labeling::regional_minima(input, nbh, l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- I u = mln::duplicate(input);
- mln_point(I) x0;
- mln_value(I) g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
-
- image2d<unsigned char> is(input.domain());
- const unsigned in_R = 1, in_N = 2, in_A = 3, in_O = 0;
- data::fill(is, in_O);
-
- typedef p_array<mln_point(I)> arr_t;
- arr_t A;
- arr_t N[256];
- accu::bbox<mln_point(I)> N_box;
-
- unsigned n_step_1 = 0, n_step_3 = 0;
-
- // Step 1.
- step_1:
- {
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- }
-
- // Step 2.
- step_2:
- {
- // R <- 0 and N <- 0
- if (N_box.is_valid() != 0)
- data::fill((is | N_box.to_result()).rw(), in_O);
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A.clear();
- A.append(x0);
- is(x0) = in_A;
- }
-
- // Step 3.
- step_3:
- {
- ++n_step_3;
-
- mln_piter(arr_t) a(A);
- mln_niter(Nbh) x(nbh, a);
-
-
-// my::save(is);
-
-
- // R <- R U A
- if (A.nsites() == 0)
- goto the_end;
-
- for_all(a)
- {
- mln_invariant(is(a) == in_A);
- is(a) = in_R;
- }
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- if (u.has(x) && is(x) == in_O)
- {
- N[u(x)].append(x);
- is(x) = in_N;
- N_box.take(x);
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN);
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (g < gN)
- {
- g = gN;
- // FIXME: DO the hole thing.
- A = N[g];
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(is(a) == in_N);
- is(a) = in_A;
- // N_box is not re-computed so that we save time;
- // N_box is always growing while looping from step 3.
- }
- N[g].clear();
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- A = N[g];
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(is(a) == in_N);
- is(a) = in_A;
- }
- N[g].clear();
- goto step_3;
- }
- // c)
- else
- {
- mln_piter(I) r(N_box);
- for_all(r)
- if (is(r) == in_R)
- u(r) = g;
- goto step_1;
- }
- }
-
- the_end:
- std::cout << n_step_1 << ' ' << n_step_3 <<
std::endl;
-
- }
-
- } // end of namespace mln::my
-
-} // end of namespace mln
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 2)
- {
- std::cerr << "usage: " << argv[0] << "
filename" << std::endl;
- return 1;
- }
-
- using namespace mln;
- using value::int_u8;
-
- image2d<int_u8> lena;
- io::pgm::load(lena, argv[1]);
-
- my::fllt(lena, c4());
- io::pgm::save(lena, "./out.pgm");
-
-}
Index: geraud/fllt/fllt.svg.4.cc
--- geraud/fllt/fllt.svg.4.cc (revision 3151)
+++ geraud/fllt/fllt.svg.4.cc (working copy)
@@ -1,352 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-
-#include <mln/value/int_u8.hh>
-# include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/level/compare.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/opt/at.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
- namespace my
- {
-
- template <typename N_t, typename G>
- void update_gN(const N_t& N, G& gN)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g].nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i].nsites() == 0)
- continue;
- std::cout << i << ": " << N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i].clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- mln::opt::at(output, row, col) =
- mln::opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- template <typename I>
- void save(const I& is, const std::string& name = "")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- switch (is(p)) {
- case 1: // R
- temp(p) = literal::red;
- break;
- case 2: // N
- temp(p) = literal::green;
- break;
- case 3: // A
- temp(p) = literal::blue;
- break;
- }
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter << ".ppm";
- io::ppm::save(my::enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
- template <typename I, typename Nbh>
- void fllt(const Image<I>& input_, const Neighborhood<Nbh>& nbh_)
- {
- const I& input = exact(input_);
- const Nbh& nbh = exact(nbh_);
-
- unsigned l = 0, l_max;
- mln_ch_value(I, unsigned) reg_min = labeling::regional_minima(input, nbh, l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- I u = mln::duplicate(input);
- mln_point(I) x0;
- mln_value(I) g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
-
-// image2d<unsigned char> is(input.domain());
-// const unsigned in_R = 1, in_N = 2, in_A = 3, in_O = 0;
-// data::fill(is, in_O);
-
- image2d<bool> deja_vu(input.domain());
- data::fill(deja_vu, false);
-
- typedef p_array<mln_point(I)> arr_t;
- arr_t A;
- arr_t N[256];
- accu::bbox<mln_point(I)> N_box;
-
- unsigned n_step_1 = 0, n_step_3 = 0;
-
- // Step 1.
- step_1:
- {
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- }
-
- // Step 2.
- step_2:
- {
- // R <- 0 and N <- 0
- if (N_box.is_valid() != 0)
- {
-// data::fill((is | N_box.to_result()).rw(), in_O);
- data::fill(deja_vu | N_box.to_result()), false);
- }
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A.clear();
- A.append(x0);
-// is(x0) = in_A;
- deja_vu(x0) = true;
- }
-
- // Step 3.
- step_3:
- {
- ++n_step_3;
-
- mln_piter(arr_t) a(A);
- mln_niter(Nbh) x(nbh, a);
-
-
-// my::save(is);
-
-
- // R <- R U A
- if (A.nsites() == 0)
- goto the_end;
-
-// for_all(a)
-// {
-// mln_invariant(is(a) == in_A);
-// is(a) = in_R;
-// }
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- {
-// if (u.has(x))
-// mln_invariant(is(x) != in_O || deja_vu(x) == false);
-
- //if (u.has(x) && is(x) == in_O)
- if (u.has(x) && !deja_vu(x))
- {
- N[u(x)].append(x);
-// is(x) = in_N;
- N_box.take(x);
- deja_vu(x) = true;
- }
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN);
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (g < gN)
- {
- g = gN;
- // FIXME: DO the hole thing.
- A = N[g];
-// mln_piter(arr_t) a(A);
-// for_all(a)
-// {
-// mln_invariant(is(a) == in_N);
-// is(a) = in_A;
-// // N_box is not re-computed so that we save time;
-// // N_box is always growing while looping from step 3.
-// }
- N[g].clear();
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- A = N[g];
-// mln_piter(arr_t) a(A);
-// for_all(a)
-// {
-// mln_invariant(is(a) == in_N);
-// is(a) = in_A;
-// }
- N[g].clear();
- goto step_3;
- }
- // c)
- else
- {
- // Here deja_vu is (R U N U A)
- // we only want R
-
- // yet A is empty (cause included in R)
- // so this test is ok: mln_invariant((is | in_A).nsites() == 0);
-
- for (unsigned i = 0; i < 256; ++i)
- if (N[i].nsites())
- data::fill(deja_vu | N[i]), false);
-// {
-// mln_piter(arr_t) p(N[i]);
-// for_all(p)
-// deja_vu(p) = false;
-// }
-
-// mln_invariant(deja_vu == ((pw::value(is) == pw::cst(in_R)) | input.domain()));
-
-// mln_piter(I) r(N_box);
-// for_all(r)
-// if (is(r) == in_R)
-// u(r) = g;
-
- mln_piter(I) r(N_box);
- for_all(r)
- if (deja_vu(r))
- u(r) = g;
-
- goto step_1;
- }
- }
-
- the_end:
- std::cout << n_step_1 << ' ' << n_step_3 <<
std::endl;
-
- }
-
- } // end of namespace mln::my
-
-} // end of namespace mln
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 2)
- {
- std::cerr << "usage: " << argv[0] << "
filename" << std::endl;
- return 1;
- }
-
- using namespace mln;
- using value::int_u8;
-
- image2d<int_u8> lena;
- io::pgm::load(lena, argv[1]);
-
- my::fllt(lena, c4());
- io::pgm::save(lena, "./out.pgm");
-
-}
Index: geraud/fllt/fllt.svg.5.cc
--- geraud/fllt/fllt.svg.5.cc (revision 3151)
+++ geraud/fllt/fllt.svg.5.cc (working copy)
@@ -1,353 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-
-#include <mln/value/int_u8.hh>
-# include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/level/compare.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/opt/at.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
- namespace my
- {
-
- template <typename N_t, typename G>
- void update_gN(const N_t& N, G& gN)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i]->nsites() == 0)
- continue;
- std::cout << i << ": " << *N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i]->clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- opt::at(output, row, col) =
- mln::opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- template <typename I>
- void save(const I& is, const std::string& name = "")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- switch (is(p)) {
- case 1: // R
- temp(p) = literal::red;
- break;
- case 2: // N
- temp(p) = literal::green;
- break;
- case 3: // A
- temp(p) = literal::blue;
- break;
- }
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter << ".ppm";
- io::ppm::save(my::enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
- template <typename I, typename Nbh>
- void fllt(const Image<I>& input_, const Neighborhood<Nbh>& nbh_)
- {
- const I& input = exact(input_);
- const Nbh& nbh = exact(nbh_);
-
- unsigned l = 0, l_max;
- mln_ch_value(I, unsigned) reg_min = labeling::regional_minima(input, nbh, l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- I u = mln::duplicate(input);
- mln_point(I) x0;
- mln_value(I) g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
-
-// image2d<unsigned char> is(input.domain());
-// const unsigned in_R = 1, in_N = 2, in_A = 3, in_O = 0;
-// data::fill(is, in_O);
-
- image2d<bool> deja_vu(input.domain());
- data::fill(deja_vu, false);
-
- typedef p_array<mln_point(I)> arr_t;
- arr_t* A = new arr_t();
- arr_t* N[256];
- for (unsigned i = 0; i < 256; ++i)
- N[i] = new arr_t();
- accu::bbox<mln_point(I)> N_box;
-
- unsigned n_step_1 = 0, n_step_3 = 0;
-
- // Step 1.
- step_1:
- {
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- }
-
- // Step 2.
- step_2:
- {
- // R <- 0 and N <- 0
- if (N_box.is_valid() != 0)
- {
-// data::fill((is | N_box.to_result()).rw(), in_O);
- data::fill(deja_vu | N_box.to_result()), false);
- }
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A->clear();
- A->append(x0);
-// is(x0) = in_A;
- deja_vu(x0) = true;
- }
-
- // Step 3.
- step_3:
- {
- ++n_step_3;
-
- mln_piter(arr_t) a(*A);
- mln_niter(Nbh) x(nbh, a);
-
-
-// my::save(is);
-
-
- // R <- R U A
- if (A->nsites() == 0)
- goto the_end;
-
-// for_all(a)
-// {
-// mln_invariant(is(a) == in_A);
-// is(a) = in_R;
-// }
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- {
-// if (u.has(x))
-// mln_invariant(is(x) != in_O || deja_vu(x) == false);
-
- //if (u.has(x) && is(x) == in_O)
- if (u.has(x) && !deja_vu(x))
- {
- N[u(x)]->append(x);
-// is(x) = in_N;
- N_box.take(x);
- deja_vu(x) = true;
- }
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN);
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (g < gN)
- {
- g = gN;
- // FIXME: DO the hole thing.
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
-// mln_piter(arr_t) a(A);
-// for_all(a)
-// {
-// mln_invariant(is(a) == in_N);
-// is(a) = in_A;
-// // N_box is not re-computed so that we save time;
-// // N_box is always growing while looping from step 3.
-// }
- N[g]->clear();
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
-// mln_piter(arr_t) a(A);
-// for_all(a)
-// {
-// mln_invariant(is(a) == in_N);
-// is(a) = in_A;
-// }
- N[g]->clear();
- goto step_3;
- }
- // c)
- else
- {
- // Here deja_vu is (R U N U A)
- // we only want R
-
- // yet A is empty (cause included in R)
- // so this test is ok: mln_invariant((is | in_A).nsites() == 0);
-
- for (unsigned i = 0; i < 256; ++i)
- if (N[i]->nsites())
- data::fill(deja_vu | *N[i]), false);
-
-// mln_invariant(deja_vu == ((pw::value(is) == pw::cst(in_R)) | input.domain()));
-
-// mln_piter(I) r(N_box);
-// for_all(r)
-// if (is(r) == in_R)
-// u(r) = g;
-
- mln_piter(I) r(N_box);
- for_all(r)
- if (deja_vu(r))
- u(r) = g;
-
- goto step_1;
- }
- }
-
- the_end:
- std::cout << n_step_1 << ' ' << n_step_3 <<
std::endl;
-
- }
-
- } // end of namespace mln::my
-
-} // end of namespace mln
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 2)
- {
- std::cerr << "usage: " << argv[0] << "
filename" << std::endl;
- return 1;
- }
-
- using namespace mln;
- using value::int_u8;
-
- image2d<int_u8> lena;
- io::pgm::load(lena, argv[1]);
-
- my::fllt(lena, c4());
- io::pgm::save(lena, "./out.pgm");
-
-}
Index: geraud/fllt/fllt.svg.6.cc
--- geraud/fllt/fllt.svg.6.cc (revision 3151)
+++ geraud/fllt/fllt.svg.6.cc (working copy)
@@ -1,1136 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <iomanip>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-#include <mln/core/site_set/p_queue_fast.hh>
-#include <mln/core/image/cast_image.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/level/compare.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/labeling/regional_maxima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/util/tree.hh>
-#include <mln/util/branch_iter_ind.hh>
-#include <mln/util/branch_iter.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
- namespace my
- {
-
-# define fllt_tree(P, V) mln::util::tree< fllt_node_elt<P, V> >
-# define fllt_node(P, V) mln::util::tree_node< fllt_node_elt<P, V> >
-# define fllt_tree_ptr(P, V) mln::util::tree< fllt_node_elt<P, V>* >
-# define fllt_node_ptr(P, V) mln::util::tree_node< fllt_node_elt<P, V>* >
-# define fllt_branch(P, V) mln::util::branch< fllt_node_elt<P, V> >
-# define fllt_branch_iter_ind(P, V) mln::util::branch_iter_ind< fllt_node_elt<P,
V> >
-# define fllt_branch_iter(P, V) mln::util::branch_iter< fllt_node_elt<P, V>
>
-
-# define stl_to_mln_iter(T) stl_iterator< T >
-
- //Fwd declarations.
- template <typename V> struct lower;
- template <typename V> struct upper;
-
- template <typename P, typename V>
- struct fllt_node_elt
- {
- V value;
- p_array<P> points;
- p_array<P> holes;
- std::vector<fllt_node(P, V)*> hole_shapes;
- /// Tell if his parent if brighter or not. Nb : if the parent
- /// if brighter, the node come from the lower level set
- bool brighter;
- unsigned nsites;
- bool tagged;
- bool set_id;
-
- fllt_node_elt(bool set_id) : nsites(0), tagged(false), set_id(set_id) {}
- };
-
-
- template <typename C>
- class stl_iterator
- {
- public:
- stl_iterator(C& c) : container_(c) {}
- void start(){ it_ = container_.begin(); }
- void next() { it_++; }
- bool is_valid() const{ return it_ != container_.end(); }
- typename C::value_type& operator*() { return *it_; }
-
- private:
- C& container_;
- typename C::iterator it_;
- };
-
- template <typename N_t, typename G, typename Set>
- void update_gN(const N_t& N, G& gN);
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, lower<V>)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, upper<V>)
- {
- for (int g = 255; g >= 0; --g)
- {
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- }
- // if N is empty, gN is the min value.
- gN = 0;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i]->nsites() == 0)
- continue;
- std::cout << i << ": " << *N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i]->clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- opt::at(output, row, col) = opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- void save_u(const image2d<value::int_u8>& u,
- const image2d<int>& is,
- box2d R_box,
- int in_R,
- int in_N)
- {
- static int id = 0;
- std::stringstream filename;
- filename << "fllt_trace_" << std::setw(5) <<
std::setfill('0')
- << std::right << id++ << ".ppm";
-
- image2d<value::int_u8> out = duplicate(cast_image<value::int_u8>(is));
-
- mln_assertion(R_box.nsites() > 0);
- mln_piter_(box2d) p(R_box);
- for_all(p)
- if (is(p) == in_R)
- out(p) = 255;
- else if (is(p) == in_N)
- out(p) = 127;
- // else if (is(p) == in_N)
- // out(p) = literal::green;
-
- io::pgm::save(out, filename.str());
- //io::pgm::save(out, filename.str());
- }
-
- template <typename I>
- void save(const I& is, unsigned in_N, unsigned in_R, const std::string& name
= "")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- if (is(p) == in_R)
- temp(p) = literal::red;
- else if (is(p) == in_N) // N
- temp(p) = literal::green;
- else if (is(p) < in_N)
- temp(p) = literal::blue;
- else
- temp(p) = literal::white;
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter << ".ppm";
- io::ppm::save(my::enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
-
- template <typename I, typename P, typename V, typename Set>
- void blob(const Set&,
- const I& is,
- p_array<mln_point(I)>* N[256],
- unsigned in_N,
- const box2d& N_box,
- fllt_node(P, V)* current_cc)
- {
- typedef p_array<mln_point(I)> arr_t;
-
-// std::cout << ">>>>>>>enter blob. " <<
current_cc << std::endl;
- bool flower = true;
- unsigned ncc = 0;
- static image2d<unsigned> is_labeled(is.domain());
- static unsigned label = 0;
-
- if (label == 0)
- {
- data::fill(is_labeled, 0);
- label++;
- }
-
- P cur;
- mln_niter(neighb2d) n(Set::bdr_nbh()/*c8()*/, cur);
- p_queue_fast<P> qu;
- p_array<P>& holes = current_cc->elt().holes;
-
- mln_piter(I) p(N_box);
- for_all(p)
- if (is(p) == in_N)
- break;
-
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
-
-
-
- for (unsigned i = 0; i < 256; ++i)
- //for (int i = 255; i >= 0; --i)
- {
- mln_piter(arr_t) p(*N[i]);
- for_all(p)
- {
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
- }
- }
-
- ++label;
-
- // if (holes.size() == 2)
- // std::cout << holes[0] << holes[1] << std::endl;
- // std::cout << " <<<<<<<exiting blob."
<< std::endl;
- }
-
-// template <typename I, typename V>
-// void blob(const I& is,
-// p_array<mln_point(I)>* N[256],
-// unsigned in_N,
-// const box2d& N_box,
-// fllt_node(mln_point(I), V)* current_cc)
-// {
-// typedef p_array<mln_point(I)> arr_t;
-
-// // std::cout << ">>>>>>>enter blob. "
<< current_cc << std::endl;
-// bool flower = true;
-// unsigned ncc = 0;
-// static image2d<unsigned> is_labeled(is.domain());
-// static unsigned label = 0;
-
-// if (label == 0)
-// {
-// data::fill(is_labeled, 0);
-// label++;
-// }
-
-// typedef mln_psite(I) P;
-// P cur;
-// mln_niter(neighb2d) n(c8(), cur);
-// p_queue_fast<P> qu;
-// p_array<P>& holes = current_cc->elt().holes;
-
-// mln_piter(I) p(N_box);
-// for_all(p)
-// if (is(p) == in_N)
-// break;
-
-// mln_assertion(is(p) == in_N);
-// if (is_labeled(p) != label)
-// {
-// if (flower == false)
-// holes.append(p);
-// else
-// flower = false;
-// qu.push(p);
-// is_labeled(p) = label;
-// do
-// {
-// cur = qu.front();
-// qu.pop();
-// for_all(n) if (is.has(n))
-// if (is(n) == in_N && is_labeled(n) != label)
-// {
-// qu.push(n);
-// is_labeled(n) = label;
-// }
-// }
-// while (! qu.is_empty());
-// }
-
-
-
-// for (unsigned i = 0; i < 256; ++i)
-// //for (int i = 255; i >= 0; --i)
-// {
-// mln_piter(arr_t) p(*N[i]);
-// for_all(p)
-// {
-// mln_assertion(is(p) == in_N);
-// if (is_labeled(p) != label)
-// {
-// if (flower == false)
-// holes.append(p);
-// else
-// flower = false;
-// qu.push(p);
-// is_labeled(p) = label;
-// do
-// {
-// cur = qu.front();
-// qu.pop();
-// for_all(n) if (is.has(n))
-// if (is(n) == in_N && is_labeled(n) != label)
-// {
-// qu.push(n);
-// is_labeled(n) = label;
-// }
-// }
-// while (! qu.is_empty());
-// }
-// }
-// }
-
-// ++label;
-
-// // if (holes.size() == 2)
-// // std::cout << holes[0] << holes[1] << std::endl;
-// // std::cout << " <<<<<<<exiting
blob." << std::endl;
-// }
-
- template <typename P, typename V>
- void
- move_A_to_R(p_array<P>& A,
- image2d<int>& deja_vu,
- fllt_node(P, V)* current_cc,
- image2d< fllt_node(P, V)* >& smallest_shapes,
- int in_R,
- int in_N,
- const V& g,
- unsigned& n_comps)
- {
- typedef p_array<P> arr_t;
-
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(deja_vu(a) == in_N);
- mln_invariant(smallest_shapes(a) != current_cc);
-
- deja_vu(a) = in_R;
- current_cc->elt().nsites++;
- if (!smallest_shapes(a))
- {
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- if (!smallest_shapes(a)->parent())
- if (smallest_shapes(a)->elt().value == g)
- {
- fllt_node(P, V)* to_delete = smallest_shapes(a);
-
- mln_piter(arr_t) p(smallest_shapes(a)->elt().points);
- // Todo optimization here.
- for_all(p)
- smallest_shapes(p) = 0;
-
- while(!to_delete->children().empty())
- current_cc->add_child(*to_delete->children().begin());
- delete to_delete;
- n_comps--;
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- smallest_shapes(a)->set_parent(current_cc);
- // N_box is not re-computed so that we save time;
- // N_box is always growing while looping from step 3.
- }
- }
-
- // LOWER LEVEL SET : region = c4, border = c8
- template <typename V>
- struct lower
- {
- typedef upper<V> opposite;
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- {
- return u < v;
- }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>& nbh,
L& nlabels)
- {
- return labeling::regional_minima(input, nbh, nlabels);
- }
-
- static const bool parent_is_brighter = true;
- static const bool id = false;
-
- static const neighb2d& bdr_nbh() { return c8(); }
- static const neighb2d& reg_nbh() { return c4(); }
- };
-
-
- // UPPER LEVEL SET : region = c8, border = c4
- template <typename V>
- struct upper
- {
- typedef lower<V> opposite;
-
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- { return u > v; }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>& nbh,
L& nlabels)
- { return labeling::regional_maxima(input, nbh, nlabels); }
-
- static const bool parent_is_brighter = false;
- static const bool id = true;
-
- static const neighb2d& bdr_nbh() { return c4(); }
- static const neighb2d& reg_nbh() { return c8(); }
- };
-
- template <typename I, typename Set>
- fllt_tree(mln_point(I), mln_value(I))&
- level_set(const Image<I>& input_,
- image2d< fllt_node(mln_point(I), mln_value(I))* >& smallest_shapes)
- {
-
- typedef mln_point(I) P;
- typedef mln_value(I) V;
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
-
- const I& input = exact(input_);
-
- mln_assertion(input.domain() == smallest_shapes.domain());
-
- unsigned l = 0, l_max = 0;
- mln_ch_value(I, unsigned) reg_min = Set::regional_extremum(input, Set::reg_nbh(),
l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- I u = mln::duplicate(input);
- P x0;
- V g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
- data::fill(smallest_shapes, 0);
- node_type* current_cc;
-
- unsigned in_N = 1, in_R = 2;
-
- image2d<int> deja_vu(input.domain().to_larger(1));
- data::fill(deja_vu, 0);
-
- typedef p_array<P> arr_t;
- arr_t* A = new arr_t();
- arr_t* N[256];
- for (unsigned i = 0; i < 256; ++i)
- N[i] = new arr_t();
- accu::bbox<P> N_box;
-
- bool touch_border_of_image = false;
- unsigned n_step_1 = 0, n_step_3 = 0, n_comps = 0, n_holes = 0;
-
- // Step 1.
- step_1:
- {
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- ++n_comps;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- touch_border_of_image = false;
-
- }
-
- // Step 2.
- step_2:
- {
- in_N += 2;
- in_R = in_N + 1;
- // R <- 0 and N <- 0
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A->clear();
- A->append(x0);
- N_box.take(x0);
-
- deja_vu(x0) = in_R;
- smallest_shapes(x0) = current_cc;
- current_cc->elt().points.append(x0);
- current_cc->elt().nsites++;
-
- }
-
- // Step 3.
- step_3:
- {
-// save_u(u, deja_vu, N_box, in_R, in_N);
- ++n_step_3;
-
- mln_piter(arr_t) a(*A);
- mln_niter(neighb2d) x(Set::reg_nbh(), a);
-
-
- // R <- R U A
- if (A->nsites() == 0)
- goto the_end;
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- {
- if (deja_vu.has(x) && deja_vu(x) < in_N)
- {
- if (u.has(x))
- {
- N[u(x)]->append(x);
- N_box.take(x);
- }
- else
- touch_border_of_image = true;
- deja_vu(x) = in_N;
- }
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN, Set());
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (Set::compare(g, gN))
- {
- g = gN;
-
- ++n_comps;
-
- if (touch_border_of_image)
- blob(Set(), deja_vu, N, in_N, N_box.to_result().to_larger(1), current_cc);
- else
- blob(Set(), deja_vu, N, in_N, N_box, current_cc);
-
- n_holes += current_cc->elt().holes.nsites();
-
- node_type* child = current_cc;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- child->set_parent(current_cc);
-
-
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // c)
- else
- {
- // FIXME: IDEA: this change might be performed while R is constructed(?)
- mln_piter(I) r(N_box);
- for_all(r)
- if (deja_vu(r) == in_R)
- u(r) = g;
-
- goto step_1;
- }
- }
-
- the_end:
- std::cout << "l_max " << l_max << " "
<< n_step_1 << ' ' << n_step_3 << std::endl;
- std::cout << "n comps = " << n_comps << " n holes
= " << n_holes << std::endl;
-
- return *new tree_type(current_cc);
- }
-
- // F is the set in which we get the node.
- template <typename P, typename V, typename F>
- fllt_node(P, V)*
- find_hole(fllt_node(P, V)& node,
- const P p,
- const image2d<fllt_node(P, V)*>& other_reg)
- {
- fllt_node(P, V)* s = other_reg(p);
- mln_assertion(s);
- while (s->parent() && F::compare(s->parent()->elt().value,
node.elt().value))
- {
- mln_assertion(s);
- s = s->parent();
- mln_assertion(s);
- }
-// std::cout << " [Find the hole] of " << p
-// << " from " << &node
-// << " return " << s
-// << std::endl;
- return s;
- }
-
- template <typename P, typename V>
- bool shape_is_included(fllt_node(P, V)* A,
- fllt_node(P, V)* B)
- {
- return A->parent() == B || A == B;
- }
-
- template <typename P, typename V>
- void find_all_holes(fllt_tree(P, V)& lower_tree,
- fllt_tree(P, V)& upper_tree,
- const image2d<fllt_node(P, V)*>& low_reg,
- const image2d<fllt_node(P, V)*>& upp_reg)
- {
- typedef p_array<P> arr_t;
- typedef fllt_node(P, V) node_type;
-
- {
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,upper<V> >(node, P(hole),
upp_reg));
- }
- }
-
- {
- fllt_branch_iter_ind(P, V) node_(upper_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,lower<V> >(node, P(hole),
low_reg));
- }
- }
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- merge_trees(fllt_tree(mln_point(I), mln_value(I))& lower_tree,
- fllt_tree(mln_point(I), mln_value(I))& upper_tree,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& low_reg,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& upp_reg,
- const Image<I>& input_)
- {
-
- const I& input = exact(input_);
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
- typedef p_array<P> arr_t;
-
-
- find_all_holes(lower_tree, upper_tree, low_reg, upp_reg);
- std::vector<node_type*> to_fill;
-
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != lower<V>::id)
- continue;
-
- // std::cout << "Fill " << &node << std::endl;
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- // std::cout << "hole : " << hole << "
" << hole->elt().points << " " << std::endl;
- // std::cout << "child hole : " << child_hole
<< " " << child_hole->elt().points << std::endl;
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
- if (!child_has_bigger_hole)
- {
- // // std::cout << "move " << hole << " as
child of " << &node << std::endl;
- node.add_child(hole);
- to_fill.push_back(hole);
- }
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- for(typename std::vector<node_type*>::iterator node_ = to_fill.begin();
- node_ != to_fill.end();
- node_++)
- {
- node_type& node = **node_;
-
- fllt_branch_iter_ind(P, V) node_(fllt_branch(P, V)(upper_tree, node));
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != upper<V>::id)
- continue;
-
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- //if (hole->elt().points <= child_hole->elt().points)
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
-
- if (!child_has_bigger_hole)
- node.add_child(hole);
-
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- }
-
- return lower_tree;
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- fllt(const Image<I>& input_)
- {
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- const I& input = exact(input_);
-
- fllt_tree(P, V) upper_tree;
- fllt_tree(P, V) lower_tree;
- image2d<fllt_node(P, V)*> low_reg(input.domain());
- image2d<fllt_node(P, V)*> upp_reg(input.domain());
-
- std::cout << "1/ Compute the lower level
set.----------------------------------------" << std::endl;
- lower_tree = level_set<I, lower<V> >(input, low_reg);
- //draw_tree(input, lower_tree);
-
- std::cout << "2/ Compute the upper level
set.----------------------------------------" << std::endl;
- upper_tree = level_set<I, upper<V> >(input, upp_reg);
- //draw_tree(input, upper_tree);
-
- std::cout << "3/
Merge.---------------------------------------------------------------" <<
std::endl;
- fllt_tree(P, V) result_tree = merge_trees(lower_tree, upper_tree, low_reg, upp_reg,
input);
-
- return result_tree;
- }
-
- template <typename P, typename V>
- void
- draw_tree(const image2d<V>& ima,
- fllt_tree(P, V)& tree)
- {
- p_array<P> tmp;
-
- fllt_branch_iter_ind(P, V) p(tree.main_branch());
- for_all(p)
- {
- std::cout << "region mere : " << (*p).parent() <<
std::endl;
- std::cout << " ^" << std::endl;
- std::cout << " |" << std::endl;
- std::cout << "region : " << &*p
- << " value = " << (*p).elt().value << std::endl
- << " from " << ((*p).elt().set_id == lower<V>::id ?
"lower" : "upper") << " level set." <<
std::endl
- << " nsites = " << (*p).elt().nsites << std::endl
- << " holes = " << (*p).elt().holes << std::endl;
-
- std::cout << std::endl;
-
- tmp.append((*p).elt().points);
-
- fllt_branch_iter_ind(P, V) n(fllt_branch(P, V)(tree, *p));
- for_all(n)
- tmp.append((*n).elt().points);
-
- if ((*p).elt().points.nsites() > 0)
- debug::println(ima | tmp);
- tmp.clear();
-
- std::cout << std::endl;
- }
- }
-
-
- template <typename P, typename V, typename I>
- unsigned
- compute_area_rec(fllt_node(P, V)* node, I& ima)
- {
-
- if (!node)
- return 0;
-
- int area = 0;
-
- for (int i = 0; i < node->children().size();i++)
- area += compute_area_rec(node->children()[i], ima);
-
- mln_piter(p_array<P>) p(node->elt().points);
- for_all(p)
- if (!ima(P(p)))
- {
- ++area;
- ima(p) = true;
- }
-
- node->elt().nsites = area;
- return area;
- }
-
- template <typename P, typename V, typename I>
- void
- compute_area(const Image<I>& input_, fllt_tree(P, V)& tree)
- {
- const I& input = exact(input_);
-
- image2d<bool> ima(input.domain());
- data::fill(ima, false);
- compute_area_rec(tree.root(), ima);
- }
-
- void draw_shape(image2d<value::int_u8>& output,
- fllt_node(point2d, value::int_u8)* node)
- {
- typedef point2d P ;
- typedef value::int_u8 V;
-
- fllt_tree(P, V) subtree(node);
- fllt_branch_iter_ind(P, V) s(fllt_branch(P, V)(subtree, *node));
- for_all(s)
- data::fill(output | (*s).elt().points), (*s).elt().value);
- }
-
- void area_filter(image2d<value::int_u8>& output,
- fllt_node(point2d, value::int_u8)* node,
- unsigned min_area,
- unsigned max_area,
- value::int_u8 bg)
- {
- typedef point2d P ;
- typedef value::int_u8 V;
-
- data::fill(output, bg);
- fllt_tree(P, V) subtree(node);
- fllt_branch_iter_ind(P, V) s(fllt_branch(P, V)(subtree, *node));
- for_all(s)
- if ((*s).elt().nsites > min_area && (*s).elt().nsites < max_area)
- draw_shape(output, &*s);
- }
-
- void area_filter_min(image2d<value::int_u8>& output,
- fllt_node(point2d, value::int_u8)* node,
- unsigned min_area,
- value::int_u8 g,
- unsigned accu)
- {
-// if ((*node).elt().nsites >= min_area)
- if (accu > min_area)
- {
- accu = 0;
- g = (*node).elt().value;
- }
-
- accu += (*node).elt().nsites;
- data::fill(output | (*node).elt().points), g);
-
- for (int i = 0; i < node->children().size();i++)
- area_filter_min(output, node->children()[i], min_area, g, accu);
- }
-
- } // end of namespace mln::my
-
-} // end of namespace mln
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using namespace mln::my;
- using value::int_u8;
-
- typedef fllt_tree(point2d, int_u8) tree_type;
-
-
-
-// if (argc != 2)
-// {
-// std::cerr << "usage: " << argv[0] << "
filename" << std::endl;
-// return 1;
-// }
-
- image2d<int_u8> lena;
- io::pgm::load(lena, argv[1]);
-
-
-// int vs[8][9] = { {0,0,0,0,0,0,0,0,0},
-// {0,0,0,0,0,0,0,0,0},
-// {0,1,1,1,1,1,1,1,0},
-// {0,1,0,0,1,3,3,1,0},
-// {0,1,0,0,1,3,4,1,0},
-// {0,1,0,0,1,3,3,1,0},
-// {0,1,1,1,1,1,1,1,0},
-// {0,0,0,0,0,0,0,0,0} };
-
-
-
-// int vs[8][9] = { {6,6,6,6,6,6,6,6,6},
-// {6,6,6,6,6,6,6,6,6},
-// {6,5,5,5,5,5,5,5,6},
-// {6,5,6,6,5,3,3,5,6},
-// {6,5,6,6,5,3,0,5,6},
-// {6,5,6,6,5,3,3,5,6},
-// {6,5,5,5,5,5,5,5,6},
-// {6,6,6,6,6,6,6,6,6} };
-
-// int vs[8][9] = { {2,2,2,2,2,2,2,2,2},
-// {2,2,2,2,2,2,2,2,2},
-// {2,1,1,1,1,1,1,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,1,1,1,1,1,1,2},
-// {2,2,2,2,2,2,2,2,2} };
-
-
- int vs[8][9] = { {2,2,2,2,2,2,2,2,2},
- {2,2,2,2,2,2,2,2,2},
- {2,1,1,1,1,1,1,1,2},
- {2,1,2,2,1,0,0,1,2},
- {2,1,2,2,1,0,4,1,2},
- {2,1,2,2,1,0,0,1,2},
- {2,1,1,1,1,1,1,1,2},
- {2,2,2,2,2,2,2,2,2} };
-
-// int vs[10][13] = { {1,1,1,1, 1,1,1,1, 1,1,1,1,1},
-// {1,2,2,2,2,2,2,2,2,2,2,2,1},
-// {1,2,2,2,2,2,2,2,2,2,2,2,1},
-// {1,2,2,2,3,3,3,3,3,3,3,2,1},
-// {1,2,2,2,3,3,3,2,2,2,3,2,1},
-// {1,2,2,2,3,4,3,2,4,4,3,2,1},
-
-// {1,2,2,2,3,3,3,2,2,2,3,2,1},
-// {1,2,2,2,3,3,3,3,3,3,3,2,1},
-// {1,2,2,2,2,2,2,2,2,2,2,2,1},
-// {1,1,1,1,1,1,1,1,1,1,1,1,1}};
-
-
-// image2d<int> lena_(make::image2d(vs));
-// image2d<int_u8> lena(lena_.domain());
-// data::fill(lena, lena_);
-
- tree_type tree = my::fllt(lena);
- compute_area(lena, tree);
-
- image2d<value::int_u8> output (lena.domain ());
-// area_filter_min(output, tree.root(), atoi(argv[2]), 0, 0);
- area_filter(output, tree.root(), atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
- io::pgm::save(output, "out.pgm");
-
- // draw_tree(lena, tree);
-}
Index: geraud/fllt/connected_filters/area_filter.cc
--- geraud/fllt/connected_filters/area_filter.cc (revision 3151)
+++ geraud/fllt/connected_filters/area_filter.cc (working copy)
@@ -1,26 +0,0 @@
-#include "fllt.svg.7.hh"
-#include "fllt_tree_to_image.hh"
-#include "area_filter.hh"
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- typedef fllt_tree(point2d, int_u8) tree_type;
-
- if (argc != 4)
- {
- std::cerr << "usage: " << argv[0] << " input
min_area output" << std::endl;
- return 1;
- }
-
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[1]);
-
- tree_type tree = fllt(ima);
- compute_area(ima, tree);
-
- area_filter_min(tree.root(), atoi(argv[2]));
- io::pgm::save(fllt_tree_to_image(ima, tree), argv[3]);
-}
Index: geraud/fllt/connected_filters/canonize_tree.hh
--- geraud/fllt/connected_filters/canonize_tree.hh (revision 3151)
+++ geraud/fllt/connected_filters/canonize_tree.hh (working copy)
@@ -1,51 +0,0 @@
-#ifndef MLN_FLLT_CANONIZE_TREE_HH
-# define MLN_FLLT_CANONIZE_TREE_HH
-
-#include "fllt.svg.7.hh"
-#include "fllt_tree_to_image.hh"
-#include "area_filter.hh"
-
-namespace mln
-{
-
- template <typename P, typename V>
- void
- merge_node(fllt_node(P, V)* src, fllt_node(P, V)* dest)
- {
- for (typename std::vector<fllt_node(P, V)* >::iterator it =
src->parent()->children().begin();
- it != src->parent()->children().end(); ++it)
- if ((*it) == src)
- {
- src->parent()->children().erase(it);
- break;
- }
-
- dest->elt().points.append(src->elt().points);
- while(!src->children().empty())
- dest->add_child(*src->children().begin());
- delete src;
- }
-
- template <typename P, typename V>
- bool
- canonize_tree(fllt_node(P, V)* node)
- {
- if (node->parent() && node->parent()->elt().value ==
node->elt().value)
- {
- merge_node(node, node->parent());
- return true;
- }
-
- bool change = true;
- while (change)
- {
- change = false;
- for (int i = 0; !change && i < node->children().size(); i++)
- change = canonize_tree(node->children()[i]);
- }
- return false;
- }
-
-}
-
-#endif // ! MLN_FLLT_CANONIZE_TREE_HH
Index: geraud/fllt/connected_filters/pseudo_flat_zones.cc
--- geraud/fllt/connected_filters/pseudo_flat_zones.cc (revision 3151)
+++ geraud/fllt/connected_filters/pseudo_flat_zones.cc (working copy)
@@ -1,44 +0,0 @@
-#include "fllt.svg.7.hh"
-#include "fllt_tree_to_image.hh"
-#include "area_filter.hh"
-#include "canonize_tree.hh"
-
-namespace mln
-{
- template <typename P, typename V>
- void flatten(fllt_node(P, V)* node,
- unsigned min_contrast)
- {
- for (int i = 0; i < node->children().size(); i++)
- {
- if (abs(node->children()[i]->elt().value - node->elt().value) <
min_contrast)
- node->children()[i]->elt().value = node->elt().value;
- flatten(node->children()[i], min_contrast);
- }
- }
-}
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- typedef fllt_tree(point2d, int_u8) tree_type;
-
- if (argc != 5)
- {
- std::cerr << "usage: " << argv[0] << " input
min_area min_contrast output" << std::endl;
- return 1;
- }
-
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[1]);
-
- tree_type tree = fllt(ima);
- compute_area(ima, tree);
-
- area_filter_min(tree.root(), atoi(argv[2]));
- canonize_tree(tree.root());
- flatten(tree.root(), atoi(argv[3]));
- io::pgm::save(fllt_tree_to_image(ima, tree), argv[4]);
-}
Index: geraud/fllt/connected_filters/area_filter.hh
--- geraud/fllt/connected_filters/area_filter.hh (revision 3151)
+++ geraud/fllt/connected_filters/area_filter.hh (working copy)
@@ -1,69 +0,0 @@
-#ifndef MLN_FLLT_AREA_FILTER_HH
-# define MLN_FLLT_AREA_FILTER_HH
-
-#include "fllt.svg.7.hh"
-
-namespace mln
-{
-
- template <typename P, typename V, typename I>
- unsigned
- compute_area_rec(fllt_node(P, V)* node, I& ima)
- {
-
- if (!node)
- return 0;
-
- int area = 0;
-
- for (int i = 0; i < node->children().size();i++)
- area += compute_area_rec(node->children()[i], ima);
-
- mln_piter(p_array<P>) p(node->elt().points);
- for_all(p)
- if (!ima(P(p)))
- {
- ++area;
- ima(p) = true;
- }
-
- node->elt().nsites = area;
- return area;
- }
-
- template <typename P, typename V, typename I>
- void
- compute_area(const Image<I>& input_, fllt_tree(P, V)& tree)
- {
- const I& input = exact(input_);
-
- image2d<bool> ima(input.domain());
- data::fill(ima, false);
- compute_area_rec(tree.root(), ima);
- }
-
- void area_filter_min_(fllt_node(point2d, value::int_u8)* node,
- unsigned min_area,
- value::int_u8 g)
- {
- unsigned area = (*node).elt().nsites;
- if (area > min_area)
- g = (*node).elt().value;
-
- node->elt().value = g;
-
- for (int i = 0; i < node->children().size(); i++)
- area_filter_min_(node->children()[i], min_area, g);
- }
-
- template <typename P, typename V>
- void area_filter_min(fllt_node(P, V)* node,
- unsigned min_area)
- {
- area_filter_min_(node, min_area, (*node).elt().value);
- }
-
-}
-
-
-#endif // ! MLN_FLLT_AREA_FILTER_HH
Index: geraud/fllt/fllt_test.hh
--- geraud/fllt/fllt_test.hh (revision 3151)
+++ geraud/fllt/fllt_test.hh (working copy)
@@ -1,874 +0,0 @@
-// Copyright (C) 2008 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.
-
-#include <iomanip>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-#include <mln/core/site_set/p_queue_fast.hh>
-#include <mln/core/image/cast_image.hh>
-
-#include <mln/opt/at.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/level/compare.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/labeling/regional_maxima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/util/tree.hh>
-#include <mln/util/branch_iter_ind.hh>
-#include <mln/util/branch_iter.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
-# define fllt_tree(P, V) mln::util::tree< fllt_node_elt<P, V> >
-# define fllt_node(P, V) mln::util::tree_node< fllt_node_elt<P, V> >
-# define fllt_tree_ptr(P, V) mln::util::tree< fllt_node_elt<P, V>* >
-# define fllt_node_ptr(P, V) mln::util::tree_node< fllt_node_elt<P, V>* >
-# define fllt_branch(P, V) mln::util::branch< fllt_node_elt<P, V> >
-# define fllt_branch_iter_ind(P, V) mln::util::branch_iter_ind< fllt_node_elt<P,
V> >
-# define fllt_branch_iter(P, V) mln::util::branch_iter< fllt_node_elt<P, V>
>
-
-# define stl_to_mln_iter(T) stl_iterator< T >
-
- //Fwd declarations.
- template <typename V> struct lower;
- template <typename V> struct upper;
-
- template <typename P, typename V>
- struct fllt_node_elt
- {
- V value;
- p_array<P> points;
- p_array<P> holes;
- std::vector<fllt_node(P, V)*> hole_shapes;
- /// Tell if his parent if brighter or not. Nb : if the parent
- /// if brighter, the node come from the lower level set
- bool brighter;
- unsigned nsites;
- bool tagged;
- bool set_id;
- char id;
-
- fllt_node_elt(bool set_id) : nsites(0), tagged(false), set_id(set_id)
- {
- static char id_ = 'A';
-
- id = id_;
- id_++;
- }
- };
-
-
- template <typename C>
- class stl_iterator
- {
- public:
- stl_iterator(C& c) : container_(c) {}
- void start(){ it_ = container_.begin(); }
- void next() { it_++; }
- bool is_valid() const{ return it_ != container_.end(); }
- typename C::value_type& operator*() { return *it_; }
-
- private:
- C& container_;
- typename C::iterator it_;
- };
-
- template <typename N_t, typename G, typename Set>
- void update_gN(const N_t& N, G& gN);
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, lower<V>)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, upper<V>)
- {
- for (int g = 255; g >= 0; --g)
- {
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- }
- // if N is empty, gN is the min value.
- gN = 0;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i]->nsites() == 0)
- continue;
- std::cout << i << ": " << *N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i]->clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- opt::at(output, row, col) = opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- template <typename P>
- void save_u(const image2d<value::int_u8>& u,
- const image2d<int>& is,
- box2d R_box,
- int in_R,
- int in_N,
- p_array<P>* N[256])
- {
- static int id = 0;
- std::stringstream filename;
- filename << "fllt_trace_" << std::setw(5) <<
std::setfill('0')
- << std::right << id++ << ".ppm";
-
- image2d<value::int_u8> out = duplicate(cast_image<value::int_u8>(is));
-
-
- mln_assertion(R_box.nsites() > 0);
- mln_piter_(box2d) p(R_box);
- for_all(p)
- if (is(p) == in_R)
- out(p) = 255;
- else if (is(p) == in_N)
- out(p) = 100;
- // else if (is(p) == in_N)
- // out(p) = literal::green;
-
- for (unsigned i = 0; i < 256; ++i)
- {
- mln_piter(p_array<P>) p(*N[i]);
- for_all(p)
- out(p) = 100;
- }
- io::pgm::save(out, filename.str());
- //io::pgm::save(out, filename.str());
- }
-
- template <typename I>
- void save(const I& is, unsigned in_N, unsigned in_R, const std::string& name =
"")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- if (is(p) == in_R)
- temp(p) = literal::red;
- else if (is(p) == in_N) // N
- temp(p) = literal::green;
- else if (is(p) < in_N)
- temp(p) = literal::blue;
- else
- temp(p) = literal::white;
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter <<
".ppm";
- io::ppm::save(enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
- template <typename I, typename P, typename V, typename Set>
- void blob(const Set&,
- const I& is,
- p_array<mln_point(I)>* N[256],
- unsigned in_N,
- const box2d& N_box,
- fllt_node(P, V)* current_cc)
- {
- typedef p_array<mln_point(I)> arr_t;
-
- // std::cout << ">>>>>>>enter blob. "
<< current_cc << std::endl;
- bool flower = true;
- unsigned ncc = 0;
- static image2d<unsigned> is_labeled(is.domain());
- static unsigned label = 0;
-
- if (label == 0)
- {
- data::fill(is_labeled, 0);
- label++;
- }
-
- P cur;
- mln_niter(neighb2d) n(Set::bdr_nbh(), cur);
- p_queue_fast<P> qu;
- p_array<P>& holes = current_cc->elt().holes;
-
- mln_piter(I) p(N_box);
- for_all(p)
- if (is(p) == in_N)
- break;
-
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
-
-
-
- for (unsigned i = 0; i < 256; ++i)
- //for (int i = 255; i >= 0; --i)
- {
- mln_piter(arr_t) p(*N[i]);
- for_all(p)
- {
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
- }
- }
-
- ++label;
-
- // if (holes.size() == 2)
- // std::cout << holes[0] << holes[1] << std::endl;
- // std::cout << " <<<<<<<exiting blob."
<< std::endl;
- }
-
- template <typename P, typename V>
- void
- move_A_to_R(p_array<P>& A,
- image2d<int>& deja_vu,
- fllt_node(P, V)* current_cc,
- image2d< fllt_node(P, V)* >& smallest_shapes,
- int in_R,
- int in_N,
- const V& g,
- unsigned& n_comps)
- {
- typedef p_array<P> arr_t;
-
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(deja_vu(a) == in_N);
- mln_invariant(smallest_shapes(a) != current_cc);
- // if (smallest_shapes(a) == current_cc)
- // continue;
-
- deja_vu(a) = in_R;
- if (!smallest_shapes(a))
- {
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- if (!smallest_shapes(a)->parent())
- if (smallest_shapes(a)->elt().value == g)
- {
- fllt_node(P, V)* to_delete = smallest_shapes(a);
-
- // current_cc->elt().points.append(smallest_shapes(a)->elt().points);
- // A.append(smallest_shapes(a)->elt().points);
-
- mln_piter(arr_t) p(smallest_shapes(a)->elt().points);
- // Todo optimization here.
- for_all(p)
- {
- smallest_shapes(p) = 0;
- // deja_vu(p) = in_R;
- //smallest_shapes(p) = current_cc;
- }
-
- while(!to_delete->children().empty())
- current_cc->add_child(*to_delete->children().begin());
- delete to_delete;
- n_comps--;
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- smallest_shapes(a)->set_parent(current_cc);
- }
- }
-
- // LOWER LEVEL SET : region = c4, border = c8
- template <typename V>
- struct lower
- {
- typedef upper<V> opposite;
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- {
- return u < v;
- }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>&
nbh, L& nlabels)
- {
- return labeling::regional_minima(input, nbh, nlabels);
- }
-
- static const bool parent_is_brighter = true;
- static const bool id = false;
-
- static const neighb2d& bdr_nbh() { return c8(); }
- static const neighb2d& reg_nbh() { return c4(); }
- };
-
-
- // UPPER LEVEL SET : region = c8, border = c4
- template <typename V>
- struct upper
- {
- typedef lower<V> opposite;
-
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- { return u > v; }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>&
nbh, L& nlabels)
- { return labeling::regional_maxima(input, nbh, nlabels); }
-
- static const bool parent_is_brighter = false;
- static const bool id = true;
-
- static const neighb2d& bdr_nbh() { return c4(); }
- static const neighb2d& reg_nbh() { return c8(); }
- };
-
-
- template <typename P, typename V, typename I>
- void print_child_parent(fllt_node(P, V)* child,
- fllt_node(P, V)* parent,
- const I& input)
- {
- typedef fllt_tree(P, V) tree_type;
-
- std::cout << "child : " << child->elt().id
- << " parent : " << parent->elt().id << std::endl;
- p_array<P> tmp;
-
- image2d<bool> ima(input.domain().to_larger(1));
- data::fill(ima, false);
-
- fllt_branch_iter(P, V) n(*child);
- for_all(n)
- data::fill((ima | (*n).elt().points).rw(), true);
-
- tmp.append((*n).elt().points);
-
- debug::println(ima);
- }
-
- template <typename I, typename Set>
- fllt_tree(mln_point(I), mln_value(I))&
- level_set(const Image<I>& input_,
- image2d< fllt_node(mln_point(I), mln_value(I))* >& smallest_shapes)
- {
-
- typedef mln_point(I) P;
- typedef mln_value(I) V;
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
-
- const I& input = exact(input_);
-
- mln_assertion(input.domain() == smallest_shapes.domain());
-
- unsigned l = 0, l_max = 0;
- mln_ch_value(I, unsigned) reg_min = Set::regional_extremum(input, Set::reg_nbh(),
l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- I u = mln::duplicate(input);
- P x0;
- V g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
- data::fill(smallest_shapes, 0);
- node_type* current_cc;
-
- unsigned in_N = 1, in_R = 2;
-
- image2d<int> deja_vu(input.domain().to_larger(1));
- data::fill(deja_vu, 0);
-
- typedef p_array<P> arr_t;
- arr_t* A = new arr_t();
- arr_t* N[256];
- for (unsigned i = 0; i < 256; ++i)
- N[i] = new arr_t();
- accu::bbox<P> N_box;
-
- bool touch_border_of_image = false;
- unsigned n_step_1 = 0, n_step_3 = 0, n_step_4c = 0, n_comps = 0, n_holes = 0;
-
- // Step 1.
- step_1:
- {
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- ++n_comps;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- touch_border_of_image = false;
-
- }
-
- // Step 2.
- step_2:
- {
- in_N += 2;
- in_R = in_N + 1;
- // R <- 0 and N <- 0
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A->clear();
- A->append(x0);
- N_box.take(x0);
-
- deja_vu(x0) = in_R;
- smallest_shapes(x0) = current_cc;
- current_cc->elt().points.append(x0);
- current_cc->elt().nsites++;
-
- }
-
- // Step 3.
- step_3:
- {
- ++n_step_3;
-
- mln_piter(arr_t) a(*A);
- mln_niter(neighb2d) x(Set::reg_nbh(), a);
-
-
- // R <- R U A
- if (A->nsites() == 0)
- goto the_end;
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- {
- if (deja_vu.has(x) && deja_vu(x) < in_N)
- {
- if (u.has(x))
- {
- N[u(x)]->append(x);
- N_box.take(x);
- }
- else
- touch_border_of_image = true;
- deja_vu(x) = in_N;
- }
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN, Set());
- save_u(u, deja_vu, N_box, in_R, in_N, N);
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (Set::compare(g, gN))
- {
- g = gN;
-
- ++n_comps;
-
- if (touch_border_of_image)
- blob(Set(), deja_vu, N, in_N, N_box.to_result().to_larger(1), current_cc);
- else
- blob(Set(), deja_vu, N, in_N, N_box, current_cc);
-
- n_holes += current_cc->elt().holes.nsites();
-
- node_type* child = current_cc;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- child->set_parent(current_cc);
-
- print_child_parent(child, current_cc, input);
-
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // c)
- else
- {
- // FIXME: IDEA: this change might be performed while R is constructed(?)
- n_step_4c++;
- mln_piter(I) r(N_box);
- for_all(r)
- if (deja_vu(r) == in_R)
- u(r) = g;
-
- goto step_1;
- }
- }
-
- the_end:
- std::cout << " n_step1 : " << n_step_1 << "
n_step3 : " << n_step_3 << " n_step4c : " << n_step_4c
<< std::endl;
- std::cout << "n comps = " << n_comps << " n holes =
" << n_holes << std::endl;
-
- return *new tree_type(current_cc);
- }
-
- // F is the set in which we get the node.
- template <typename P, typename V, typename F>
- fllt_node(P, V)*
- find_hole(fllt_node(P, V)& node,
- const P p,
- const image2d<fllt_node(P, V)*>& other_reg)
- {
- fllt_node(P, V)* s = other_reg(p);
- mln_assertion(s);
- while (s->parent() && F::compare(s->parent()->elt().value,
node.elt().value))
- {
- mln_assertion(s);
- s = s->parent();
- mln_assertion(s);
- }
- // std::cout << " [Find the hole] of " << p
- // << " from " << &node
- // << " return " << s
- // << std::endl;
- return s;
- }
-
- template <typename P, typename V>
- bool shape_is_included(fllt_node(P, V)* A,
- fllt_node(P, V)* B)
- {
- return A->parent() == B || A == B;
- }
-
- template <typename P, typename V>
- void find_all_holes(fllt_tree(P, V)& lower_tree,
- fllt_tree(P, V)& upper_tree,
- const image2d<fllt_node(P, V)*>& low_reg,
- const image2d<fllt_node(P, V)*>& upp_reg)
- {
- typedef p_array<P> arr_t;
- typedef fllt_node(P, V) node_type;
-
- {
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,upper<V> >(node, P(hole),
upp_reg));
- }
- }
-
- {
- fllt_branch_iter_ind(P, V) node_(upper_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,lower<V> >(node, P(hole),
low_reg));
- }
- }
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- merge_trees(fllt_tree(mln_point(I), mln_value(I))& lower_tree,
- fllt_tree(mln_point(I), mln_value(I))& upper_tree,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& low_reg,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& upp_reg,
- const Image<I>& input_)
- {
-
- const I& input = exact(input_);
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
- typedef p_array<P> arr_t;
-
-
- find_all_holes(lower_tree, upper_tree, low_reg, upp_reg);
- std::vector<node_type*> to_fill;
-
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != lower<V>::id)
- continue;
-
- // std::cout << "Fill " << &node << std::endl;
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- // std::cout << "hole : " << hole << "
" << hole->elt().points << " " << std::endl;
- // std::cout << "child hole : " << child_hole <<
" " << child_hole->elt().points << std::endl;
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
- if (!child_has_bigger_hole)
- {
- // // std::cout << "move " << hole << " as child
of " << &node << std::endl;
- node.add_child(hole);
- to_fill.push_back(hole);
- }
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- for(typename std::vector<node_type*>::iterator node_ = to_fill.begin();
- node_ != to_fill.end();
- node_++)
- {
- node_type& node = **node_;
-
- fllt_branch_iter_ind(P, V) node_(fllt_branch(P, V)(upper_tree, node));
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != upper<V>::id)
- continue;
-
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- //if (hole->elt().points <= child_hole->elt().points)
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
-
- if (!child_has_bigger_hole)
- node.add_child(hole);
-
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- }
-
- return lower_tree;
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- fllt(const Image<I>& input_)
- {
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- const I& input = exact(input_);
-
- fllt_tree(P, V) upper_tree;
- fllt_tree(P, V) lower_tree;
- image2d<fllt_node(P, V)*> low_reg(input.domain());
- image2d<fllt_node(P, V)*> upp_reg(input.domain());
-
- std::cout << "1/ Compute the lower level
set.----------------------------------------" << std::endl;
- lower_tree = level_set<I, lower<V> >(input, low_reg);
-
- std::cout << "2/ Compute the upper level
set.----------------------------------------" << std::endl;
- upper_tree = level_set<I, upper<V> >(input, upp_reg);
-
- std::cout << "3/
Merge.---------------------------------------------------------------" <<
std::endl;
- fllt_tree(P, V) result_tree = merge_trees(lower_tree, upper_tree, low_reg, upp_reg,
input);
-
- return result_tree;
- }
-
-} // end of namespace mln
Index: geraud/fllt.svg.7.hh
--- geraud/fllt.svg.7.hh (revision 3151)
+++ geraud/fllt.svg.7.hh (working copy)
@@ -1,838 +0,0 @@
-// Copyright (C) 2008 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_FLLT_HH
-# define MLN_FLLT_HH
-
-#include <iomanip>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/image_if_value.hh>
-#include <mln/core/image/sub_image.hh>
-#include <mln/core/site_set/p_queue_fast.hh>
-#include <mln/core/image/cast_image.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/level/compare.hh>
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_minima.hh>
-#include <mln/labeling/regional_maxima.hh>
-#include <mln/accu/bbox.hh>
-#include <mln/geom/bbox.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/literal/black.hh>
-#include <mln/literal/white.hh>
-#include <mln/literal/colors.hh>
-
-#include <mln/util/tree.hh>
-#include <mln/util/branch_iter_ind.hh>
-#include <mln/util/branch_iter.hh>
-#include <mln/opt/at.hh>
-
-#include <sstream>
-
-
-namespace mln
-{
-
-# define fllt_tree(P, V) mln::util::tree< fllt_node_elt<P, V> >
-# define fllt_node(P, V) mln::util::tree_node< fllt_node_elt<P, V> >
-# define fllt_tree_ptr(P, V) mln::util::tree< fllt_node_elt<P, V>* >
-# define fllt_node_ptr(P, V) mln::util::tree_node< fllt_node_elt<P, V>* >
-# define fllt_branch(P, V) mln::util::branch< fllt_node_elt<P, V> >
-# define fllt_branch_iter_ind(P, V) mln::util::branch_iter_ind< fllt_node_elt<P,
V> >
-# define fllt_branch_iter(P, V) mln::util::branch_iter< fllt_node_elt<P, V>
>
-
-# define stl_to_mln_iter(T) stl_iterator< T >
-
- //Fwd declarations.
- template <typename V> struct lower;
- template <typename V> struct upper;
-
- template <typename P, typename V>
- struct fllt_node_elt
- {
- V value;
- p_array<P> points;
- p_array<P> holes;
- std::vector<fllt_node(P, V)*> hole_shapes;
- /// Tell if his parent if brighter or not. Nb : if the parent
- /// if brighter, the node come from the lower level set
- bool brighter;
- unsigned nsites;
- bool tagged;
- bool set_id;
-
- fllt_node_elt(bool set_id) : nsites(0), tagged(false), set_id(set_id) {}
- };
-
-
- template <typename C>
- class stl_iterator
- {
- public:
- stl_iterator(C& c) : container_(c) {}
- void start(){ it_ = container_.begin(); }
- void next() { it_++; }
- bool is_valid() const{ return it_ != container_.end(); }
- typename C::value_type& operator*() { return *it_; }
-
- private:
- C& container_;
- typename C::iterator it_;
- };
-
- template <typename N_t, typename G, typename Set>
- void update_gN(const N_t& N, G& gN);
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, lower<V>)
- {
- for (unsigned g = 0; g < 256; ++g)
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- // if N is empty, gN is the max value.
- gN = 255;
- }
-
- template <typename N_t, typename G, typename V>
- void update_gN(const N_t& N, G& gN, upper<V>)
- {
- for (int g = 255; g >= 0; --g)
- {
- if (N[g]->nsites() != 0)
- {
- gN = g;
- return;
- }
- }
- // if N is empty, gN is the min value.
- gN = 0;
- }
-
-
- template <typename N_t>
- void print_N(const N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- {
- if (N[i]->nsites() == 0)
- continue;
- std::cout << i << ": " << *N[i] << std::endl;
- }
- }
-
- template <typename N_t>
- void clear_N(N_t& N)
- {
- for (unsigned i = 0; i < 256; ++i)
- N[i]->clear();
- }
-
-
-
- template <typename T>
- image2d<T> enlarge(const image2d<T>& input, unsigned coef)
- {
- unsigned
- nrows_ = coef * geom::nrows(input),
- ncols_ = coef * geom::ncols(input);
- image2d<T> output(nrows_, ncols_);
- for (int row = 0; row < nrows_; ++row)
- for (int col = 0; col < ncols_; ++col)
- opt::at(output, row, col) = opt::at(input, row / coef, col / coef);
- return output;
- }
-
-
- void save_u(const image2d<value::int_u8>& u,
- const image2d<int>& is,
- box2d R_box,
- int in_R,
- int in_N)
- {
- static int id = 0;
- std::stringstream filename;
- filename << "fllt_trace_" << std::setw(5) <<
std::setfill('0')
- << std::right << id++ << ".ppm";
-
- image2d<value::int_u8> out = duplicate(cast_image<value::int_u8>(is));
-
- mln_assertion(R_box.nsites() > 0);
- mln_piter_(box2d) p(R_box);
- for_all(p)
- if (is(p) == in_R)
- out(p) = 255;
- else if (is(p) == in_N)
- out(p) = 127;
- // else if (is(p) == in_N)
- // out(p) = literal::green;
-
- io::pgm::save(out, filename.str());
- //io::pgm::save(out, filename.str());
- }
-
- template <typename I>
- void save(const I& is, unsigned in_N, unsigned in_R, const std::string& name =
"")
- {
- static unsigned counter = 0;
- using value::rgb8;
-
- image2d<rgb8> temp(is.domain());
- data::fill(temp, literal::black);
-
- mln_piter(I) p(is.domain());
- for_all(p)
- if (is(p) == in_R)
- temp(p) = literal::red;
- else if (is(p) == in_N) // N
- temp(p) = literal::green;
- else if (is(p) < in_N)
- temp(p) = literal::blue;
- else
- temp(p) = literal::white;
-
- if (name == "")
- {
- std::stringstream filename;
- filename << "./temp_" << ++counter <<
".ppm";
- io::ppm::save(enlarge(temp, 10), filename.str());
- }
- else
- io::ppm::save(temp, name);
- }
-
-
- template <typename I, typename P, typename V, typename Set>
- void blob(const Set&,
- const I& is,
- p_array<mln_point(I)>* N[256],
- unsigned in_N,
- const box2d& N_box,
- fllt_node(P, V)* current_cc)
- {
- typedef p_array<mln_point(I)> arr_t;
-
- // std::cout << ">>>>>>>enter blob. "
<< current_cc << std::endl;
- bool flower = true;
- unsigned ncc = 0;
- static image2d<unsigned> is_labeled(is.domain());
- static unsigned label = 0;
-
- if (label == 0)
- {
- data::fill(is_labeled, 0);
- label++;
- }
-
- P cur;
- mln_niter(neighb2d) n(Set::bdr_nbh(), cur);
- p_queue_fast<P> qu;
- p_array<P>& holes = current_cc->elt().holes;
-
- mln_piter(I) p(N_box);
- for_all(p)
- if (is(p) == in_N)
- break;
-
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
-
-
-
- for (unsigned i = 0; i < 256; ++i)
- //for (int i = 255; i >= 0; --i)
- {
- mln_piter(arr_t) p(*N[i]);
- for_all(p)
- {
- mln_assertion(is(p) == in_N);
- if (is_labeled(p) != label)
- {
- if (flower == false)
- holes.append(p);
- else
- flower = false;
- qu.push(p);
- is_labeled(p) = label;
- do
- {
- cur = qu.front();
- qu.pop();
- for_all(n) if (is.has(n))
- if (is(n) == in_N && is_labeled(n) != label)
- {
- qu.push(n);
- is_labeled(n) = label;
- }
- }
- while (! qu.is_empty());
- }
- }
- }
-
- ++label;
-
- // if (holes.size() == 2)
- // std::cout << holes[0] << holes[1] << std::endl;
- // std::cout << " <<<<<<<exiting blob."
<< std::endl;
- }
-
- template <typename P, typename V>
- void
- move_A_to_R(p_array<P>& A,
- image2d<int>& deja_vu,
- fllt_node(P, V)* current_cc,
- image2d< fllt_node(P, V)* >& smallest_shapes,
- int in_R,
- int in_N,
- const V& g,
- unsigned& n_comps)
- {
- typedef p_array<P> arr_t;
-
- mln_piter(arr_t) a(A);
- for_all(a)
- {
- mln_invariant(deja_vu(a) == in_N);
- mln_invariant(smallest_shapes(a) != current_cc);
- // if (smallest_shapes(a) == current_cc)
- // continue;
-
- deja_vu(a) = in_R;
- if (!smallest_shapes(a))
- {
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- if (!smallest_shapes(a)->parent())
- if (smallest_shapes(a)->elt().value == g)
- {
- fllt_node(P, V)* to_delete = smallest_shapes(a);
-
- // current_cc->elt().points.append(smallest_shapes(a)->elt().points);
- // A.append(smallest_shapes(a)->elt().points);
-
- mln_piter(arr_t) p(smallest_shapes(a)->elt().points);
- // Todo optimization here.
- for_all(p)
- {
- smallest_shapes(p) = 0;
- // deja_vu(p) = in_R;
- //smallest_shapes(p) = current_cc;
- }
-
- while(!to_delete->children().empty())
- current_cc->add_child(*to_delete->children().begin());
- delete to_delete;
- n_comps--;
- smallest_shapes(a) = current_cc;
- current_cc->elt().points.append(a);
- }
- else
- smallest_shapes(a)->set_parent(current_cc);
- }
- }
-
- // LOWER LEVEL SET : region = c4, border = c8
- template <typename V>
- struct lower
- {
- typedef upper<V> opposite;
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- {
- return u < v;
- }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>&
nbh, L& nlabels)
- {
- return labeling::regional_minima(input, nbh, nlabels);
- }
-
- static const bool parent_is_brighter = true;
- static const bool id = false;
-
- static const neighb2d& bdr_nbh() { return c8(); }
- static const neighb2d& reg_nbh() { return c4(); }
- };
-
-
- // UPPER LEVEL SET : region = c8, border = c4
- template <typename V>
- struct upper
- {
- typedef lower<V> opposite;
-
- // If compare(u,v) u root <- v <- u
- // else root <- u <- v
- static bool
- compare(const V& u, const V& v)
- { return u > v; }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>&
nbh, L& nlabels)
- { return labeling::regional_maxima(input, nbh, nlabels); }
-
- static const bool parent_is_brighter = false;
- static const bool id = true;
-
- static const neighb2d& bdr_nbh() { return c4(); }
- static const neighb2d& reg_nbh() { return c8(); }
- };
-
- template <typename I, typename Set>
- fllt_tree(mln_point(I), mln_value(I))&
- level_set(const Image<I>& input_,
- image2d< fllt_node(mln_point(I), mln_value(I))* >& smallest_shapes)
- {
-
- typedef mln_point(I) P;
- typedef mln_value(I) V;
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
-
- const I& input = exact(input_);
-
- mln_assertion(input.domain() == smallest_shapes.domain());
-
- unsigned l = 0, l_max = 0;
- mln_ch_value(I, unsigned) reg_min = Set::regional_extremum(input, Set::reg_nbh(),
l_max);
- std::vector<bool> tag(l_max + 1, false);
- tag[0] = true;
-
- // Variables.
- I u = mln::duplicate(input);
- P x0;
- V g, gN;
- mln_fwd_piter(I) p(input.domain());
- p.start();
- data::fill(smallest_shapes, 0);
- node_type* current_cc;
-
- unsigned in_N = 1, in_R = 2;
-
- image2d<int> deja_vu(input.domain().to_larger(1));
- data::fill(deja_vu, 0);
-
- typedef p_array<P> arr_t;
- arr_t* A = new arr_t();
- arr_t* N[256];
- for (unsigned i = 0; i < 256; ++i)
- N[i] = new arr_t();
- accu::bbox<P> N_box;
-
- bool touch_border_of_image = false;
- unsigned n_step_1 = 0, n_step_3 = 0, n_step_4c = 0, n_comps = 0, n_holes = 0;
-
- // Step 1.
- step_1:
- {
- while (tag[reg_min(p)] && p.is_valid())
- p.next();
- if (p.is_valid())
- tag[reg_min(p)] = true; // To be processed.
- else
- goto the_end;
-
- ++n_step_1;
- x0 = p;
- g = input(x0);
- ++n_comps;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- touch_border_of_image = false;
-
- }
-
- // Step 2.
- step_2:
- {
- in_N += 2;
- in_R = in_N + 1;
- // R <- 0 and N <- 0
- clear_N(N);
- N_box.init();
-
- // A <- { x0 }
- A->clear();
- A->append(x0);
- N_box.take(x0);
-
- deja_vu(x0) = in_R;
- smallest_shapes(x0) = current_cc;
- current_cc->elt().points.append(x0);
- current_cc->elt().nsites++;
-
- }
-
- // Step 3.
- step_3:
- {
- // save_u(u, deja_vu, N_box, in_R, in_N);
- ++n_step_3;
-
- mln_piter(arr_t) a(*A);
- mln_niter(neighb2d) x(Set::reg_nbh(), a);
-
-
- // R <- R U A
- if (A->nsites() == 0)
- goto the_end;
-
- // N <- N U { x in nbh of A and not in R }
- for_all(a)
- for_all(x)
- {
- if (deja_vu.has(x) && deja_vu(x) < in_N)
- {
- if (u.has(x))
- {
- N[u(x)]->append(x);
- N_box.take(x);
- }
- else
- touch_border_of_image = true;
- deja_vu(x) = in_N;
- }
- }
- // gN = min u(x) for all x in N
- update_gN(N, gN, Set());
-
- // FIXME: update the number of CC of the border of R
- }
-
- // Step 4.
- step_4:
- {
- // a)
- if (Set::compare(g, gN))
- {
- g = gN;
-
- ++n_comps;
-
- if (touch_border_of_image)
- blob(Set(), deja_vu, N, in_N, N_box.to_result().to_larger(1), current_cc);
- else
- blob(Set(), deja_vu, N, in_N, N_box, current_cc);
-
- n_holes += current_cc->elt().holes.nsites();
-
- node_type* child = current_cc;
- current_cc = new node_type(Set::id);
- current_cc->elt().value = g;
- child->set_parent(current_cc);
-
-
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // b)
- else if (g == gN)
- {
- arr_t* tmp = A;
- A = N[g];
- N[g] = tmp;
- N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
- goto step_3;
- }
- // c)
- else
- {
- // FIXME: IDEA: this change might be performed while R is constructed(?)
- n_step_4c++;
- mln_piter(I) r(N_box);
- for_all(r)
- if (deja_vu(r) == in_R)
- u(r) = g;
-
- goto step_1;
- }
- }
-
- the_end:
- std::cout << " n_step1 : " << n_step_1 << "
n_step3 : " << n_step_3 << " n_step4c : " << n_step_4c
<< std::endl;
- std::cout << "n comps = " << n_comps << " n holes =
" << n_holes << std::endl;
-
- return *new tree_type(current_cc);
- }
-
- // F is the set in which we get the node.
- template <typename P, typename V, typename F>
- fllt_node(P, V)*
- find_hole(fllt_node(P, V)& node,
- const P p,
- const image2d<fllt_node(P, V)*>& other_reg)
- {
- fllt_node(P, V)* s = other_reg(p);
- mln_assertion(s);
- while (s->parent() && F::compare(s->parent()->elt().value,
node.elt().value))
- {
- mln_assertion(s);
- s = s->parent();
- mln_assertion(s);
- }
- // std::cout << " [Find the hole] of " << p
- // << " from " << &node
- // << " return " << s
- // << std::endl;
- return s;
- }
-
- template <typename P, typename V>
- bool shape_is_included(fllt_node(P, V)* A,
- fllt_node(P, V)* B)
- {
- return A->parent() == B || A == B;
- }
-
- template <typename P, typename V>
- void find_all_holes(fllt_tree(P, V)& lower_tree,
- fllt_tree(P, V)& upper_tree,
- const image2d<fllt_node(P, V)*>& low_reg,
- const image2d<fllt_node(P, V)*>& upp_reg)
- {
- typedef p_array<P> arr_t;
- typedef fllt_node(P, V) node_type;
-
- {
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,upper<V> >(node, P(hole),
upp_reg));
- }
- }
-
- {
- fllt_branch_iter_ind(P, V) node_(upper_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- mln_piter(arr_t) hole(node.elt().holes);
- for_all(hole)
- node.elt().hole_shapes.push_back(find_hole<P,V,lower<V> >(node, P(hole),
low_reg));
- }
- }
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- merge_trees(fllt_tree(mln_point(I), mln_value(I))& lower_tree,
- fllt_tree(mln_point(I), mln_value(I))& upper_tree,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& low_reg,
- const image2d<fllt_node(mln_point(I), mln_value(I))*>& upp_reg,
- const Image<I>& input_)
- {
-
- const I& input = exact(input_);
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- typedef fllt_node(P, V) node_type;
- typedef fllt_tree(P, V) tree_type;
- typedef p_array<P> arr_t;
-
-
- find_all_holes(lower_tree, upper_tree, low_reg, upp_reg);
- std::vector<node_type*> to_fill;
-
- fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != lower<V>::id)
- continue;
-
- // std::cout << "Fill " << &node << std::endl;
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- // std::cout << "hole : " << hole << "
" << hole->elt().points << " " << std::endl;
- // std::cout << "child hole : " << child_hole <<
" " << child_hole->elt().points << std::endl;
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
- if (!child_has_bigger_hole)
- {
- // // std::cout << "move " << hole << " as child
of " << &node << std::endl;
- node.add_child(hole);
- to_fill.push_back(hole);
- }
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- for(typename std::vector<node_type*>::iterator node_ = to_fill.begin();
- node_ != to_fill.end();
- node_++)
- {
- node_type& node = **node_;
-
- fllt_branch_iter_ind(P, V) node_(fllt_branch(P, V)(upper_tree, node));
- for_all(node_)
- {
- node_type& node = *node_;
- if (node.elt().set_id != upper<V>::id)
- continue;
-
- typename std::vector<fllt_node(P, V)*>::iterator hole_;
- for (hole_ = node.elt().hole_shapes.begin();
- hole_ != node.elt().hole_shapes.end();
- hole_++)
- {
- fllt_node(P, V)* hole = *hole_;
-
- bool child_has_bigger_hole = false;
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
- {
- // Browse the holes of each child.
- typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
- for (child_hole_ = (*it)->elt().hole_shapes.begin();
- child_hole_ != (*it)->elt().hole_shapes.end();
- child_hole_++)
- {
- fllt_node(P, V)* child_hole = *child_hole_;
- //if (hole->elt().points <= child_hole->elt().points)
- if (shape_is_included(hole, child_hole))
- {
- child_has_bigger_hole = true;
- break;
- }
- } // end of browsing child's holes.
- } // end of browsing childs.
-
- if (!child_has_bigger_hole)
- node.add_child(hole);
-
- } // end of browsing holes of node.
- node.elt().holes.clear();
- } // end of browsing lower_tree.
-
- }
-
- return lower_tree;
- }
-
- template <typename I>
- fllt_tree(mln_point(I), mln_value(I))
- fllt(const Image<I>& input_)
- {
- typedef mln_point(I) P;
- typedef mln_value(I) V;
-
- const I& input = exact(input_);
-
- fllt_tree(P, V) upper_tree;
- fllt_tree(P, V) lower_tree;
- image2d<fllt_node(P, V)*> low_reg(input.domain());
- image2d<fllt_node(P, V)*> upp_reg(input.domain());
-
- std::cout << "1/ Compute the lower level
set.----------------------------------------" << std::endl;
- lower_tree = level_set<I, lower<V> >(input, low_reg);
-
- std::cout << "2/ Compute the upper level
set.----------------------------------------" << std::endl;
- upper_tree = level_set<I, upper<V> >(input, upp_reg);
-
- std::cout << "3/
Merge.---------------------------------------------------------------" <<
std::endl;
- fllt_tree(P, V) result_tree = merge_trees(lower_tree, upper_tree, low_reg, upp_reg,
input);
-
- return result_tree;
- }
-
-} // end of namespace mln
-
-#endif // ! MLN_FLLT_HH
Index: geraud/win_fun.hh
--- geraud/win_fun.hh (revision 3151)
+++ geraud/win_fun.hh (working copy)
@@ -1,160 +0,0 @@
-// Copyright (C) 2008 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 infun 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_WIN_FUN_HH
-# define MLN_WIN_FUN_HH
-
-/*! \file mln/win/fun.hh
- *
- * \brief Definition of the mln::win::fun window.
- */
-
-# include <mln/core/internal/window_base.hh>
-# include <mln/core/internal/site_relative_iterator_base.hh>
-
-
-namespace mln
-{
-
- namespace win
- {
-
- // Fwd decl.
- template <typename F> class fun_piter;
-
-
- /*! \brief Window defined by a function.
- */
- template <typename F>
- struct fun : public internal::window_base< mln_deduce(F, result, dpsite),
- fun<F> >
- {
-
- /// Site_Iterator type to browse a fun forward
- typedef fun_piter<F> fwd_qiter;
-
- /// Site_Iterator type to browse a fun backward
- typedef fun_piter<F> bkd_qiter;
-
- /// Same as fwd_qiter
- typedef fwd_qiter qiter;
-
- /// Constructor.
- fun(const F& f) : f(f) {}
-
- /// Test if the window is centered.
- bool is_centered() const { return false; }
-
- /// Test if the window is empty.
- bool is_empty() const { return false; }
-
- /// Test if the window is symmetric.
- bool is_symmetric() const { return false; }
-
- /// Give the maximum coordinate gap between the window
- unsigned delta() const { return 100; } // FIXME
-
- /// Apply a central symmetry to the target window.
- void sym() {}
-
- const F& f;
- };
-
-
- template <typename F>
- class fun_piter
- : public internal::site_relative_iterator_base< fun<F>,
- fun_piter<F> >
- {
- public:
-
- typedef mln_result(F) W;
-
- /// Constructor.
- template <typename P>
- fun_piter(const fun<F>& win, const P& c)
- : f_(win.f)
- {
- q_.center_at(c);
- this->change_target(win);
- this->center_at(c);
- }
-
- /// Test the iterator validity.
- bool is_valid_() const
- {
- return this->c_ != 0 && q_.is_valid();
- }
-
- /// Invalidate the iterator.
- void invalidate_()
- {
- q_.invalidate();
- }
-
- /// Start an iteration.
- void do_start_()
- {
- q_.change_target(f_(*this->c_));
- q_.start();
- }
-
- /// Go to the next point.
- void do_next_()
- {
- q_.next();
- }
-
- /// Compute the current psite.
- mln_psite(W) compute_p_() const
- {
- return q_;
- }
-
- protected:
-
- const F& f_;
- mln_fwd_qiter(W) q_;
- };
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- // FIXME: Move code here.
-
- // MEMO: mln_fwd_qiter(mln_result(F))
-
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace mln::win
-
-} // end of namespace mln
-
-
-
-#endif // ! MLN_WIN_FUN_HH
Index: geraud/Rd/hybrid.hh
--- geraud/Rd/hybrid.hh (revision 3151)
+++ geraud/Rd/hybrid.hh (working copy)
@@ -1,117 +0,0 @@
-// Copyright (C) 2007, 2008 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_MORPHO_RD_HYBRID_HH
-# define MLN_MORPHO_RD_HYBRID_HH
-
-# include <queue>
-# include "utils.hh"
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
-
- template <typename I, typename N>
- I hybrid(const I& f, const I& g, const N& nbh,
- bool echo = false)
- {
- typedef mln_site(I) point;
- std::queue<point> q;
-
- // initialisation
- I o = duplicate(f);
-
- unsigned n_init_pushs = 0, n_body_pushs = 0, n_pops = 0;
-
- // sequence
- {
- mln_bkd_piter(I) p(f.domain());
- for_all(p)
- o(p) = min( max_Nminus(o, p,nbh), g(p) );
- }
- {
- mln_fwd_piter(I) p(f.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- o(p) = min( max_Nplus(o, p,nbh), g(p) );
- for_all(n)
- if (f.has(n) &&
- util::ord_strict(n.to_site(), p.to_site())) // N+
- if (o(n) < o(p) && o(n) < g(n))
- {
- q.push(p);
- ++n_init_pushs;
- }
- }
- }
-
- // propagation
- {
- point p;
- mln_niter(N) n(nbh, p);
- while (not q.empty())
- {
- p = q.front();
- if (echo) std::cout << std::endl << "pop " << p
<< " :";
- q.pop();
- ++n_pops;
- for_all(n) if (f.has(n))
- if (o(n) < o(p) && o(n) != g(n))
- {
- o(n) = min(o(p), g(n));
- if (echo) std::cout << " push " << n;
- q.push(n);
- ++n_body_pushs;
- }
- }
- if (echo) std::cout << std::endl;
- }
-
- if (echo)
- std::cout << "n_init_pushs = " << n_init_pushs <<
std::endl
- << "n_body_pushs = " << n_body_pushs << std::endl
- << "n_pops = " << n_pops << std::endl;
-
- return o;
- }
-
- } // end of namespace mln::morpho::Rd
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_RD_HYBRID_HH
Index: geraud/Rd/queue_based.hh
--- geraud/Rd/queue_based.hh (revision 3151)
+++ geraud/Rd/queue_based.hh (working copy)
@@ -1,124 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research && 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 && 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_RD_QUEUE_BASED_HH
-# define MLN_MORPHO_RD_QUEUE_BASED_HH
-
-# include <queue>
-# include "utils.hh"
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
- template <typename I, typename N>
- I queue_based(const I& f, const I& g, const N& nbh,
- bool echo = false)
- {
-
- mln_ch_value(I, bool) que(f.domain());
- data::fill(que, false);
-
-
- if (echo) std::cout << std::endl;
-
- typedef mln_site(I) point;
- std::queue<point> q;
- I o;
-
- unsigned n_init_pushs = 0, n_body_pushs = 0, n_pops = 0;
-
- // initialisation
- {
- o = regional_maxima(f, nbh);
- // p in M <=> o(p) != 0
- if (echo) debug::println(o);
-
- mln_piter(I) p(f.domain());
- mln_niter(N) n(nbh, p);
-
- for_all(p) if (o(p) != 0u) // p in M
- for_all(n) if (f.has(n) && o(n) == 0u) // n not in M
- {
- q.push(p);
- que(p) = true;
- ++n_init_pushs;
- break;
- }
- }
-
- // propagation
- {
- point p;
- mln_niter(N) n(nbh, p);
- while (not q.empty())
- {
- p = q.front();
- if (echo) std::cout << std::endl << "pop " << p
<< " :";
- q.pop();
- que(p) = false;
- ++n_pops;
- for_all(n) if (f.has(n))
- {
- if (o(n) < o(p) && o(n) != g(n))
- {
- o(n) = min(o(p), g(n));
- if (echo) std::cout << " push " << n;
- if (que(n) == false)
- {
- q.push(n);
- que(n) = true;
- ++n_body_pushs;
- }
- }
- }
- }
- if (echo) std::cout << std::endl;
- }
-
- if (echo)
- std::cout << "n_init_pushs = " << n_init_pushs <<
std::endl
- << "n_body_pushs = " << n_body_pushs << std::endl
- << "n_pops = " << n_pops << std::endl;
-
- return o;
- }
-
- } // end of namespace mln::morpho::Rd
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_RD_QUEUE_BASED_HH
Index: geraud/Rd/parallel.cc
--- geraud/Rd/parallel.cc (revision 3151)
+++ geraud/Rd/parallel.cc (working copy)
@@ -1,54 +0,0 @@
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/value/int_u8.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include "parallel.hh"
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c
output.pgm" << std::endl
- << "reconstruction by dilation (parallel version; sep 2008)"
<< std::endl
- << "f = marker (to be dilated)" << std::endl
- << "g = mask (constraint >= f)" << std::endl
- << "c: 4 or 8" << std::endl;
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 5)
- usage(argv);
-
- using namespace mln;
- using value::int_u8;
-
- border::thickness = 0; // Safety.
-
- typedef image2d<int_u8> I;
-
- int c = atoi(argv[3]);
- if (c != 4 and c != 8)
- usage(argv);
-
- I f, g;
- io::pgm::load(f, argv[1]);
- io::pgm::load(g, argv[2]);
-
- if (! (f <= g))
- {
- std::cerr << "error: the precondition 'f <= g' is not
true" << std::endl;
- return 1;
- }
-
- I o = morpho::Rd::parallel(f, g,
- (c == 4 ? c4() : c8()));
- io::pgm::save(o, argv[4]);
-}
Index: geraud/Rd/parallel_wo.cc
--- geraud/Rd/parallel_wo.cc (revision 3151)
+++ geraud/Rd/parallel_wo.cc (working copy)
@@ -1,46 +0,0 @@
-#include <iostream>
-
-#include <mln/core/image2d.hh>
-#include <mln/core/neighb2d.hh>
-#include <mln/value/int_u8.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include "parallel.hh"
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c
output.pgm" << std::endl
- << "reconstruction by dilation (parallel version; may 2007)"
<< std::endl
- << "f = marker (to be dilated)" << std::endl
- << "g = mask (constraint >= f)" << std::endl
- << "c: 4 or 8" << std::endl;
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 5)
- usage(argv);
-
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<int_u8> I;
-
- int c = atoi(argv[3]);
- if (c != 4 and c != 8)
- usage(argv);
-
- I f = io::pgm::load<int_u8>(argv[1]);
- I g = io::pgm::load<int_u8>(argv[2]);
-
- io::pgm::save(morpho::Rd::parallel(f, g,
- (c == 4 ? c4() : c8()),
- false),
- argv[4]);
-}
Index: geraud/Rd/union_find.hh
--- geraud/Rd/union_find.hh (revision 3151)
+++ geraud/Rd/union_find.hh (working copy)
@@ -1,166 +0,0 @@
-// Copyright (C) 2007, 2008 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_MORPHO_RD_UNION_FIND_HH
-# define MLN_MORPHO_RD_UNION_FIND_HH
-
-# include "utils.hh"
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
-
- template <typename I, typename N>
- struct union_find_t
- {
- typedef mln_site(I) point;
- typedef mln_value(I) value;
-
- // in:
- const I f, g;
- N nbh;
-
- // out:
- I o;
-
- // aux:
- std::vector<point> S;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, point) parent;
-
- union_find_t(const I& f, const I& g, const N& nbh)
- : f(f), g(g), nbh(nbh)
- {
- initialize(o, f);
- initialize(parent, f);
- initialize(deja_vu, f);
-
- // init
-
- data::fill(deja_vu, false);
- S = histo_reverse_sort(g);
- data::paste(f, o); // Replace: for all p, make_set(p) { data(p) = f(p) }
-
- // first pass
-
- for (unsigned i = 0; i < S.size(); ++i)
- {
- point p = S[i];
- make_set(p);
- mln_niter(N) n(nbh, p);
- for_all(n)
- {
- if (f.has(n))
- mln_invariant(deja_vu(n) == is_proc(n, p));
- if (f.has(n) && deja_vu(n))
- do_union(n, p);
- }
- deja_vu(p) = true;
- }
-
- // second pass
-
- for (int i = S.size() - 1; i >= 0; --i)
- {
- point p = S[i];
- if (parent(p) == p)
- {
- if (o(p) == mln_max(value))
- o(p) = g(p);
- }
- else
- o(p) = o(parent(p));
- }
-
- }
-
- bool is_proc(const point& n, const point& p) const
- {
- return g(n) > g(p) or (g(n) == g(p) &&
- util::ord_strict(n, p));
- }
-
- void make_set(const point& p)
- {
- parent(p) = p;
- // was: data(p) = f(p);
- // now: in "initialization"
- }
-
- point find_root(const point& x)
- {
- if (parent(x) == x)
- return x;
- else
- return parent(x) = find_root(parent(x));
- }
-
- void do_union(const point& n, const point& p)
- {
- point r = find_root(n);
- if (r != p)
- {
- // NEW: o replaces data
-
- if (g(r) == g(p) or g(p) >= o(r)) // equiv test
- {
- parent(r) = p;
- if (o(r) > o(p))
- o(p) = o(r); // increasing criterion
- }
- else
- o(p) = mln_max(value);
- }
- }
-
- };
-
-
- template <typename I, typename N>
- I union_find(const I& f, const I& g, const N& nbh)
- {
- mln_precondition(f <= g);
- union_find_t<I, N> run(f, g, nbh);
- return run.o;
- }
-
-
- } // end of namespace mln::morpho::Rd
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_RD_UNION_FIND_HH
Index: geraud/Rd/parallel.hh
--- geraud/Rd/parallel.hh (revision 3151)
+++ geraud/Rd/parallel.hh (working copy)
@@ -1,85 +0,0 @@
-// Copyright (C) 2007, 2008 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_MORPHO_RD_PARALLEL_HH
-# define MLN_MORPHO_RD_PARALLEL_HH
-
-# include "utils.hh"
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
-
- template <typename I, typename N>
- I parallel(const I& f, const I& g, const N& nbh,
- bool test = true)
- {
- if (test)
- mln_precondition(f <= g);
-
- I o_(f.domain());
- mln_piter(I) p(f.domain());
-
- // initialisation
- I o = duplicate(f);
-
- bool stability;
- do
- {
- data::paste(o, o_); // memorisation
-
- // opere
- for_all(p)
- o(p) = max_N(o_, p, nbh);
- // conditionne
- for_all(p)
- o(p) = min(o(p), g(p));
-
- stability = (o == o_);
- }
- while (not stability);
-
- if (test)
- mln_postcondition(o <= g);
- return o;
- }
-
- } // end of namespace mln::morpho::Rd
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_RD_PARALLEL_HH
Index: geraud/Rd/diff.cc
--- geraud/Rd/diff.cc (revision 3151)
+++ geraud/Rd/diff.cc (working copy)
@@ -1,28 +0,0 @@
-#include <oln/core/2d/image2d.hh>
-#include <oln/io/load_pgm.hh>
-#include <oln/level/compare.hh>
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " 1.pgm
2.pgm" << std::endl
- << "(may 2007)" << std::endl;
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 3)
- usage(argv);
-
- using namespace oln;
- typedef image2d<unsigned char> I;
-
- I ima1 = io::load_pgm(argv[1]);
- I ima2 = io::load_pgm(argv[2]);
-
- if (ima1 != ima2)
- std::cout << "images differ" << std::endl;
- return 0;
-}
Index: geraud/Rd/sequential_bench.cc
--- geraud/Rd/sequential_bench.cc (revision 3151)
+++ geraud/Rd/sequential_bench.cc (working copy)
@@ -1,51 +0,0 @@
-#include <mln/core/image2d.hh>
-#include <mln/core/neighb2d.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include "sequential_bench.hh"
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c
output.pgm" << std::endl
- << "reconstruction by dilation (sequential version; may
2007)" << std::endl
- << "f = marker (to be dilated)" << std::endl
- << "g = mask (constraint >= f)" << std::endl
- << "c: 4 or 8" << std::endl;
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 5)
- usage(argv);
-
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<int_u8> I;
-
- int c = atoi(argv[3]);
- if (c != 4 and c != 8)
- usage(argv);
-
- I f = io::pgm::load<int_u8>(argv[1]);
- f.name_it("main.f");
-
- I g = io::pgm::load<int_u8>(argv[2]);
- g.name_it("main.g");
-
- if (not (f <= g))
- {
- std::cerr << "pb" << std::endl;
- return 1;
- }
-
- io::pgm::save(morpho::Rd::sequential(f, g,
- (c == 4 ? c4() : c8())),
- argv[4]);
-}
Index: geraud/Rd/sequential.cc
--- geraud/Rd/sequential.cc (revision 3151)
+++ geraud/Rd/sequential.cc (working copy)
@@ -1,50 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include "sequential.hh"
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c
output.pgm" << std::endl
- << "reconstruction by dilation (sequential version; sep
2008)" << std::endl
- << "f = marker (to be dilated)" << std::endl
- << "g = mask (constraint >= f)" << std::endl
- << "c: 4 or 8" << std::endl;
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 5)
- usage(argv);
-
- using namespace mln;
- using value::int_u8;
-
- border::thickness = 0; // Safety.
-
- typedef image2d<int_u8> I;
-
- int c = atoi(argv[3]);
- if (c != 4 and c != 8)
- usage(argv);
-
- I f, g;
- io::pgm::load(f, argv[1]);
- io::pgm::load(g, argv[2]);
-
- if (not (f <= g))
- {
- std::cerr << "error: the precondition 'f <= g' is not
true" << std::endl;
- return 1;
- }
-
- I o = morpho::Rd::sequential(f, g, (c == 4 ? c4() : c8()));
- io::pgm::save(o, argv[4]);
-}
Index: geraud/Rd/deco.cc
--- geraud/Rd/deco.cc (revision 3151)
+++ geraud/Rd/deco.cc (working copy)
@@ -1,71 +0,0 @@
-// 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.
-
-/*! \file tests/decorated_image.cc
- *
- * \brief Tests on mln::decorated_image.
- * \todo Make this test work.
- */
-
-#include <mln/core/image2d.hh>
-#include <mln/core/decorated_image.hh>
-
-
-unsigned count_read = 0, count_write = 0;
-
-template <typename I>
-struct counter
-{
- void reading(const I&, const mln_psite(I)&) const
- {
- ++count_read;
- }
- void writing(I&, const mln_psite(I)&, const mln_value(I)&)
- {
- ++count_write;
- }
-};
-
-
-int main()
-{
- using namespace mln;
-
- typedef image2d<int> I;
- I ima(1, 1);
- point2d p = make::point2d(0, 0);
-
- decorated_image< I, counter<I> > ima_ = decorate(ima, counter<I>());
- ima_(p) = ima_(p) = 51;
-
- std::cout << count_read << ' ' << count_write <<
std::endl;
-
- mln_assertion(count_read == 1 && count_write == 2);
-
- const I& imac = ima;
- decorated_image< const I, counter<I> > cima_ = decorate(imac,
counter<I>());
-}
Index: geraud/Rd/utils.hh
--- geraud/Rd/utils.hh (revision 3151)
+++ geraud/Rd/utils.hh (working copy)
@@ -1,269 +0,0 @@
-// Copyright (C) 2007, 2008 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_MORPHO_RD_UTILS_HH
-# define MLN_MORPHO_RD_UTILS_HH
-
-# include <vector>
-
-# include <mln/core/concept/image.hh>
-# include <mln/core/routine/duplicate.hh>
-
-# include <mln/util/ord.hh>
-
-# include <mln/data/fill_with_value.hh>
-# include <mln/data/paste.hh>
-# include <mln/level/compare.hh>
-
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
-
- template <typename T>
- T min(T v1, T v2)
- {
- return v1 < v2 ? v1 : v2;
- }
-
-
- template <typename I>
- I minimun(const I& ima1, const I& ima2)
- {
- mln_precondition(ima1.is_valid() && ima2.is_valid());
- mln_precondition(ima1.domain() == ima2.domain());
- I out(ima1.domain());
- mln_piter(I) p(ima1.domain());
- for_all(p)
- out(p) = ima1(p) < ima2(p) ? ima1(p) : ima2(p);
- return out;
- }
-
-
- template <typename I, typename P, typename N>
- mln_value(I) max_N(const I& ima, const P& p, const N& nbh)
- {
- mln_value(I) v = ima(p);
- mln_niter(N) n(nbh, p);
- for_all(n)
- if (ima.has(n) && ima(n) > v)
- v = ima(n);
- return v;
- }
-
-
- template <typename I, typename P, typename N>
- mln_value(I) max_Nminus(const I& ima, const P& p, const N& nbh)
- {
- mln_value(I) v = ima(p);
- mln_niter(N) n(nbh, p);
- for_all(n)
- if (ima.has(n) &&
- util::ord_strict(p.to_site(), n.to_site()) &&
- ima(n) > v)
- v = ima(n);
- return v;
- }
-
- template <typename I, typename P, typename N>
- mln_value(I) max_Nplus(const I& ima, const P& p, const N& nbh)
- {
- mln_value(I) v = ima(p);
- mln_niter(N) n(nbh, p);
- for_all(n)
- if (ima.has(n) &&
- util::ord_strict(n.to_site(), p.to_site()) &&
- ima(n) > v)
- v = ima(n);
- return v;
- }
-
-
- template <typename I>
- std::vector<unsigned> compute_histo(const I& ima)
- {
- std::vector<unsigned> h(256, 0);
- mln_piter(I) p(ima.domain());
- for_all(p)
- ++h[ima(p)];
- return h;
- }
-
-
-// template <typename I>
-// std::vector<mln_site(I)> histo_sort(const I& ima)
-// {
-// std::vector<unsigned> h = compute_histo(ima);
-// // preparing output data
-// std::vector<int> loc(256);
-// loc[0] = 0;
-// for (int l = 1; l < 256; ++l)
-// loc[l] = loc[l-1] + h[l-1];
-// std::vector<mln_site(I)> vec(ima.nsites());
-// // storing output data
-// mln_piter(I) p(ima.domain());
-// for_all(p)
-// vec[loc[ima(p)]++] = p;
-// return vec;
-// }
-
-
- template <typename I>
- std::vector<mln_site(I)> histo_reverse_sort(const I& ima)
- {
- std::vector<unsigned> h = compute_histo(ima);
- // preparing output data
- std::vector<int> loc(256);
- loc[255] = 0;
- for (int l = 254; l >= 0; --l)
- loc[l] = loc[l+1] + h[l+1];
- std::vector<mln_site(I)> vec(ima.nsites());
- // storing output data
- mln_piter(I) p(ima.domain());
- for_all(p)
- vec[loc[ima(p)]++] = p;
- return vec;
- }
-
-
-
- template <typename I, typename N>
- struct regional_maxima_t
- {
- typedef mln_site(I) point;
- typedef mln_ch_value(I, bool) image_bool;
- typedef mln_ch_value(I, point) image_point;
-
- // in:
- I f;
- N nbh;
-
- // out:
- I o;
-
- // aux:
- std::vector<point> S;
- image_bool deja_vu;
- image_bool attr;
- image_point parent;
-
- regional_maxima_t(const I& f, const N& nbh)
- : f(f), nbh(nbh)
- {
- initialize(o, f);
- initialize(parent, f);
- initialize(attr, f);
- initialize(deja_vu, f);
-
- // init
-
- data::fill_with_value(deja_vu, false);
- S = histo_reverse_sort(f);
-
- // first pass
-
- for (unsigned i = 0; i < S.size(); ++i)
- {
- point p = S[i];
-
- make_set(p);
- mln_niter(N) n(nbh, p);
- for_all(n)
- if (f.has(n) && deja_vu(n))
- {
- if (f(n) == f(p))
- do_union(n, p);
- else // f(n) > f(p)
- attr(p) = false;
- }
- deja_vu(p) = true;
- }
-
- // second pass
-
- const mln_value(I) zero = 0;
- for (int i = S.size() - 1; i >= 0; --i)
- {
- point p = S[i];
- if (parent(p) == p)
- o(p) = attr(p) ? f(p) : zero;
- else
- o(p) = o(parent(p));
- }
- }
-
- void make_set(const point& p)
- {
- parent(p) = p;
- attr(p) = true;
- }
-
- point find_root(const point& x)
- {
- if (parent(x) == x)
- return x;
- else
- return parent(x) = find_root(parent(x));
- }
-
- void do_union(const point& n, const point& p)
- {
- point r = find_root(n);
- if (r != p)
- {
- parent(r) = p;
- attr(p) = attr(p) && attr(r);
- }
- }
-
- };
-
-
- template <typename I, typename N>
- I
- regional_maxima(const I& f, const N& nbh)
- {
- regional_maxima_t<I, N> run(f, nbh);
- return run.o;
- }
-
-
- } // end of namespace mln::morpho::Rd
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_RD_UTILS_HH
Index: geraud/Rd/diff_pgm.cc
--- geraud/Rd/diff_pgm.cc (revision 3151)
+++ geraud/Rd/diff_pgm.cc (working copy)
@@ -1,43 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/level/compare.hh>
-#include <mln/value/int_u8.hh>
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " 1.pgm 2.pgm
out.pgm" << std::endl
- << "(october 2008)" << std::endl;
- exit(1);
-}
-
-
-unsigned char diff_abs(unsigned char c1,
- unsigned char c2)
-{
- return c1 > c2 ? c1 - c2 : c2 - c1;
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 4)
- usage(argv);
-
- using namespace mln;
- typedef image2d<value::int_u8> I;
-
- I ima1;
- io::pgm::load(ima1, argv[1]);
- I ima2;
- io::pgm::load(ima2, argv[2]);
-
- I out(ima1.domain());
- mln_piter_(I) p(ima1.domain());
- for_all(p)
- out(p) = diff_abs(ima1(p), ima2(p));
-
- io::pgm::save(out, argv[3]);
- return 0;
-}
Index: geraud/Rd/hybrid.cc
--- geraud/Rd/hybrid.cc (revision 3151)
+++ geraud/Rd/hybrid.cc (working copy)
@@ -1,53 +0,0 @@
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/value/int_u8.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include "hybrid.hh"
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c
output.pgm" << std::endl
- << "reconstruction by dilation (hybrid version; sep 2008)"
<< std::endl
- << "f = marker (to be dilated)" << std::endl
- << "g = mask (constraint >= f)" << std::endl
- << "c: 4 or 8" << std::endl;
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 5)
- usage(argv);
-
- using namespace mln;
- using value::int_u8;
-
- border::thickness = 0; // Safety.
-
- typedef image2d<int_u8> I;
-
- int c = atoi(argv[3]);
- if (c != 4 and c != 8)
- usage(argv);
-
- I f, g;
- io::pgm::load(f, argv[1]);
- io::pgm::load(g, argv[2]);
-
- if (not (f <= g))
- {
- std::cerr << "error: the precondition 'f <= g' is not
true" << std::endl;
- return 1;
- }
-
- I o = morpho::Rd::hybrid(f, g, (c == 4 ? c4() : c8()));
- io::pgm::save(o, argv[4]);
-}
Index: geraud/Rd/queue_based.cc
--- geraud/Rd/queue_based.cc (revision 3151)
+++ geraud/Rd/queue_based.cc (working copy)
@@ -1,51 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/value/int_u8.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include "queue_based.hh"
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c
output.pgm" << std::endl
- << "reconstruction by dilation (queue_based version; sep
2008)" << std::endl
- << "f = marker (to be dilated)" << std::endl
- << "g = mask (constraint >= f)" << std::endl
- << "c: 4 or 8" << std::endl;
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 5)
- usage(argv);
-
- using namespace mln;
- using value::int_u8;
-
- border::thickness = 0; // Safety.
-
- typedef image2d<int_u8> I;
-
- int c = atoi(argv[3]);
- if (c != 4 and c != 8)
- usage(argv);
-
- I f, g;
- io::pgm::load(f, argv[1]);
- io::pgm::load(g, argv[2]);
-
- if (! (f <= g))
- {
- std::cerr << "error: the precondition 'f <= g' is not
true" << std::endl;
- return 1;
- }
-
- I o = morpho::Rd::queue_based(f, g, (c == 4 ? c4() : c8()));
- io::pgm::save(o, argv[4]);
-}
Index: geraud/Rd/sequential_bench.hh
--- geraud/Rd/sequential_bench.hh (revision 3151)
+++ geraud/Rd/sequential_bench.hh (working copy)
@@ -1,100 +0,0 @@
-// 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_MORPHO_RD_SEQUENTIAL_HH
-# define MLN_MORPHO_RD_SEQUENTIAL_HH
-
-# include "utils.hh"
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
- template <typename I, typename N>
- I sequential(const I& f, const I& g, const N& nbh)
- {
- mln_precondition(f <= g);
-
- f.name_it("f");
- g.name_it("g");
-
- I o_(f.domain());
- o_.name_it("o_");
-
- unsigned nloops = 0;
-
- // initialisation
- I o = duplicate(f);
- o.name_it("o");
-
- bool stability;
- do
- {
- ++nloops;
-
- data::paste(o, o_); // memorisation
-
- // passe 1
- {
- mln_bkd_piter(I) p(f.domain());
- for_all(p)
- o(p) = min( max_Nminus(o, p, nbh), g(p) );
- }
-
- // passe 2
- {
- mln_fwd_piter(I) p(f.domain());
- for_all(p)
- o(p) = min( max_Nplus(o, p, nbh), g(p) );
- }
-
- stability = (o == o_);
- }
- while (not stability);
-
- std::cout << "nloops = " << nloops << std::endl;
-
- print_counts();
-
- mln_postcondition(o <= g);
- return o;
- }
-
- } // end of namespace mln::morpho::Rd
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_RD_SEQUENTIAL_HH
Index: geraud/Rd/min.cc
--- geraud/Rd/min.cc (revision 3151)
+++ geraud/Rd/min.cc (working copy)
@@ -1,42 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " 1.pgm 2.pgm
out.pgm" << std::endl
- << "(sep 2008)" << std::endl;
- exit(1);
-}
-
-
-template <typename I>
-I min(const I& ima1, const I& ima2)
-{
- mln_precondition(ima1.is_valid() and ima2.is_valid());
- mln_precondition(ima1.domain() == ima2.domain());
- I out(ima1.domain());
- mln_piter(I) p(ima1.domain());
- for_all(p)
- out(p) = ima1(p) < ima2(p) ? ima1(p) : ima2(p);
- return out;
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 4)
- usage(argv);
-
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<int_u8> I;
-
- I ima1 = io::pgm::load<int_u8>(argv[1]);
- I ima2 = io::pgm::load<int_u8>(argv[2]);
-
- io::pgm::save(min(ima1, ima2), argv[3]);
-}
Index: geraud/Rd/sequential.hh
--- geraud/Rd/sequential.hh (revision 3151)
+++ geraud/Rd/sequential.hh (working copy)
@@ -1,87 +0,0 @@
-// Copyright (C) 2007, 2008 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_MORPHO_RD_SEQUENTIAL_HH
-# define MLN_MORPHO_RD_SEQUENTIAL_HH
-
-# include "utils.hh"
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
- template <typename I, typename N>
- I sequential(const I& f, const I& g, const N& nbh)
- {
- mln_precondition(f <= g);
-
- I o_(f.domain());
-
- // initialisation
- I o = duplicate(f);
-
- bool stability;
- do
- {
- data::paste(o, o_); // memorisation
-
- // passe 1
- {
- mln_bkd_piter(I) p(f.domain());
- for_all(p)
- o(p) = min( max_Nminus(o, p, nbh), g(p) );
- }
-
- // passe 2
- {
- mln_fwd_piter(I) p(f.domain());
- for_all(p)
- o(p) = min( max_Nplus(o, p, nbh), g(p) );
- }
-
- stability = (o == o_);
- }
- while (not stability);
-
- mln_postcondition(o <= g);
- return o;
- }
-
- } // end of namespace mln::morpho::Rd
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_RD_SEQUENTIAL_HH
Index: geraud/Rd/debase.union_find.hh
--- geraud/Rd/debase.union_find.hh (revision 3151)
+++ geraud/Rd/debase.union_find.hh (working copy)
@@ -1,165 +0,0 @@
-// Copyright (C) 2007, 2008 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 OLN_MORPHO_RD_UNION_FIND_HH
-# define OLN_MORPHO_RD_UNION_FIND_HH
-
-# include <oln/morpho/Rd/utils.hh>
-
-
-namespace oln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
-
- template <typename I, typename N>
- struct union_find_t
- {
- typedef oln_point(I) point;
-
- // in:
- I f, g;
- N nbh;
-
- // out:
- I o;
-
- // aux:
- std::vector<point> S;
- I data;
- oln_plain_value(I, bool) is_proc;
- oln_plain_value(I, point) parent;
-
- union_find_t(const I& f, const I& g, const N& nbh)
- : f(f), g(g), nbh(nbh)
- {
- prepare(o, with, f);
- prepare(parent, with, f);
- prepare(is_proc, with, f);
- prepare(data, with, f);
-
- // init
-
- std::cout << "0 ";
- data::fill(is_proc, false);
- S = histo_reverse_sort(g);
-
- // first pass
-
- std::cout << "1 ";
- for (unsigned i = 0; i < S.size(); ++i)
- {
- point p = S[i];
-
- make_set(p);
- oln_niter(N) n(nbh, p);
- for_all(n)
- if (f.has(n) and is_proc(n))
- do_union(n, p);
- is_proc(p) = true;
- }
-
- // second pass
-
- std::cout << "2 ";
- data::fill(is_proc, false);
- for (int i = S.size() - 1; i >= 0; --i)
- {
- point p = S[i];
- assert(is_proc(p) == false);
- if (parent(p) == p)
- o(p) = data(p) == 255 ? g(p) : data(p);
- else
- {
- assert(is_proc(parent(p)) == true);
- o(p) = o(parent(p));
- }
- is_proc(p) = true;
- }
-
- }
-
- void make_set(const point& p)
- {
- parent(p) = p;
- data(p) = f(p);
- }
-
- point find_root(const point& x)
- {
- if (parent(x) == x)
- return x;
- else
- return parent(x) = find_root(parent(x));
- }
-
- bool equiv(const point& r, const point& p)
- {
- return g(r) == g(p) or g(p) >= data(r);
- }
-
- void do_union(const point& n, const point& p)
- {
- point r = find_root(n);
- if (r != p)
- {
- if (equiv(r, p))
- {
- parent(r) = p;
- if (data(r) > data(p))
- data(p) = data(r); // increasing criterion
- }
- else
- data(p) = 255;
- }
- }
-
- };
-
-
- template <typename I, typename N>
- I union_find(const I& f, const I& g, const N& nbh)
- {
- precondition(f <= g);
- union_find_t<I, N> run(f, g, nbh);
- return run.o;
- }
-
-
- } // end of namespace oln::morpho::Rd
-
- } // end of namespace oln::morpho
-
-} // end of namespace oln
-
-
-#endif // ! OLN_MORPHO_RD_UNION_FIND_HH
Index: geraud/Rd/union_find.cc
--- geraud/Rd/union_find.cc (revision 3151)
+++ geraud/Rd/union_find.cc (working copy)
@@ -1,52 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/value/int_u8.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include "union_find.hh"
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c
output.pgm" << std::endl
- << "reconstruction by dilation (union_find version; sep
2008)" << std::endl
- << "f = marker (to be dilated)" << std::endl
- << "g = mask (constraint >= f)" << std::endl
- << "c: 4 or 8" << std::endl;
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 5)
- usage(argv);
-
- using namespace mln;
- using value::int_u8;
-
- border::thickness = 0; // Safety.
-
- typedef image2d<int_u8> I;
-
- int c = atoi(argv[3]);
- if (c != 4 and c != 8)
- usage(argv);
-
- I f, g;
- io::pgm::load(f, argv[1]);
- io::pgm::load(g, argv[2]);
-
- if (! (f <= g))
- {
- std::cerr << "error: the precondition 'f <= g' is not
true" << std::endl;
- return 1;
- }
-
- I o = morpho::Rd::union_find(f, g, (c == 4 ? c4() : c8()));
- io::pgm::save(o, argv[4]);
-}
Index: geraud/Rd/svg.queue_based.hh
--- geraud/Rd/svg.queue_based.hh (revision 3151)
+++ geraud/Rd/svg.queue_based.hh (working copy)
@@ -1,118 +0,0 @@
-// 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_MORPHO_RD_QUEUE_BASED_HH
-# define MLN_MORPHO_RD_QUEUE_BASED_HH
-
-# include <queue>
-# include "utils.hh"
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace Rd
- {
-
- template <typename I, typename N>
- I queue_based(const I& f, const I& g, const N& nbh,
- bool echo = false)
- {
- if (echo) std::cout << std::endl;
-
- f.name_it("f");
- g.name_it("g");
-
- typedef mln_point(I) point;
- std::queue<point> q;
- I o;
- o.name_it("o");
-
- unsigned n_init_pushs = 0, n_body_pushs = 0, n_pops = 0;
-
- // initialisation
- {
- o = regional_maxima(f, nbh);
- // p in M <=> o(p) != 0
- if (echo) debug::println(o);
-
- mln_piter(I) p(f.domain());
- mln_niter(N) n(nbh, p);
-
- for_all(p) if (o(p) != 0) // p in M
- for_all(n) if (f.has(n) and o(n) == 0) // n not in M
- {
- q.push(p);
- ++n_init_pushs;
- break;
- }
- }
-
- // propagation
- {
- point p;
- mln_niter(N) n(nbh, p);
- while (not q.empty())
- {
- p = q.front();
- if (echo) std::cout << std::endl << "pop " << p
<< " :";
- q.pop();
- ++n_pops;
- for_all(n) if (f.has(n))
- {
- if (o(n) < o(p) and o(n) != g(n))
- {
- o(n) = min(o(p), g(n));
- if (echo) std::cout << " push " << n;
- q.push(n);
- ++n_body_pushs;
- }
- }
- }
- if (echo) std::cout << std::endl;
- }
-
- std::cout << "n_init_pushs = " << n_init_pushs << std::endl
- << "n_body_pushs = " << n_body_pushs << std::endl
- << "n_pops = " << n_pops << std::endl;
-
- print_counts();
-
- return o;
- }
-
- } // end of namespace mln::morpho::Rd
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_RD_QUEUE_BASED_HH
Index: geraud/dmap.cc
--- geraud/dmap.cc (revision 3151)
+++ geraud/dmap.cc (working copy)
@@ -1,131 +0,0 @@
-#include <vector>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/w_window2d_int.hh>
-#include <mln/debug/println.hh>
-#include <mln/data/fill.hh>
-#include <mln/level/stretch.hh>
-#include <mln/accu/max.hh>
-#include <mln/io/pbm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
- template<typename I, typename W>
- mln_ch_value(I, unsigned) dmap(const Image<I>& input_,
- const Weighted_Window<W>& win_)
- {
- const I& input = exact(input_);
- const W& win = exact(win_);
- mln_precondition(input.is_valid());
-
- typedef std::vector<mln_site(I)> bucket_t;
-
- // Initialization of distance.
- mln_ch_value(I, unsigned) distance;
- initialize(distance, input);
-
- // Mod determination.
- accu::max<unsigned> max;
- for (unsigned i = 0; i < win.size(); ++i)
- max.take(win.w(i));
- unsigned mod = unsigned(max) + 1;
-
- // Aux data.
- std::vector<bucket_t> bucket(mod);
- unsigned bucket_size = 0;
-
- // Initialization.
- {
- mln_piter(I) p(input.domain());
- mln_qiter(W) q(win, p);
- for_all(p)
- if (input(p))
- {
- distance(p) = literal::zero;
- for_all(q)
- if (input.has(q) && ! input(q))
- {
- bucket[0].push_back(p);
- ++bucket_size;
- break;
- }
- }
- else
- distance(p) = mln_max(unsigned);
- }
-
- // Propagation.
- {
- mln_site(I) p;
- mln_qiter(W) q(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 (distance(p) < d)
- // p has already been processed, having a distance less than d.
- continue;
-
- for_all(q)
- if (distance.has(q) && distance(q) > d)
- {
- unsigned d_ = d + q.w();
-
- if (d_ < distance(q))
- {
- distance(q) = d_;
- bucket[d_ % mod].push_back(q);
- ++bucket_size;
- }
- }
- }
- bucket_size -= bucket_d.size();
- bucket_d.clear();
- }
-
- } // end of propagation.
-
- return distance;
- }
-
-} // end of namespace mln
-
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- const unsigned n = 9;
- image2d<bool> ima(n, n);
- data::fill(ima, false);
- opt::at(ima, n / 2, n / 2) = true;
-
-// int ws[] = { 3, 2, 3,
-// 2, 0, 2,
-// 3, 2, 3 };
-
- 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 }; // coef = 4.1203
-
- w_window2d_int win = make::w_window2d(ws);
-
- image2d<unsigned> d = dmap(ima, win);
- debug::println(d);
-
-// image2d<int_u8> out;
-// level::stretch(d, out);
-// io::pgm::save(out, "out.pgm");
-}
Index: geraud/compute_parent_more.hh
--- geraud/compute_parent_more.hh (revision 3151)
+++ geraud/compute_parent_more.hh (working copy)
@@ -1,191 +0,0 @@
-// 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_MORPHO_TREE_COMPUTE_PARENT_HH
-# define MLN_MORPHO_TREE_COMPUTE_PARENT_HH
-
-/// \file mln/morpho/tree/compute_parent.hh
-///
-/// Compute a canonized tree from an image.
-///
-/// \todo Specialize for low quant (and try fastest).
-
-# include <mln/core/concept/image.hh>
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/data/fill.hh>
-
-
-namespace mln
-{
-
- namespace morpho
- {
-
- namespace tree
- {
-
-
- template <typename T>
- inline
- mln_psite(T)
- zfind_root(T& zpar, const mln_psite(T)& x)
- {
- mlc_equal(mln_value(T), mln_psite(T))::check();
- if (zpar(x) == x)
- return x;
- else
- return zpar(x) = zfind_root(zpar, zpar(x));
- }
-
-
-
- template <typename I, typename N, typename S>
- inline
- mln_ch_value(I, mln_psite(I))
- compute_parent_more(const Image<I>& f_,
- const Neighborhood<N>& nbh_,
- const Site_Set<S>& s_)
- {
- typedef mln_psite(I) P;
-
- const I& f = exact(f_);
- const N& nbh = exact(nbh_);
- const S& s = exact(s_);
-
- // Auxiliary data.
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, P) parent;
- mln_ch_value(I, P) zpar;
-
- initialize(deja_vu, f);
- initialize(parent, f);
- initialize(zpar, f);
-
- typedef mln_vset(S) Vs;
- typedef mln_pset(S) Ps;
- S roots;
-
- // Initialization.
- data::fill(deja_vu, false);
- unsigned nnodes = 0;
-
- // Body.
- mln_bkd_viter(Vs) v(s.values());
- for_all(v)
- {
- if (s(v).is_empty())
- continue;
-
- mln_bkd_piter(Ps) p(s(v));
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- // Make-Set.
- parent(p) = p;
- zpar(p) = p;
-
- for_all(n)
- if (f.domain().has(n) && deja_vu(n))
- {
- // Do-Union.
- P r = internal::zfind_root(zpar, n);
- if (r != p)
- {
- parent(r) = p;
- zpar(r) = p;
- }
- }
- deja_vu(p) = true;
- }
-
-
- /*
-
- // Canonization on the-fly.
- {
- // Intra-v:
- mln_fwd_piter(Ps) p(s(v));
- for_all(p)
- parent(p) = parent(parent(p));
-
- // Inter "previous v and current v":
- mln_piter(Ps) r(v_roots);
- for_all(r)
- parent(r) = parent(parent(r));
- v_roots.clear();
-
- {
- // New roots:
- mln_piter(Ps) p(s(v));
- for_all(p)
- if (parent(p) == p)
- v_roots.insert(p);
- nnodes += v_roots.nsites();
- }
- }
-
- */
-
- // Storing roots.
- {
- mln_piter(Ps) p(s(v));
- for_all(p)
- if (parent(p) == p)
- roots(v).insert(p);
- nnodes += roots(v).nsites();
- }
-
- } // end of "for_all(v)"
-
-
- // Canonization.
- {
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- P q = parent(p);
- if (f(parent(q)) == f(q))
- parent(p) = parent(q);
- }
- }
-
- std::cout << "roots = " << roots << std::endl;
- std::cout << "nnodes = " << nnodes << std::endl;
-
-
- return parent;
- }
-
-
- } // end of namespace mln::morpho::tree
-
- } // end of namespace mln::morpho
-
-} // end of namespace mln
-
-
-#endif // ! MLN_MORPHO_TREE_COMPUTE_PARENT_HH
Index: geraud/tufa_2008/steps.0.cc
--- geraud/tufa_2008/steps.0.cc (revision 3151)
+++ geraud/tufa_2008/steps.0.cc (working copy)
@@ -1,171 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/steps.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/morpho/tree/data.hh>
-
-#include <mln/accu/count.hh>
-
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/closing_area.hh>
-#include <mln/data/fill.hh>
-#include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
- template <typename I, typename A, typename N>
- mln_concrete(I) filtering(const I& f, const A& a, const N& nbh,
mln_value(A) lambda)
- {
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(a);
-
- // s maps increasing attributes.
-
- mln_concrete(I) out;
- initialize(out, f);
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, bool) deja_vu;
- {
- initialize(par, f);
- mln_piter(A) p(par.domain());
- for_all(p)
- par(p) = p;
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
- }
-
- // First pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (a.domain().has(n) && deja_vu(n))
- {
- r = find_root__(par, n);
- if (r != p)
- if (f(r) == f(p) || a(r) < lambda)
- par(r) = p; // Union.
- }
- deja_vu(p) = true;
- }
- }
-
- // Second pass.
- {
- mln_bkd_piter(S) p(s);
- for_all(p)
- if (par(p) == p)
- out(p) = f(p);
- else
- out(p) = out(par(p));
- }
- return out;
- }
-
-
-} // mln
-
-
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- int_u8 n;
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, "../../../img/fly.pgm");
- debug::println("f =", f);
-
- debug::println("ref =", morpho::closing_area(f, c4(), 10));
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- morpho::tree::data<I,S> t(f, s, c4());
- accu::count< util::pix<I> > attr;
-
- image2d<unsigned> a = morpho::tree::compute_attribute_image(attr, t);
- I g = filtering(f, a, c4(), 10);
- debug::println("g =", g);
-
- {
- S s = level::sort_psites_decreasing(g);
- morpho::tree::data<I,S> t(g, s, c4());
- image2d<unsigned> a_g = morpho::tree::compute_attribute_image(attr, t);
- debug::println("a(f) =", a);
- debug::println("a(g) =", a_g);
- }
-
-}
Index: geraud/tufa_2008/steps.1.cc
--- geraud/tufa_2008/steps.1.cc (revision 3151)
+++ geraud/tufa_2008/steps.1.cc (working copy)
@@ -1,274 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/steps.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/morpho/tree/data.hh>
-
-#include <mln/accu/count.hh>
-#include <mln/util/set.hh>
-
-#include <mln/labeling/regional_minima.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/closing_area.hh>
-#include <mln/data/fill.hh>
-#include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
- template <typename I, typename A, typename N>
- void run_run(const I& f, const A& a, const N& nbh)
- {
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(a);
- // s maps increasing attributes.
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, util::set<unsigned>) labels;
- unsigned nbassins, current_n;
-
-
- // Initialization.
- {
- mln_piter(A) p(f.domain());
-
- // parent
- initialize(par, f);
- for_all(p)
- par(p) = p;
-
- // deja_vu
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
-
- // labels
- mln_ch_value(I, unsigned) regmin = labeling::regional_minima(a, nbh,
- nbassins);
- debug::println(regmin);
- initialize(labels, f);
- for_all(p)
- if (regmin(p) != 0) // p in a reg min of the attribute image
- labels(p).insert(regmin(p));
- }
-
- current_n = nbassins;
-
- // First pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (a.domain().has(n) && deja_vu(n))
- {
- r = find_root__(par, n);
- if (r != p)
- {
- par(r) = p; // Union.
-
- // logging the different cases
- if (labels(p).is_empty() && labels(r).is_empty())
- {
- std::cout << "x";
-
- // It can happen with:
- // M M m
- // (m a min, M a flat zone)
- // During the pass:
- // M M {m}
- // then the 1st point is processed
- // {} M {m}
- // and when processing the 2nd point
- // r={} p={} {m}
- // the (left) neighbor of p has an empty set such as p.
-
-// // Extra log.
-// std::cout << std::endl
-// << "p = " << p << " "
-// << "r = " << r << std::endl;
-// debug::println(labels);
- }
- else
- if (labels(p).is_empty() || labels(r).is_empty())
- {
- std::cout << (labels(p).is_empty() ? 'p' : 'r');
- }
- else
- if (labels(p) == labels(r))
- {
- std::cout << "=";
-// // Extra log.
-// std::cout << std::endl
-// << "p = " << p << " "
-// << "r = " << r << std::endl;
-// debug::println(labels);
- }
- else
- std::cout << ".";
- // end of log
-
- // The invariants below are erroneous.
-// mln_invariant(! (labels(p).is_empty() && labels(r).is_empty()));
-// mln_invariant(labels(p) != labels(r));
-
- // Either:
- // one of the two label sets is empty (and the other is not)
- // or:
- // both label sets are not empty then they differ.
-
- // More restrictively:
-// mln_invariant(! labels(r).is_empty());
-
- if (labels(p).is_empty())
- {
- labels(p).insert(labels(r));
- }
- else
- {
-
-// std::cout << std::endl
-// << "at " << p << std::endl
-// << "before:" << std::endl;
-// debug::println(labels);
-
- unsigned
- np = labels(p).nelements(),
- nr = labels(r).nelements();
- labels(p).insert(labels(r));
- unsigned
- n = labels(p).nelements(),
- dnp = n - np,
- dnr = n - nr,
- delta_n = std::min(dnp, dnr);
-
- // The invariant below is erroneous.
-// mln_invariant(delta_n != 0);
-
-
-// std::cout << "delta = " << delta_n << std::endl
-// << "after: " << std::endl;
-// debug::println(labels);
-
-
- // We can have the three cases below:
- if (dnr > dnp)
- std::cout << '>';
- else
- if (dnr < dnp)
- std::cout << '<';
- else
- std::cout << '~';
- std::cout << '(' << delta_n << ')';
- }
- }
- }
- deja_vu(p) = true;
- }
- }
-
- std::cout << std::endl;
-// debug::println(labels);
- }
-
-
-} // mln
-
-
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- int_u8 n;
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, "../../../img/tiny.pgm");
-// debug::println("f =", f);
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- morpho::tree::data<I,S> t(f, s, c4());
- accu::count< util::pix<I> > attr;
-
- image2d<unsigned> a = morpho::tree::compute_attribute_image(attr, t);
- run_run(f, a, c4());
-
-// {
-// S s = level::sort_psites_decreasing(g);
-// morpho::tree::data<I,S> t(g, s, c4());
-// image2d<unsigned> a_g = morpho::tree::compute_attribute_image(attr, t);
-// debug::println("a(f) =", a);
-// debug::println("a(g) =", a_g);
-// }
-
-}
Index: geraud/tufa_2008/gradient.cc
--- geraud/tufa_2008/gradient.cc (revision 3151)
+++ geraud/tufa_2008/gradient.cc (working copy)
@@ -1,60 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/gradient.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/morpho/elementary/gradient.hh>
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
output.pgm" << std::endl;
- std::cerr << "elementary gradient with c4" << std::endl;
- std::abort();
-}
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 3)
- usage(argv);
-
- image2d<int_u8> f;
- io::pgm::load(f, argv[1]);
- io::pgm::save(morpho::elementary::gradient(f, c4()),
- argv[2]);
-}
Index: geraud/tufa_2008/closing.cc
--- geraud/tufa_2008/closing.cc (revision 3151)
+++ geraud/tufa_2008/closing.cc (working copy)
@@ -1,64 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/closing.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/morpho/elementary/gradient.hh>
-#include <mln/morpho/closing_volume.hh>
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
lambda output.pgm" << std::endl;
- std::abort();
-}
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 4)
- usage(argv);
-
- image2d<int_u8> f;
- io::pgm::load(f, argv[1]);
- unsigned lambda = std::atoi(argv[2]);
- io::pgm::save(morpho::closing_volume(f,
- c4(),
- lambda),
- argv[3]);
-}
Index: geraud/tufa_2008/steps.2.cc
--- geraud/tufa_2008/steps.2.cc (revision 3151)
+++ geraud/tufa_2008/steps.2.cc (working copy)
@@ -1,259 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/steps.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/morpho/tree/data.hh>
-
-#include <mln/accu/count.hh>
-#include <mln/util/set.hh>
-
-#include <mln/labeling/regional_minima.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/closing_area.hh>
-#include <mln/data/fill.hh>
-#include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
- template <typename I, typename A, typename N>
- mln_ch_value(I, util::set<unsigned>)
- compute_labels(const I& f, const A& a, const N& nbh,
- unsigned n_objects,
- bool echo = false)
- {
- if (echo)
- debug::println("f =", f);
-
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(a);
- // s maps increasing attributes.
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, util::set<unsigned>) labels;
- unsigned nbassins, current_n;
-
- // Initialization.
- {
- mln_piter(A) p(f.domain());
-
- // parent
- initialize(par, f);
- for_all(p)
- par(p) = p;
-
- // deja_vu
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
-
- // labels
- mln_ch_value(I, unsigned) regmin = labeling::regional_minima(a, nbh,
- nbassins);
- if (n_objects >= nbassins)
- {
- std::cerr << "The number of expected objects is higher than the number of
regional minima!" << std::endl;
- std::abort();
- }
-
- if (echo)
- debug::println("regmin(f) =", regmin);
-
- initialize(labels, f);
- for_all(p)
- if (regmin(p) != 0) // p in a reg min of the attribute image
- labels(p).insert(regmin(p));
- }
-
- current_n = nbassins;
-
- // First pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (a.domain().has(n) && deja_vu(n))
- {
- r = find_root__(par, n);
- if (r != p)
- {
- par(r) = p; // Union.
-
- if (labels(r).is_empty())
- // No-op.
- ;
- else
- if (labels(p).is_empty())
- labels(p) = labels(r);
- else
- if (labels(p) == labels(r))
- // No-op.
- ;
- else
- {
- labels(p).insert(labels(r));
- --current_n;
- if (current_n == n_objects && echo)
- {
- // Filtering.
- mln_concrete(I) g;
- initialize(g, f);
- mln_bkd_piter(S) p(s);
- for_all(p)
- if (par(p) == p)
- g(p) = f(p);
- else
- g(p) = g(par(p));
- debug::println("g =", g);
-
- // Testing.
- unsigned n_result;
- mln_ch_value(I, unsigned) g_regmin;
- g_regmin = labeling::regional_minima(g, nbh, n_result);
- debug::println("regmin(g) =", g_regmin);
-
- mln_invariant(n_result == n_objects);
- }
- }
- }
- }
- deja_vu(p) = true;
- }
- }
-
- mln_invariant(current_n == 1); // All labels are merged into a single set.
-
- return labels;
- }
-
-
-} // mln
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm n
echo" << std::endl;
- std::cerr << "n: number of expected objects (n > 0)" <<
std::endl;
- std::cerr << "echo: 0 (silent) or 1 (verbose)" << std::endl;
- std::cerr << "merge using sets of labels from regional minima and save the
highest label image" << std::endl;
- std::abort();
-}
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 4)
- usage(argv);
-
- typedef image2d<int_u8> I;
- I f;
- // input image
- io::pgm::load(f, argv[1]);
-
- // n
- int n = std::atoi(argv[2]);
- if (n <= 0)
- usage(argv);
-
- // echo
- int echo = std::atoi(argv[3]);
- if (echo != 0 && echo != 1)
- usage(argv);
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- morpho::tree::data<I,S> t(f, s, c4());
- accu::count< util::pix<I> > attr;
-
- image2d<unsigned> a = morpho::tree::compute_attribute_image(attr, t);
-
-
- image2d< util::set<unsigned> > labels = compute_labels(f, a, c4(), n,
echo);
- if (echo)
- debug::println("labels =", labels);
-
- {
- image2d<unsigned> lab(f.domain());
- mln_piter_(I) p(f.domain());
- for_all(p)
- {
- mln_assertion(! labels(p).is_empty());
- lab(p) = labels(p).last_element();
- }
- if (echo)
- debug::println("max of labels (clearly NOT the objects image!) =", lab);
-
- // We can observe that we do NOT get objects this way...
- }
-
-}
Index: geraud/tufa_2008/opening.cc
--- geraud/tufa_2008/opening.cc (revision 3151)
+++ geraud/tufa_2008/opening.cc (working copy)
@@ -1,63 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/opening.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/morpho/opening_volume.hh>
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
lambda output.pgm" << std::endl;
- std::abort();
-}
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 4)
- usage(argv);
-
- image2d<int_u8> f, g;
- io::pgm::load(f, argv[1]);
- unsigned lambda = std::atoi(argv[2]);
- initialize(g, f);
- morpho::opening_volume(f, c4(), lambda, g);
- io::pgm::save(g,
- argv[3]);
-}
Index: geraud/tufa_2008/steps.3.cc
--- geraud/tufa_2008/steps.3.cc (revision 3151)
+++ geraud/tufa_2008/steps.3.cc (working copy)
@@ -1,186 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/steps.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/morpho/tree/data.hh>
-
-#include <mln/accu/count.hh>
-#include <mln/util/set.hh>
-
-#include <mln/labeling/regional_minima.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/closing_area.hh>
-#include <mln/data/fill.hh>
-
-#include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
- template <typename I, typename A, typename N>
- void run_run(const I& f, const A& a, const N& nbh)
- {
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(a);
- // s maps increasing attributes.
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, util::set<unsigned>) labels;
- unsigned nbassins, current_n;
-
-
- // Initialization.
- {
- mln_piter(A) p(f.domain());
-
- // parent
- initialize(par, f);
- for_all(p)
- par(p) = p;
-
- // deja_vu
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
-
- // labels
- mln_ch_value(I, unsigned) regmin = labeling::regional_minima(a, nbh,
- nbassins);
- initialize(labels, f);
- for_all(p)
- if (regmin(p) != 0) // p in a reg min of the attribute image
- labels(p).insert(regmin(p));
- }
-
- current_n = nbassins;
-
- // First pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (a.domain().has(n) && deja_vu(n))
- {
- r = find_root__(par, n);
- if (r != p)
- {
- par(r) = p; // Union.
-
- if (labels(r).is_empty())
- // No-op.
- ;
- else
- if (labels(p).is_empty())
- labels(p) = labels(r);
- else
- if (labels(p) == labels(r))
- // No-op.
- ;
- else
- {
- labels(p).insert(labels(r));
- --current_n;
- }
- }
- }
- deja_vu(p) = true;
- }
- }
-
- std::cout << std::endl;
- std::cout << "end = " << current_n << std::endl;
- }
-
-
-} // mln
-
-
-
-
-int main(int, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- int_u8 n;
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- morpho::tree::data<I,S> t(f, s, c4());
- accu::count< util::pix<I> > attr;
-
- image2d<unsigned> a = morpho::tree::compute_attribute_image(attr, t);
- run_run(f, a, c4());
-
-}
Index: geraud/tufa_2008/steps.2b.cc
--- geraud/tufa_2008/steps.2b.cc (revision 3151)
+++ geraud/tufa_2008/steps.2b.cc (working copy)
@@ -1,185 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/steps.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/morpho/tree/data.hh>
-
-#include <mln/accu/count.hh>
-#include <set>
-
-#include <mln/labeling/regional_minima.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/closing_area.hh>
-#include <mln/data/fill.hh>
-#include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
- template <typename I, typename A, typename N>
- void run_run(const I& f, const A& a, const N& nbh)
- {
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(a);
- // s maps increasing attributes.
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, std::set<unsigned>) labels;
- unsigned nbassins, current_n;
-
-
- // Initialization.
- {
- mln_piter(A) p(f.domain());
-
- // parent
- initialize(par, f);
- for_all(p)
- par(p) = p;
-
- // deja_vu
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
-
- // labels
- mln_ch_value(I, unsigned) regmin = labeling::regional_minima(a, nbh,
- nbassins);
- initialize(labels, f);
- for_all(p)
- if (regmin(p) != 0) // p in a reg min of the attribute image
- labels(p).insert(regmin(p));
- }
-
- current_n = nbassins;
-
- // First pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (a.domain().has(n) && deja_vu(n))
- {
- r = find_root__(par, n);
- if (r != p)
- {
- par(r) = p; // Union.
-
- if (labels(r).empty())
- // No-op.
- ;
- else
- if (labels(p).empty())
- labels(p) = labels(r);
- else
- if (labels(p) == labels(r))
- // No-op.
- ;
- else
- {
- labels(p).insert(labels(r).begin(), labels(r).end());
- --current_n;
- }
- }
- }
- deja_vu(p) = true;
- }
- }
-
- std::cout << std::endl;
- std::cout << "end = " << current_n << std::endl;
- }
-
-
-} // mln
-
-
-
-
-int main(int, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- int_u8 n;
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- morpho::tree::data<I,S> t(f, s, c4());
- accu::count< util::pix<I> > attr;
-
- image2d<unsigned> a = morpho::tree::compute_attribute_image(attr, t);
- run_run(f, a, c4());
-
-}
Index: geraud/tufa_2008/filter_n.cc
--- geraud/tufa_2008/filter_n.cc (revision 3151)
+++ geraud/tufa_2008/filter_n.cc (working copy)
@@ -1,341 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/soluce.cc
-
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/morpho/tree/data.hh>
-
-#include <mln/accu/count.hh>
-#include <mln/util/set.hh>
-
-#include <mln/labeling/regional_minima.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/closing_area.hh>
-#include <mln/data/fill.hh>
-#include <mln/opt/at.hh>
-
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
- template <typename I>
- struct my_less_
- {
- const I& ima_;
-
- inline
- my_less_(const I& ima)
- : ima_(ima)
- {
- }
-
- inline
- bool operator()(const mln_site(I)& lhs,
- const mln_site(I)& rhs) const
- {
- return util::ord_strict(ima_(lhs), ima_(rhs))
- || (ima_(lhs) == ima_(rhs)
- &&
- util::ord_strict(lhs, rhs));
- }
- };
-
-
- template <typename I, typename S>
- p_array<mln_site(I)> my_sort_increasing(const I& ima, const S& s)
- {
- p_array<mln_site(I)> v;
- convert::from_to(s, v);
- std::sort(v.hook_std_vector_().begin(), v.hook_std_vector_().end(),
- my_less_<I>(ima));
- return v;
- }
-
-
-
- // FIXME: HERE
-
- template <typename A, typename T, typename N>
- inline
- mln_concrete(typename T::function)
- get_attribute_image(const A& a, const T& t, const N& nbh,
- unsigned n_objects,
- bool echo = false)
- {
- typedef typename T::function I;
-
-
- unsigned n_regmins_f;
- mln_ch_value(I, unsigned) regmins_f = labeling::regional_minima(t.f(), nbh,
n_regmins_f);
- if (echo)
- {
- debug::println("f =", t.f());
- debug::println("regmins(f) =", regmins_f);
- debug::println("par on nodes = ", t.parent_image() | t.nodes());
- std::cout << "n regmins(f) = " << n_regmins_f << std::endl
- << std::endl;
- }
- if (n_objects >= n_regmins_f)
- {
- std::cout << "warning: number of expected objects is greater than number of
regmins!" << std::endl;
- std::cout << "aborting..." << std::endl;
- return duplicate(t.f());
- }
-
- // Compute attribute on nodes.
- // ---------------------------
-
-
- mln_ch_value(I, A) acc;
- initialize(acc, t.f());
-
-
- mln_ch_value(I, unsigned) nchildren;
- initialize(nchildren, t.f());
- data::fill(nchildren, 0);
-
- {
- // Transmit "dynamic data" (state) of 'a' to every values of
- // 'acc'. It is usually a no-op (so useless) except for a
- // few accumulators, e.g., for accu::rank which has the 'k'
- // attribute.
- data::fill(acc, a);
- }
- {
- // Initialize every attribute with the corresponding pixel.
- mln_piter(I) p(t.f().domain());
- for_all(p)
- acc(p).take_as_init(make::pix(t.f(), p));
- }
- {
- mln_fwd_piter(T) p(t.domain());
- // Propagate attribute from a site to its parent.
- for_all(p)
- if (! t.is_root(p))
- {
- acc(t.parent(p)).take(acc(p));
- if (t.is_a_node(p))
- ++nchildren(t.parent(p)); // so parent(p) is a node
- }
- // Back-propagate attribute from a node to sites of its
- // component. Below, p is a non-node component site and
- // parent(p) is a node, that is, the site representative of
- // the component p belongs to.
- for_all(p)
- if (! t.is_a_node(p))
- {
- mln_assertion(t.is_a_node(t.parent(p)));
- acc(p) = acc(t.parent(p));
- }
- }
-
- if (echo)
- debug::println("nchildren =", nchildren | t.nodes());
-
- typedef typename T::function I;
- mln_ch_value(I, mln_result(A)) attr;
- {
- // Change accumulator into its result.
- initialize(attr, acc);
- mln_piter(I) p(t.f().domain());
- for_all(p)
- if (t.is_a_node(p))
- attr(p) = acc(p).to_result();
- }
-
- if (echo)
- debug::println("attr on nodes = ", attr | t.nodes());
-
-
-
- // ...
- // ---------------------------
-
-
- unsigned lambda = mln_max(unsigned);
-
-
- typedef p_array<mln_site(I)> S;
- S s = my_sort_increasing(attr, t.nodes());
-
- const typename T::parent_t& par = t.parent_image();
-
- unsigned
- count = n_regmins_f,
- less = 0;
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- if (attr(p) < lambda && par(p) != p)
- {
- mln_assertion(nchildren(par(p)) > 0);
- --nchildren(par(p));
- if (nchildren(par(p)) != 0)
- {
- if (count <= n_objects)
- {
- ++less; // minus 1 object wrt the expected number!
- }
- --count;
- if (count == n_objects)
- {
- lambda = attr(p) + 1;
- std::cout << "lambda = " << lambda << std::endl
- << std::endl;
- // break; // Stop iterations.
- }
- }
- }
- }
-
- if (less != 0)
- std::cerr << "WARNING: less objects (" << less <<
") than expected..." << std::endl
- << std::endl;
-
- if (echo)
- debug::println("nchildren =", nchildren | t.nodes());
-
-
- // Filtering.
- mln_concrete(I) g;
- {
- initialize(g, t.f());
- mln_bkd_piter(T) p(t.domain());
- for_all(p)
- if (t.is_a_node(p) && attr(p) >= lambda)
- g(p) = t.f(p);
- else
- g(p) = g(par(p));
-
- if (echo)
- debug::println("g =", g);
- }
-
- // Test!
- {
- mln_concrete(I) g_ref = morpho::closing_area(t.f(), nbh, lambda);
- if (echo)
- debug::println("g_ref =", g_ref);
-
- unsigned n_regmins_g_ref;
- mln_ch_value(I, unsigned) regmin_g = labeling::regional_minima(g_ref, nbh,
n_regmins_g_ref);
- if (echo)
- std::cout << "n_regmins(g_ref) = " << n_regmins_g_ref <<
std::endl
- << std::endl;
-
- if (g != g_ref)
- std::cerr << "OOPS: g DIFFERS FROM ref!" << std::endl
- << std::endl;
-
- bool consistency = (n_regmins_g_ref + less == n_objects);
- if (consistency == false)
- std::cerr << "OOPS: INCONSISTENCY (BUG...)!" << std::endl
- << std::endl;
- }
-
- return g;
- }
-
-
-} // mln
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm n
output.pgm echo" << std::endl;
- std::cerr << "n: number of expected objects (n > 0)" <<
std::endl;
- std::cerr << "echo: 0 (silent) or 1 (verbose)" << std::endl;
- std::cerr << "filter" << std::endl;
- std::abort();
-}
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 5)
- usage(argv);
-
- typedef image2d<int_u8> I;
- I f;
- // input image
- io::pgm::load(f, argv[1]);
-
- // n
- int n = std::atoi(argv[2]);
- if (n <= 0)
- usage(argv);
-
- // echo
- int echo = std::atoi(argv[4]);
- if (echo != 0 && echo != 1)
- usage(argv);
-
- neighb2d nbh = c4();
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- typedef morpho::tree::data<I,S> tree_t;
- tree_t t(f, s, nbh);
-
- accu::count< util::pix<I> > attr;
- I g = get_attribute_image(attr, t, nbh, n, echo);
- io::pgm::save(g, argv[3]);
-}
Index: geraud/tufa_2008/wst_f_equal_wst_a.cc
--- geraud/tufa_2008/wst_f_equal_wst_a.cc (revision 3151)
+++ geraud/tufa_2008/wst_f_equal_wst_a.cc (working copy)
@@ -1,140 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/steps.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/pw/all.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/ppm/save.hh>
-#include <mln/io/pbm/save.hh>
-#include <mln/literal/black.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/level/transform.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/morpho/tree/data.hh>
-
-#include <mln/accu/volume.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/meyer_wst.hh>
-
-#include <mln/labeling/regional_minima.hh>
-
-#include <mln/core/var.hh>
-
-
-namespace mln
-{
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
-} // mln
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm"
<< std::endl;
- std::abort();
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 2)
- usage(argv);
-
- unsigned nref, n;
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
-
- labeling::regional_minima(f, c4(), nref);
- std::cout << nref << std::endl;
-
-
- image2d<unsigned> wst_f = morpho::meyer_wst(f, c4(), n);
- mln_assertion(n == nref);
-
- io::ppm::save(level::transform(wst_f, colorize(n)),
- "wst_f.ppm");
- mln_VAR(WST_f, (pw::value(wst_f) == pw::cst(0u)) | f.domain());
- io::pbm::save(WST_f, "wst_f.pbm");
-
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- morpho::tree::data<I,S> t(f, s, c4());
- accu::volume<I> vol;
- image2d<unsigned> a = morpho::tree::compute_attribute_image(vol, t);
-
- labeling::regional_minima(a, c4(), n);
- mln_assertion(n == nref);
-
-
- image2d<unsigned> wst_a = morpho::meyer_wst(a, c4(), n);
- mln_assertion(n == nref);
-
- io::ppm::save(level::transform(wst_a, colorize(n)),
- "wst_a.ppm");
- mln_VAR(WST_a, (pw::value(wst_a) == pw::cst(0u)) | f.domain());
- io::pbm::save(WST_a, "wst_a.pbm");
-
-
- io::pbm::save((pw::value(WST_a) != pw::value(WST_f)) | f.domain(),
- "diff.pbm");
-}
Index: geraud/tufa_2008/compute_a.cc
--- geraud/tufa_2008/compute_a.cc (revision 3151)
+++ geraud/tufa_2008/compute_a.cc (working copy)
@@ -1,412 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/compute_a.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/image_if.hh>
-#include <mln/pw/all.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/data/fill.hh>
-#include <mln/data/paste.hh>
-#include <mln/level/compare.hh>
-
-#include <mln/morpho/tree/data.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/labeling/regional_minima.hh>
-
-#include <mln/accu/count.hh>
-#include <mln/opt/at.hh>
-
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
-
- //------------------------------- compute_a
-
-
-
- template <typename I, typename N, typename A>
- mln_ch_value(I, mln_result(A))
- compute_a(const I& f, const N& nbh, A, unsigned& n_regmins)
- {
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(f);
- // s maps increasing attributes.
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, mln_site(I)) zpar;
- mln_ch_value(I, bool) deja_vu, flag;
- mln_ch_value(I, A) attr;
-
- n_regmins = f.domain().nsites();
-
-
- // Initialization.
- {
- // parent
- initialize(par, f);
- initialize(zpar, f);
-
- // deja_vu
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
-
- // flag
- initialize(flag, f);
- data::fill(flag, true);
-
- // attr
- initialize(attr, f);
- }
-
-
- // First Pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- // Make-Set.
- par(p) = p;
- zpar(p) = p;
- attr(p).take_as_init(p);
-
- for_all(n)
- if (f.domain().has(n) && deja_vu(n))
- {
- r = find_root__(zpar, n);
- if (r != p)
- {
- // Fully compressed union.
- zpar(r) = p;
- attr(p).take(attr(r));
-
- if (f(r) == f(p))
- {
- // Weak-Union; only for flat zones.
- par(r) = p;
-
- if (flag(p) == false && flag(r) == false)
- {
- // Two non-reg-min components merge (same flat
- // zone) so we had an extra invalidation.
- ++n_regmins;
- }
- flag(p) = flag(p) && flag(r);
- --n_regmins; // So we get the number of flat zones
- // minus the non-reg-min flat zones.
- }
- else
- {
- mln_invariant(f(r) < f(p));
- if (flag(p) == true)
- --n_regmins; // Invalidation.
- flag(p) = false;
- }
- }
- }
- deja_vu(p) = true;
- }
- } // end of First Pass.
-
-
- std::cout << "n reg min = " << n_regmins << std::endl;
-
-
- {
- unsigned n = 0;
- mln_fwd_piter(S) p(s);
- for_all(p)
- if (par(p) == p && flag(p))
- ++n;
- mln_assertion(n == n_regmins);
- }
-
-
- // The attr image is not correct on flat zones since there is
- // no back-propagation of the attribute value of the component
- // root. For instance with f="v v v" we get attr="1 2 3"
- // instead of "3 3 3". So a finalization is required.
-
- mln_ch_value(I, mln_result(A)) a;
- initialize(a, f);
- data::paste(attr, a);
-
- // Finalization.
- {
- mln_bkd_piter(S) p(s); // Reverse.
-
- unsigned n_non_compressed_par = 0;
- for_all(p)
- {
- a(p) = a(par(p));
- if (par(par(p)) != par(p))
- ++ n_non_compressed_par;
- }
- std::cout << "n_non_compressed_par = " <<
n_non_compressed_par << std::endl;
- }
-
- // TODO: compress at least the reg minima!
-
-
- {
- image2d<unsigned> regmin;
- initialize(regmin, f);
- {
- unsigned i_regmin = 0;
- mln_bkd_piter(S) p(s);
- for_all(p)
- {
- if (par(p) == p)
- {
- if (flag(p))
- regmin(p) = ++i_regmin;
- else
- regmin(p) = 0;
- }
- else
- regmin(p) = regmin(par(p));
- }
- }
-
- debug::println("f", f);
-
- debug::println("flag", flag);
- // We can see that some point are at true for components that
- // are not reg min; flag is a candidate to be compressed...
-
- debug::println("regmin", regmin);
-
-
-
- // TODO:
-
- // On veut tester ici dans quel ordre on voit les
- // reg min lorsque a croit. Pour tous les points d'un reg min,
- // est-ce que le root est vu en premier ?
-
-
-
- image2d<bool> seen;
- initialize(seen, f);
- data::fill(seen, false);
-
- s = level::sort_psites_increasing(a);
- mln_bkd_piter(S) p(s);
- for_all(p)
- {
- if (regmin(p) == 0)
- continue;
- // p is in a regional minimum.
- if (par(p) != p) // A non-root point.
- {
- mln_assertion(regmin(par(p)) != 0); // Root in a regional minimum.
- mln_assertion(regmin(par(p)) == regmin(p)); // and the same as p.
- mln_assertion(seen(par(p)));
- }
- seen(p) = true;
- }
- debug::println(seen);
-
-// if (flag(p))
-// std::cout << a(p) << ' ' << p << ' '
<< (par(p) == p) << std::endl;
-
- }
-
- return a;
- }
-
-
-
- //------------------------------- filtering
-
-
-
-// template <typename I, typename A, typename N>
-// mln_concrete(I) filtering(const I& f, const A& a, const N& nbh,
-// unsigned n_regmins, unsigned n_wanted)
-// {
-// typedef p_array<mln_psite(I)> S;
-// S s = level::sort_psites_increasing(a);
-
-// // s maps increasing attributes.
-
-// mln_concrete(I) out;
-// initialize(out, f);
-
-// mln_ch_value(I, mln_site(I)) par;
-// mln_ch_value(I, bool) deja_vu, flag;
-
-// // Initialization.
-// {
-// initialize(par, f);
-// mln_piter(A) p(par.domain());
-// for_all(p)
-// par(p) = p;
-// initialize(deja_vu, f);
-// data::fill(deja_vu, false);
-
-// // flag
-// initialize(flag, f);
-// data::fill(flag, true);
-// }
-
-
-// int counter = 0;
-// // We are trying to count the number of merges of regional minima...
-
-
-// // First Pass.
-// {
-// mln_site(I) r;
-// mln_fwd_piter(S) p(s);
-// mln_niter(N) n(nbh, p);
-// for_all(p)
-// {
-// for_all(n)
-// if (a.domain().has(n) && deja_vu(n))
-// {
-// r = find_root__(par, n);
-// if (r != p)
-// if (a(r) == a(p))
-// {
-// par(r) = p; // Union.
-// if (flag(r) == true && flag(p) == true)
-// --counter;
-// flag(p) = flag(p) && flag(r);
-// }
-// else // a(r) != a(p)
-// {
-// if (flag(r) == true && flag(p) == true)
-// ++counter;
-// mln_invariant(a(p) > a(r));
-// flag(p) = false;
-// }
-// }
-// deja_vu(p) = true;
-// }
-// std::cout << counter << std::endl;
-// }
-
-// // // Second Pass.
-// // {
-// // mln_bkd_piter(S) p(s);
-// // for_all(p)
-// // if (par(p) == p)
-// // out(p) = f(p);
-// // else
-// // out(p) = out(par(p));
-// // }
-
-// return out;
-// }
-
-
-
-
-} // mln
-
-
-
-
-int main(int, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
- // debug::println(f);
-
- accu::count<point2d> area;
- unsigned n_regmins;
- image2d<unsigned> a = compute_a(f, c4(), area, n_regmins);
- // debug::println(a);
-
-// {
-// // Test of 'n_regmins'.
-// unsigned ref;
-// labeling::regional_minima(f, c4(), ref);
-// mln_assertion(n_regmins == ref);
-// }
-
-// {
-// // Test of 'a'.
-// typedef p_array<point2d> S;
-// S s = level::sort_psites_decreasing(f);
-// morpho::tree::data<I,S> t(f, s, c4());
-// accu::count< util::pix<I> > area;
-// image2d<unsigned> ref = morpho::tree::compute_attribute_image(area, t);
-// mln_assertion(a == ref);
-// }
-
-
-
-
-
-// unsigned n_wanted = 10;
-// I g = filtering(f, a, c4(), n_regmins, n_wanted);
-
-}
Index: geraud/tufa_2008/wst.cc
--- geraud/tufa_2008/wst.cc (revision 3151)
+++ geraud/tufa_2008/wst.cc (working copy)
@@ -1,69 +0,0 @@
-// 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.
-
-/// \file wst.cc
-
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/var.hh>
-
-#include <mln/value/int_u8.hh>
-
-#include <mln/data/fill.hh>
-#include <mln/level/replace.hh>
-#include <mln/morpho/meyer_wst.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
output.pgm" << std::endl;
- std::abort();
-}
-
-
-int main(int argc, char* argv [])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 3)
- usage(argv);
-
-
- image2d<int_u8> input;
- io::pgm::load(input, argv[1]);
-
- int_u8 nbasins;
- image2d<int_u8> output = morpho::meyer_wst(input, c4(), nbasins);
- std::cout << "n basins = " << nbasins << std::endl;
- io::pgm::save(output, argv[2]);
-}
Index: geraud/tufa_2008/experiment.cc
--- geraud/tufa_2008/experiment.cc (revision 3151)
+++ geraud/tufa_2008/experiment.cc (working copy)
@@ -1,138 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/experiment.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/literal/black.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/morpho/tree/data.hh>
-
-#include <mln/accu/volume.hh>
-#include <mln/win/disk2d.hh>
-
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/meyer_wst.hh>
-#include <mln/morpho/opening.hh>
-#include <mln/morpho/closing_area.hh>
-
-#include <mln/data/fill.hh>
-
-#include <mln/level/transform.hh>
-#include <mln/level/stretch.hh>
-
-
-
-namespace mln
-{
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
-} // mln
-
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm"
<< std::endl;
- std::abort();
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 2)
- usage(argv);
-
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- morpho::tree::data<I,S> t(f, s, c4());
- accu::volume<I> attr;
-
- image2d<unsigned> a = morpho::tree::compute_attribute_image(attr, t);
- io::pgm::save(level::stretch(int_u8(), a),
- "a.pgm");
-
- unsigned n;
- image2d<unsigned> wst_a = morpho::meyer_wst(a, c4(), n);
- io::ppm::save(level::transform(wst_a, colorize(n)),
- "wst_a.ppm");
- std::cout << "n(a) = " << n << std::endl;
-
- // FIXME: ça n'a pas de sens de faire ce qui est dessous... :-(
-
-
- image2d<unsigned> aa = morpho::closing_area(a, c4(), 100);
- io::pgm::save(level::stretch(int_u8(), aa),
- "aa.pgm");
-
- image2d<unsigned> wst_aa = morpho::meyer_wst(aa, c4(), n);
- io::ppm::save(level::transform(wst_aa, colorize(n)),
- "wst_aa.ppm");
- std::cout << "n(aa) = " << n << std::endl;
-}
Index: geraud/tufa_2008/n_cmpt.cc
--- geraud/tufa_2008/n_cmpt.cc (revision 3151)
+++ geraud/tufa_2008/n_cmpt.cc (working copy)
@@ -1,263 +0,0 @@
-// 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.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/int_u16.hh>
-#include <mln/io/pgm/load.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/debug/iota.hh>
-
-#include <mln/labeling/regional_minima.hh>
-#include <mln/data/fill.hh>
-
-#include <mln/morpho/tree/data.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-
-#include <mln/accu/volume.hh>
-#include <mln/accu/count.hh>
-
-
-namespace mln
-{
-
- 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 A, typename I, typename N>
- mln_concrete(I)
- n_cmpt(A a, const I& f, const N& nbh, unsigned lambda)
- {
- // Compute attribute image.
- //-------------------------
-
- typedef p_array<mln_psite(I)> S;
- typedef mln_ch_value(I, mln_result(A)) Attr;
-
- S s = level::sort_psites_decreasing(f);
- morpho::tree::data<I,S> t(f, s, nbh);
- Attr attr = morpho::tree::compute_attribute_image(a, t);
- s = level::sort_psites_increasing(attr);
- debug::println("attr =", attr);
-
-
- // Compute regional minima of attribute image.
- //--------------------------------------------
-
- unsigned label;
- mln_ch_value(I, unsigned) min_v = labeling::regional_minima(attr, nbh, label);
- debug::println("regmin =", min_v);
-
- // number of minima
- unsigned cmpts = label;
- if (lambda > cmpts)
- std::cout << "Warning: lambda value is too high!" <<
std::endl;
-
- std::cout << cmpts << std::endl;
-
-
- // two pass algo
- //--------------
-
- // init fused image
- mln_ch_value(I, bool) fused;
- initialize(fused, attr);
- mln::data::fill(fused, false);
-
- // prepare union find
- typedef mln_psite(I) P;
-
- //deja_vu
- mln_ch_value(I, bool) deja_vu;
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
-
- //parent
- mln_ch_value(I, P) parent(attr.domain());
- {
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- parent(p) = p;
-
- // Mandatory since we propagate fused
- if (min_v(p) != 0) // p in a reg min of the attribute image
- fused(p) = true; // ok
- }
- }
-
- // UNION FIND ON ATTR
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- // std::cout << p << std::endl;
- for_all(n)
- {
- if (attr.domain().has(n) && deja_vu(n))
- {
- P r = find_root__(parent, n);
- if (r != p)
- {
- // std::cout << "neighb: " << n << std::endl;
- // std::cout << "v(r): " << attr(r) << " v(p):
"
- // << attr(p) << " f(p): " << fused(p)
<< std::endl;
-
- //if (attr(r) != attr(p)) // r and p have different attrs
- // This check was wrong.
- // you just fused with a minima.
- // then you fuse with a neighbor already fused that has the same attr as you
- // a) 1 50 1
- // 2 2 2
- // we don't have ( attr(r) == attr(p) ) => not fused(r)
- // even if r and p are not minima
-
- // problem :
- // - when fusing minima : same level, both fused. NOT DEC
- // - when fusing cmpts (a) : same level, both fused. DEC
-
- // One cmpt less if
-
-// if (fused(r) && min_v(p) == 0) // p is not a minima
-// if (fused(p)) // p already belong to a cmpt (fused for an another n)
-// if (cmpts >= lambda) // union is still allowed
-
- if (fused(r) && min_v(p) == 0 // p is not a minima
- && fused(p) // p already belong to a cmpt (fused for an another n)
- && cmpts >= lambda) // union is still allowed
- {
- --cmpts;
- // std::cout << "dec" << std::endl;
- }
-
- mln_invariant(fused(r) || attr(r) == attr(p));
-
- // Union made if
- if (cmpts >= lambda || // union is still allowed or
- ! fused(r) || // r not fused or
- ! fused(p) || // p not fused or
- min_v(p) != 0) // p is a minima
- {
- // std::cout << "fusing " << p << " with "
<< n << std::endl;
- parent(r) = p;
-
- // This test is mandatory. Sometimes (--_) points are fused
- // tough none of these points belongs to a component (attached
- // to a local minima). In this case fused(p) must not be true
- // since it can be fused again without removing a component.
- // looking if r is fused should be enough.
- // This test force minima to be initialized fused.
- if (fused(r))
- fused(p) = true;
-
-
- // If I try to fuse with something never fused I am on a plateau.
- // not fused(r) => ( attr(r) == attr(p) )
- mln_invariant(fused(r) || attr(r) == attr(p));
- // fused(r) and ( attr(r) == attr(p) ) happen on minima plateau.
-
- // fused(n) = true; // useless ? probably yes because when we
- // want to know that we really fuse component, we look at
- // fused(r) not n.
- // fused(n) is not an invariant: --_. And it is ok (I think).
- // We don't have to retro-propagate fused.
-
-
- // std::cout << "attr " << attr(p) << " - "
<< cmpts << std::endl;
- //debug::println(fused);
- }
- }
- }
- }
- deja_vu(p) = true;
- }
-
- mln_ch_value(I,value::int_u<16>) iota(f.domain());
- debug::iota(iota);
-
- std::cout << std::endl;
- std::cout << "cmpts: " << cmpts << std::endl;
-
- // second pass
- mln_concrete(I) output;
- initialize(output, f);
- {
- mln_bkd_piter(S) p(s);
- for_all(p)
- if (parent(p) == p) // p is root.
- output(p) = iota(p);
- else
- output(p) = output(parent(p));
- }
-
- return output;
- }
-
-} // end of namespace mln
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
n" << std::endl;
- std::cerr << "n: expected number of basins" << std::endl;
- std::abort();
-}
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 3)
- usage(argv);
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
- debug::println("f =", f);
-
- unsigned n = std::atoi(argv[2]);
-
- accu::count< util::pix<I> > acc;
- // accu::volume<I> acc;
-
- image2d<int_u8> g = n_cmpt(acc, f, c4(), n + 1);
- debug::println(g);
-}
Index: geraud/tufa_2008/filter.cc
--- geraud/tufa_2008/filter.cc (revision 3151)
+++ geraud/tufa_2008/filter.cc (working copy)
@@ -1,169 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/filter.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/literal/black.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/data/fill.hh>
-
-#include <mln/morpho/tree/data.hh>
-#include <mln/morpho/tree/compute_attribute_image.hh>
-#include <mln/morpho/closing_volume.hh>
-
-
-
-namespace mln
-{
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
- template <typename I, typename A, typename N>
- mln_concrete(I) filtering(const I& f, const A& a, const N& nbh,
mln_value(A) lambda)
- {
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(a);
-
- // s maps increasing attributes.
-
- mln_concrete(I) out;
- initialize(out, f);
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, bool) deja_vu;
- {
- initialize(par, f);
- mln_piter(A) p(par.domain());
- for_all(p)
- par(p) = p;
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
- }
-
- // First pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (a.domain().has(n) && deja_vu(n))
- {
- r = find_root__(par, n);
- if (r != p)
- if (f(r) == f(p) || a(r) < lambda)
- par(r) = p; // Union.
- }
- deja_vu(p) = true;
- }
- }
-
- // Second pass.
- {
- mln_bkd_piter(S) p(s);
- for_all(p)
- if (par(p) == p)
- out(p) = f(p);
- else
- out(p) = out(par(p));
- }
- return out;
- }
-
-
-} // mln
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
lambda output.pgm" << std::endl;
- std::abort();
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 4)
- usage(argv);
-
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
-
- unsigned lambda = std::atoi(argv[2]);
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- // Children go towards lower levels so leafs are regional minima.
- // We get a min-tree so that we can perform morphological closings.
-
- morpho::tree::data<I,S> t(f, s, c4());
- accu::volume<I> attr;
-
- image2d<unsigned> a = morpho::tree::compute_attribute_image(attr, t);
-
- I g = filtering(f, a, c4(), lambda);
-
- {
- I ref = morpho::closing_volume(f, c4(), lambda);
- if (g != ref)
- {
- io::pgm::save(ref, "ref.pgm");
- std::cerr << "oops!" << std::endl;
- }
- }
-
- io::pgm::save(g, argv[3]);
-}
Index: geraud/tufa_2008/closed_gradient.cc
--- geraud/tufa_2008/closed_gradient.cc (revision 3151)
+++ geraud/tufa_2008/closed_gradient.cc (working copy)
@@ -1,64 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/closed_gradient.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/morpho/elementary/gradient.hh>
-#include <mln/morpho/closing_volume.hh>
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
lambda output.pgm" << std::endl;
- std::abort();
-}
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 4)
- usage(argv);
-
- image2d<int_u8> f;
- io::pgm::load(f, argv[1]);
- unsigned lambda = std::atoi(argv[2]);
- io::pgm::save(morpho::closing_volume(morpho::elementary::gradient(f, c4()),
- c4(),
- lambda),
- argv[3]);
-}
Index: geraud/tufa_2008/fz_count.cc
--- geraud/tufa_2008/fz_count.cc (revision 3151)
+++ geraud/tufa_2008/fz_count.cc (working copy)
@@ -1,160 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/fz_count.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/labeling/regional_minima.hh>
-#include <mln/labeling/flat_zones.hh>
-#include <mln/data/fill.hh>
-#include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
- template <typename I, typename N>
- unsigned fz_count(const I& f, const N& nbh)
- {
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(f);
- // s maps increasing attributes.
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, bool) deja_vu;
-
- unsigned counter = f.domain().nsites();
-
- // Initialization.
- {
- mln_piter(I) p(f.domain());
-
- // parent
- initialize(par, f);
- for_all(p)
- par(p) = p;
-
- // deja_vu
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
- }
-
- // First pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (f.domain().has(n) && deja_vu(n))
- {
- r = find_root__(par, n);
- if (r != p) // not already merged
- {
- if (f(r) == f(p))
- {
-
- // Moving the line below out of this test
- // (either before the test or after the block)
- // makes the algorithm fail.
- // The erroneous result is less than the ref
- // result => we want this current block too many
- // times. Since we merge (thru "par(r) = p")
- // whatever "f(r) == f(p)" is true or not, we
- // have more often "f(r) == f(p)" than expected.
- par(r) = p;
-
- --counter;
- }
- }
- }
-
- deja_vu(p) = true;
- }
- }
-
- return counter;
- }
-
-
-} // mln
-
-
-
-
-int main(int, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
-
- unsigned ref, n = fz_count(f, c4());
- labeling::flat_zones(f, c4(), ref);
-
- if (n == ref)
- std::cout << "success: n flat zones = " << n <<
std::endl;
- else
- std::cout << "FAILURE: found = " << n << " v. ref =
" << ref << std::endl;
-}
Index: geraud/tufa_2008/regmin_count.cc
--- geraud/tufa_2008/regmin_count.cc (revision 3151)
+++ geraud/tufa_2008/regmin_count.cc (working copy)
@@ -1,175 +0,0 @@
-// 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.
-
-/// \file sandbox/geraud/tufa/regmin_count.cc
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/debug/println.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/labeling/regional_minima.hh>
-#include <mln/labeling/flat_zones.hh>
-#include <mln/data/fill.hh>
-
-#include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
- template <typename I>
- void println_par(const I& par)
- {
- int nr = par.nrows(), nc = par.ncols();
- for (int r = 0; r < nr; ++r)
- {
- for (int c = 0; c < nc; ++c)
- if (opt::at(par, r,c) == point2d(r,c))
- std::cout << "( ) ";
- else
- std::cout << opt::at(par, r,c) << ' ';
- std::cout << std::endl;
- }
- }
-
- template <typename P>
- inline
- mln_value(P) find_root__(P& par, const mln_value(P)& x)
- {
- if (par(x) == x)
- return x;
- else
- return par(x) = find_root__(par, par(x));
- }
-
-
- template <typename I, typename N>
- unsigned regmin_count(const I& f, const N& nbh)
- {
- typedef p_array<mln_psite(I)> S;
- S s = level::sort_psites_increasing(f);
- // s maps increasing attributes.
-
- mln_ch_value(I, mln_site(I)) par;
- mln_ch_value(I, bool) deja_vu, flag;
-
- unsigned counter = f.domain().nsites();
-
-
- // Initialization.
- {
- mln_piter(I) p(f.domain());
-
- // parent
- initialize(par, f);
- for_all(p)
- par(p) = p;
-
- // flag
- initialize(flag, f);
- data::fill(flag, true);
-
- // deja_vu
- initialize(deja_vu, f);
- data::fill(deja_vu, false);
- }
-
- // First pass.
- {
- mln_site(I) r;
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- unsigned loc = 0;
- for_all(n)
- if (f.domain().has(n) && deja_vu(n))
- {
- r = find_root__(par, n);
- if (r != p)
- {
- if (f(r) == f(p))
- {
- par(r) = p; // Union.
- if (flag(p) == false && flag(r) == false)
- {
- // Two non-reg-min components merge (same flat
- // zone) so we had an extra invalidation.
- ++counter;
- }
- flag(p) = flag(p) && flag(r);
- --counter; // So we get the number of flat zones
- // minus the non-reg-min flat zones.
- }
- else
- {
- mln_invariant(f(r) < f(p));
- if (flag(p) == true)
- {
- ++loc;
- --counter; // Invalidation.
- }
- flag(p) = false;
- }
- }
- }
- mln_invariant(loc == 0 || loc == 1);
- deja_vu(p) = true;
- }
- }
-
- return counter;
- }
-
-
-} // mln
-
-
-
-
-int main(int, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<int_u8> I;
- I f;
- io::pgm::load(f, argv[1]);
-
- unsigned ref, n = regmin_count(f, c4());
- labeling::regional_minima(f, c4(), ref);
-
- if (n == ref)
- std::cout << "success: n regional minima = " << n <<
std::endl;
- else
- std::cout << "FAILURE: found = " << n << " v. ref =
" << ref << std::endl;
-}
Index: geraud/estimate.hh
--- geraud/estimate.hh (revision 3151)
+++ geraud/estimate.hh (working copy)
@@ -1,90 +0,0 @@
-// 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_LABELING_ESTIMATE_HH
-# define MLN_LABELING_ESTIMATE_HH
-
-/*! \file mln/labeling/estimate.hh
- *
- * \brief Compute the estimate pixel value.
- */
-
-# include <mln/core/concept/image.hh>
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/canvas/labeling.hh>
-
-# include <mln/accu/compute.hh>
-// # include <mln/core/image_if_value.hh>
-
-
-
-namespace mln
-{
-
- namespace labeling
- {
-
- /*! \brief Label a binary image and compute some estimations over
- * the components.
- *
- * \param[in] input The image.
- *
- * The free parameter \c A is a type of accumulator.
- *
- * FIXME: Not yet impled.
- */
- template <typename A, typename I>
- void
- estimate(const Image<I>& input);
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename A, typename I>
- void
- estimate(const Image<I>& input)
- {
- trace::entering("labeling::estimate");
- mlc_equal(mln_trait_image_kind(I), mln::trait::image::kind::binary)::check();
- mln_precondition(exact(input).is_valid());
-
- std::cerr << "Sorry: mln::labeling::estimate is not yet
implemented!" << std::endl;
-
- // FIXME: Was:
- // mln_accu_with(A, util::pix<I>)::result res = accu::compute<A>(input
| val);
-
- trace::exiting("labeling::estimate");
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace mln::labeling
-
-} // end of namespace mln
-
-
-#endif // ! MLN_LABELING_ESTIMATE_HH
Index: geraud/laurent/wst_edge.cc
--- geraud/laurent/wst_edge.cc (revision 3151)
+++ geraud/laurent/wst_edge.cc (working copy)
@@ -1,409 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/extended.hh>
-# include <mln/core/routine/extend.hh>
-
-# include <mln/core/alias/window2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-# include <mln/core/site_set/p_centered.hh>
-
-# include <mln/literal/origin.hh>
-# include <mln/literal/black.hh>
-# include <mln/literal/white.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/accu/min_max.hh>
-# include <mln/accu/mean.hh>
-
-# include <mln/fun/i2v/array.hh>
-# include <mln/fun/p2v/iota.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/level/transform.hh>
-# include <mln/extension/fill.hh>
-
-# include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/closing_volume.hh>
-
-# include <mln/opt/at.hh>
-
-# include <mln/debug/println.hh>
-
-
-
-// Functions
-
-inline
-bool is_row_odd(const mln::point2d& p)
-{
- return p.row() % 2;
-}
-
-inline
-bool is_cell(const mln::point2d& p)
-{
- return p.row() % 2 == 0 && p.col() % 2 == 0;
-}
-
-inline
-bool is_edge(const mln::point2d& p)
-{
- return p.row() % 2 + p.col() % 2 == 1;
-}
-
-inline
-bool is_point(const mln::point2d& p)
-{
- return p.row() % 2 && p.col() % 2;
-}
-
-
-inline
-bool is_not_edge(const mln::point2d& p)
-{
- return ! is_edge(p);
-}
-
-
-
-namespace mln
-{
-
- namespace border
- {
-
- template <typename I>
- void
- fill(I& ima, const mln_value(I)& v)
- {
- const int nrows = ima.nrows();
- const int ncols = ima.ncols();
- for (int r = -1; r <= nrows; ++r)
- {
- opt::at(ima, r, -1) = v;
- opt::at(ima, r, ncols) = v;
- }
- for (int c = -1; c <= ncols; ++c)
- {
- opt::at(ima, -1, c) = v;
- opt::at(ima, nrows, c) = v;
- }
- }
-
- } // mln::border
-
- namespace accu
- {
-
- template <typename I, typename L, typename A, typename V>
- inline
- void
- compute(const Image<I>& input_,
- const Image<L>& label_,
- const Accumulator<A>&,
- V& v)
- {
- trace::entering("accu::compute");
-
- const I& input = exact(input_);
- const L& label = exact(label_);
-
- const unsigned n = v.size();
- std::vector<A> a(n);
-
- mln_piter(I) p(input.domain());
- for_all(p)
- a[label(p)].take(input(p));
-
- for (unsigned l = 1; l < n; ++l)
- v(l) = a[l].to_result();
-
- trace::exiting("accu::compute");
- }
-
- } // mln::accu
-
- namespace morpho
- {
-
- template <typename I, typename N>
- mln_concrete(I)
- gradient(const I& input, const N& nbh)
- {
- mln_concrete(I) output;
- initialize(output, input);
- accu::min_max<mln_value(I)> mm;
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- mm.init();
- for_all(n) if (input.has(n))
- mm.take(input(n));
- output(p) = mm.second() - mm.first();
- }
- return output;
- }
-
- template <typename I, typename N>
- mln_concrete(I)
- dilation(const I& input, const N& nbh)
- {
- typedef mln_value(I) V;
- // FIXME: extension::fill(input, mln_min(V));
-
- mln_concrete(I) output;
- initialize(output, input);
- accu::max<V> m;
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- m.init();
- for_all(n) if (input.has(n))
- m.take(input(n));
- output(p) = m;
- }
- return output;
- }
-
- } // mln::morpho
-
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
-
- template <typename I>
- I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-} // mln
-
-
-
-template <typename T>
-mln::image2d<T>
-image2cells(const mln::image2d<T>& input)
-{
- mln::image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (int row = 0; row < input.nrows(); ++row)
- for (int col = 0; col < input.ncols(); ++col)
- mln::opt::at(output, 2 * row, 2 * col) = mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename T>
-mln::image2d<T>
-cells2image(const mln::image2d<T>& input)
-{
- mln::image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (int row = 0; row < input.nrows(); row += 2)
- for (int col = 0; col < input.ncols(); col += 2)
- mln::opt::at(output, row / 2, col / 2) =
- mln::opt::at(input, row, col);
- return output;
-}
-
-
-
-
-template <typename I>
-void
-do_it(I& ima, int lambda, const std::string& filename, unsigned& nbasins)
-{
- using namespace mln;
-
- // e2c
-
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
-
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
-
- mln_VAR( e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v) );
-
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
-
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
-
- mln_VAR( e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v) );
-
- // cell
- mln_VAR(cell, ima | is_cell);
-
- // edge
- mln_VAR(edge, extend((ima | is_edge).rw(),
- pw::value(ima)));
-
- data::paste(morpho::gradient(edge, e2c), edge);
- // ^^^
- // edge -> neighboring cells
-
- // 'edge' looks like:
- //
- // 1 1
- // 3 3 3
- // 1 1
-
- {
- io::pgm::save(display_edge(ima, 0, 3),
- "temp_edge.pgm");
- }
-
-
- data::paste( morpho::closing_volume(edge, e2e, lambda), edge );
-
-
- image2d<unsigned> label(ima.bbox(), 0);
- // mln_ch_value(I, unsigned) label;
- // initialize(label, ima);
-
-
- mln_VAR(wst, label | is_edge);
-
- data::fill(wst, morpho::meyer_wst(edge, e2e, nbasins));
- // ^^^
- // edge -> neighboring edges
-
- // 'wst' looks like:
- //
- // 2 2
- // 0 0 0
- // 1 1
-
- colorize colors(nbasins);
-
- {
- image2d<value::rgb8> temp(label.domain());
- data::fill(temp, literal::white);
-
- data::paste( level::transform(label | is_edge,
- colors),
- temp );
-
- io::ppm::save(display_edge(temp, literal::white, 3),
- "temp_label.ppm");
- }
-
- // YET THOSE VALUES ARE ON EDGES, NOT ON CELLS...
-
-
- mln_VAR(lab, label | is_cell);
-
- data::paste(morpho::dilation(extend(lab, label),
- c4()),
- label);
-
- // 'lab' looks like:
- //
- // 2 2 2
- //
- // 1 1 1
-
- io::ppm::save(level::transform(cells2image(label),
- colors),
- filename);
-}
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm
lambda output.ppm" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 4)
- usage(argv);
-
- image2d<int_u8> temp;
- io::pgm::load(temp, argv[1]);
-
- image2d<int_u8> ima = image2cells(temp);
-
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- std::string filename(argv[3]);
-
- unsigned nbasins;
- do_it(ima, lambda, filename, nbasins);
- std::cout << "nbasins = " << nbasins << std::endl;
-}
Index: geraud/laurent/wst2d.cc
--- geraud/laurent/wst2d.cc (revision 3151)
+++ geraud/laurent/wst2d.cc (working copy)
@@ -1,154 +0,0 @@
-# include <cstdlib>
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/rgb8.hh>
-
-# include <mln/io/pgm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/core/var.hh>
-# include <mln/core/image/image2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-
-# include <mln/level/transform.hh>
-# include <mln/literal/black.hh>
-# include <mln/debug/println.hh>
-
-# include <mln/morpho/closing_area.hh>
-# include <mln/morpho/gradient.hh>
-# include <mln/accu/min_max.hh>
-# include <mln/morpho/meyer_wst.hh>
-
-
-using namespace mln;
-using value::int_u8;
-
-
-template <typename I, typename N>
-mln_concrete(I)
-morpho_gradient(const Image<I>& input_, const Neighborhood<N>& nbh_)
-{
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
-
- mln_concrete(I) output;
- initialize(output, input);
- accu::min_max<mln_value(I)> mm;
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
-
- for_all(p)
- {
- mm.take_as_init(input(p));
- for_all(n)
- mm.take(input(n));
- output(p) = mm.second() - mm.first();
- }
-
- return output;
-}
-
-struct colorize : Function_v2v< colorize >
-{
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
-};
-
-
-bool is_chess(const point2d& p)
-{
- return p.col() % 2 == p.row() % 2;
-}
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm nbh
lambda output.ppm" << std::endl;
- std::cerr << " nbh in {4, 6, 8}; lambda >= 0" << std::endl;
- abort();
-}
-
-
-template <typename I, typename N>
-void do_it(const I& ima,
- const N& nbh,
- int lambda,
- const std::string& filename)
-{
- I grad = morpho_gradient(ima, nbh);
-
- I clo;
- if (lambda > 1)
- clo = morpho::closing_area(grad, nbh, lambda);
- else
- clo = grad;
-
- unsigned l;
- mln_ch_value(I, unsigned) wst = morpho::meyer_wst(clo, nbh, l);
-
- std::cout << "nbasins = " << l << std::endl;
-// debug::println(labeling::regional_minima(clo, nbh, l));
-// debug::println(wst);
-
- io::ppm::save(level::transform(wst, colorize(l)), filename);
-}
-
-
-int main(int argc, char* argv[])
-{
- if (argc != 5)
- usage(argv);
-
- image2d<int_u8> ima;
-
- io::pgm::load(ima, argv[1]);
-
- int nbh_ = atoi(argv[2]);
- if (! (nbh_ == 4 || nbh_ == 6 || nbh_ == 8))
- usage(argv);
-
- int lambda = atoi(argv[3]);
- if (lambda < 0)
- usage(argv);
-
- std::string filename(argv[4]);
-
- if (nbh_ == 4)
- {
- mln_VAR(nbh, c4());
- do_it(ima, nbh, lambda, filename);
- }
- else if (nbh_ == 8)
- {
- mln_VAR(nbh, c8());
- do_it(ima, nbh, lambda, filename);
- }
- else if (nbh_ == 6)
- {
- bool vert[] = { 1, 1, 0,
- 1, 0, 1,
- 0, 1, 1 };
-
- bool hori[] = { 0, 1, 1,
- 1, 0, 1,
- 1, 1, 0 };
-
- mln_VAR(nbh, make::double_neighb2d(is_chess, vert, hori));
- do_it(ima, nbh, lambda, filename);
- }
-}
Index: geraud/laurent/classif.cc
--- geraud/laurent/classif.cc (revision 3151)
+++ geraud/laurent/classif.cc (working copy)
@@ -1,419 +0,0 @@
-// 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.
-
-/// \file tests/core/image/complex_image_swt.cc
-/// \brief Testing Meyer's Watershed Transform on mln::complex_image.
-
-#include <iostream>
-
-#include <vector>
-#include <mln/core/image/image2d.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_queue_fast.hh>
-#include <mln/labeling/blobs.hh>
-#include <mln/io/pbm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/debug/println.hh>
-#include <mln/draw/line.hh>
-#include <mln/pw/all.hh>
-
-
-#include <mln/value/int_u8.hh>
-#include <mln/core/alias/point2d.hh>
-
-#include <mln/core/site_set/p_faces.hh>
-#include <mln/core/image/complex_image.hh>
-
-// FIXME: Include these elsewhere? (In complex_image.hh?)
-#include <mln/core/image/complex_neighborhoods.hh>
-#include <mln/core/image/complex_neighborhood_piter.hh>
-
-#include <mln/debug/iota.hh>
-#include <mln/data/fill.hh>
-#include <mln/norm/l2.hh>
-
-#include <mln/morpho/closing_area.hh>
-#include <mln/morpho/closing_volume.hh>
-#include <mln/morpho/closing_height.hh>
-#include <mln/morpho/meyer_wst.hh>
-
-
-namespace mln
-{
-
- template <typename I, typename N>
- mln_concrete(I)
- influence_zones(const I& input, const N& nbh)
- {
- mln_concrete(I) output = duplicate(input);
-
- p_queue_fast<mln_site(I)> q;
-
- {
- // Initialization.
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- if (input(p) != 0)
- for_all(n) if (input.has(n))
- if (input(n) == 0)
- {
- q.push(p);
- break;
- }
- }
- {
- // Body.
- mln_site(I) p;
- mln_niter(N) n(nbh, p);
- while (! q.is_empty())
- {
- p = q.pop_front();
- mln_invariant(output(p) != 0);
- for_all(n) if (input.has(n))
- if (output(n) == 0)
- {
- output(n) = output(p);
- q.push(n);
- }
- }
- }
-
- return output;
-
- } // IZ
-
-
- template <typename I>
- void
- mk_graph(const I& iz, unsigned nlabels)
- {
- }
-
-}
-
-
-void usage(char* argv[])
-{
- std::cerr << argv[0] << " lambda" << std::endl;
- abort();
-}
-
-int main(int argc, char* argv[])
-{
- if (argc != 2)
- usage(argv);
-
- using namespace mln;
- using mln::value::int_u8;
-
- /*----------------------------------------.
- | Complex + complex geometry (location). |
- `----------------------------------------*/
-
- /* A (simplicial) 1-complex and its adjacency graph.
-
- c 0 1 2 3
- r .------------------------
- | v0 e3 v3
- 0 | o-----------o v0----e3----v3
- | / \ / / \ /
- | / \ / / \ /
- 1 | e0 / e1 / e4 e0 e1 e4
- | / \ / / \ /
- | / \ / / \ /
- 2 | o-----------o v1----e2----v2
- | v1 e2 v2
-
- v = vertex
- e = edge
- */
-
-
-
-
- border::thickness = 0;
-
- image2d<bool> seeds;
- io::pbm::load(seeds, "+seeds.pbm");
-
-// debug::println(seeds);
-
- unsigned nlabels;
- image2d<unsigned> label = labeling::blobs(seeds, c4(), nlabels);
-
- std::cout << "n seeds = " << nlabels << std::endl;
- {
- image2d<int_u8> lab(label.domain());
- data::paste(label, lab);
- io::pgm::save(lab, "label.pgm");
- }
-
- image2d<unsigned> iz = influence_zones(label, c4());
- {
- image2d<int_u8> IZ(iz.domain());
- data::paste(iz, IZ);
- io::pgm::save(IZ, "iz.pgm");
- }
-// debug::println( (pw::value(iz) - pw::cst(1)) | iz.domain() );
-
-
- // mk_graph
-
- std::vector< std::vector<bool> > adj(nlabels + 1);
- for (unsigned l = 1; l <= nlabels; ++l)
- adj[l].resize(nlabels + 1, false);
-
- {
- box2d::piter p(iz.domain());
- for_all(p)
- {
- point2d r = p + right, b = p + down;
- if (iz.has(r) && iz(p) != iz(r))
- {
- if (iz(p) <= iz(r))
- adj[iz(p)][iz(r)] = true;
- else
- adj[iz(r)][iz(p)] = true;
- }
- if (iz.has(b) && iz(p) != iz(b))
- {
- if (iz(p) <= iz(b))
- adj[iz(p)][iz(b)] = true;
- else
- adj[iz(b)][iz(p)] = true;
- }
- }
- }
-
- // end of mk_graph
-
-
- const unsigned D = 1;
-
- topo::complex<D> c;
-
- typedef point2d P;
- typedef geom::complex_geometry<D, P> G;
- G geom;
-
- // Convenience typedefs.
- typedef topo::n_face<0, D> vertex;
- typedef topo::n_face<1, D> edge;
-
- {
-
- // 0-faces (vertices).
- std::vector<vertex> v;
- {
- box2d::piter p(label.domain());
- for_all(p)
- if (label(p) != 0)
- {
- geom.add_location(p);
- v.push_back(c.add_face());
- }
- }
-
- std::cout << "v size = " << v.size() << std::endl;
-
- // 1-faces (edges).
- std::vector<edge> e;
- {
- for (unsigned l = 1; l <= nlabels; ++l)
- for (unsigned ll = l + 1; ll <= nlabels; ++ll)
- if (adj[l][ll])
- e.push_back( c.add_face(-v[l-1] + v[ll-1]) );
- }
-
- std::cout << "e size = " << e.size() << std::endl;
-
- }
-
-
-// {
-// for (unsigned l = 1; l <= nlabels; ++l)
-// for (unsigned ll = l + 1; ll <= nlabels; ++ll)
-// if (adj[l][ll])
-// std::cout << l-1 << ' ' << ll-1 << std::endl;
-// }
-
-
-
-// std::cout << c << std::endl;
-
-
- image2d<int_u8> canvas(seeds.domain());
- data::fill(canvas, 0);
-
-
- /*---------------------.
- | Complex-based pset. |
- `---------------------*/
-
- p_complex<D, G> pc(c, geom);
-
- /*----------------------.
- | Complex-based image. |
- `----------------------*/
-
- // An image type built on a 1-complex with unsigned values on each
- // face (both vertices and edges).
- typedef complex_image<D, G, unsigned> dist_ima_t;
-
- // Create and initialize an image based on PC.
- dist_ima_t dist_ima(pc);
- data::fill(dist_ima, 0u);
-
- /*--------------------------------.
- | Complex-based image iterators. |
- `--------------------------------*/
-
- accu::max<unsigned> dist_max;
-
- // For each edge (1-face), compute the distance between the two
- // adjacent vertices (0-faces).
- p_n_faces_fwd_piter<D, G> e(dist_ima.domain(), 1);
- typedef complex_lower_neighborhood<D, G> v_nbh_t;
- v_nbh_t v_nbh;
- mln_niter_(v_nbh_t) v(v_nbh, e);
- for_all(e)
- {
- v.start();
- point2d p1 = v.to_site().front();
- v.next();
- point2d p2 = v.to_site().front();
- v.next();
- mln_invariant(!v.is_valid());
-
- dist_ima(e) = norm::l2_distance(p1.to_vec(), p2.to_vec()) / 2;
- dist_max.take(dist_ima(e));
-
- draw::line(canvas, p1, p2, dist_ima(e));
- canvas(p1) = 255;
- canvas(p2) = 255;
- }
-
- std::cout << "distance max = " << dist_max << std::endl;
-
-
- io::pgm::save(canvas, "canvas.pgm");
-
-
-// // Initialize 0-faces to a dummy value, to prevent the watershed from
-// // finding minima on 0-faces.
-// p_n_faces_fwd_piter<D, G> v_(dist_ima.domain(), 0);
-// for_all(v_)
-// {
-// // FIXME: canvas(v_.to_site().front()) = 255;
-// dist_ima(v_) = mln_max(mln_value_(dist_ima_t));
-// }
-
-
-
-
-// // For all edges, iterate on adjacent edges (i.e., on edges sharing
-// // an adjacent vertex).
- typedef complex_lower_dim_connected_n_face_neighborhood<D, G> nbh_t;
- nbh_t nbh;
-// // Neighbor edge.
-// mln_niter_(nbh_t) ne(nbh, e);
-// for_all(e)
-// {
-// std::cout << "dist_ima(" << e << ") = "
<< dist_ima(e)
-// << " -- adjacent edges :" << std::endl;
-// for_all(ne)
-// std::cout << " " << ne << std::endl;
-// }
-
-
-
- /*-----------------.
- | Simplification. |
- `-----------------*/
-
- // Currently, does nothing (lambda = 1).
- dist_ima_t closed_dist_ima (dist_ima.domain());
- morpho::closing_height(dist_ima, nbh, atoi(argv[1]), closed_dist_ima);
-
- /*------.
- | WST. |
- `------*/
-
- // Perform a Watershed Transform.
- typedef unsigned wst_val_t;
- wst_val_t nbasins;
- typedef complex_image<D, G, wst_val_t> wst_ima_t;
- wst_ima_t wshed = morpho::meyer_wst(closed_dist_ima, nbh, nbasins);
- /* Note that since the image is based not only on the 1-faces but
- also on the 0-faces of the complex, and given the above
- neighborhood, the domain seen by the WST is not connected! It is
- actually composed of five components :
-
- - a component containing all the 1-faces (egdes) which are all
- connected through
- mln::complex_lower_dim_connected_n_face_neighborhood;
-
- - four (singleton) components corresponding to the 0-faces
- (vertices), connected to no other part of the complex according to
- mln::complex_lower_dim_connected_n_face_neighborhood.
-
- Since the component made of the edges contains two local minima,
- the number of basins is equal to 6:
-
- 2 minima for the edges' component
- + 4 * 1 minima for the vertices's components
- --------------------------------------------
- 6 basins.
-
- Hence the result.
-
-
- We definitely need a complex_image that can accept a subset of a
- complex as domain (or at least a p_face<N, D, P>. */
- std::cout << "nbasins = " << nbasins - c.nfaces(0) <<
std::endl;
-
-
- image2d<int_u8> canvas_wst(seeds.domain());
- data::fill(canvas_wst, 255);
-
- for_all(e)
- {
- v.start();
- point2d p1 = v.to_site().front();
- v.next();
- point2d p2 = v.to_site().front();
- v.next();
- mln_invariant(!v.is_valid());
-
- draw::line(canvas_wst, p1, p2, wshed(e));
- }
-
- io::pgm::save(canvas_wst, "canvas_wst.pgm");
-
-}
Index: geraud/laurent/wst3d.cc
--- geraud/laurent/wst3d.cc (revision 3151)
+++ geraud/laurent/wst3d.cc (working copy)
@@ -1,79 +0,0 @@
-# include <cstdlib>
-# include <cstdio>
-
-# include <mln/value/int_u16.hh>
-# include <mln/value/int_u8.hh>
-# include <mln/level/stretch.hh>
-
-# include <mln/io/pgm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/core/var.hh>
-# include <mln/core/image/image3d.hh>
-# include <mln/core/alias/neighb3d.hh>
-
-# include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/closing_area.hh>
-# include <mln/morpho/closing_volume.hh>
-
-
-
-using namespace mln;
-using value::int_u8;
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.raw
lambda output.ppm" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
- using value::int_u16;
-
- if (argc != 3)
- usage(argv);
-
- trace::quiet = false;
-
- image3d<int_u16> ima16(256, 256, 256, 0);
- int size = 256 * 256 * 256 * 2;
-
- std::FILE* file = std::fopen(argv[1], "r");
- std::fread(ima16.buffer(), size, 1, file);
-
-// typedef image3d<int_u16> I;
-// mln_piter_(I) p(ima16.domain());
-// for_all(p)
-// if (ima16(p) != 0)
-// std::cout << ima16(p) << std::endl;
-
-// abort();
-
- int_u16 min_, max_;
- estim::min_max(ima16, min_, max_);
- std::cout << min_ << ' ' << max_ << std::endl;
-
- abort();
-
- image3d<int_u8> ima(ima16.domain());
- level::stretch(ima16, ima);
- ima16.destroy();
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- image3d<int_u8> clo(ima.domain());
- morpho::closing_volume(ima, c6(), lambda, clo);
-
- unsigned nbasins;
- image3d<unsigned> wst = morpho::meyer_wst(clo, c6(), nbasins);
- std::cout << "nbasins = " << nbasins << std::endl;
-}
Index: geraud/laurent/segmentation.hh
--- geraud/laurent/segmentation.hh (revision 3151)
+++ geraud/laurent/segmentation.hh (working copy)
@@ -1,14 +0,0 @@
-
-
-template <typename I, typename N>
-mln_ch_value(I, rgb8) segmentation(const I& ima,
- const N& nbh,
- unsigned area)
-{
- mln_concrete(I) filtered = morpho::closing_area(ima, nbh, area);
-
- unsigned nbasins;
- mln_ch_value(I, unsigned) wst = morpho::wst_meyer(filtered, nbh, nbasins);
-
- return level::transform(wst, colorize(nbasins));
-}
Index: geraud/irm.cc
--- geraud/irm.cc (revision 3151)
+++ geraud/irm.cc (working copy)
@@ -1,178 +0,0 @@
-
-#include <iterator>
-#include <iostream>
-#include <algorithm>
-
-#include <mln/core/image/image2d.hh>
-
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/alias/window2d.hh>
-#include <mln/core/image/image_if.hh>
-#include <mln/win/rectangle2d.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/level/transform.hh>
-
-#include <mln/convert/to_window.hh>
-#include <mln/convert/to_image.hh>
-#include <mln/convert/to_fun.hh>
-
-#include <mln/morpho/gradient.hh>
-#include <mln/morpho/closing_area.hh>
-#include <mln/morpho/meyer_wst.hh>
-
-#include <mln/accu/mean.hh>
-#include <mln/level/take.hh>
-
-#include <mln/util/graph.hh>
-
-#include <mln/debug/println.hh>
-
-
-mln::value::int_u8 foo(unsigned u)
-{
- return u == 0 ?
- 0 : // wshed line
- 1 + (u - 1) % 255; // basin
-}
-
-
-namespace mln
-{
-
- template <typename I>
- void doit(const I& irm,
- const image2d<unsigned>& lbl,
- unsigned nlabels)
- {
- {
-// accu::mean_<unsigned> m;
-
-// mln_piter(I) p(irm.domain());
-// for_all(p)
-// if (lbl(p) == 82)
-// m.take(irm(p));
-
-// level::take(irm | (pw::value(lbl) == pw::cst(82)), m);
-
-// std::cout << "reg 82 has mean = " << m << std::endl;
- }
-
- std::vector< accu::mean_<unsigned> > m(nlabels + 1);
- mln_piter(I) p(irm.domain());
- for_all(p)
- m[lbl(p)].take(irm(p));
-
-// for (unsigned l = 1; l <= nlabels; ++l)
-// std::cout << l << ":" << m[l] << "
";
-// std::cout << std::endl;
-
- accu::mean_<unsigned> mm;
- mm.take(m[70]);
- mm.take(m[77]);
- mm.take(m[80]);
- mm.take(m[82]);
- mm.take(m[99]);
- std::cout << mm.to_result() << std::endl;
- }
-
-
- /*template <typename I, typename N>
- void mk_graph(const I& lbl,
- N nbh,
- unsigned nlabels)
- {
- std::vector< std::vector<bool> > adja(nlabels + 1);
- for (unsigned l = 1; l <= nlabels; ++l)
- adja[l].resize(l, false);
-
- mln_piter(I) p(lbl.domain());
- mln_niter(N) n(nbh, p);
-
- // We compute the adjacency matrix of the RAG.
- for_all(p)
- if (lbl(p) == 0) // wshed
- {
- std::set<unsigned> s;
- for_all(n) if (lbl.has(n))
- {
- if (lbl(n) == 0)
- continue;
- s.insert(lbl(n));
- }
- if (s.size() < 2)
- {
- std::cout << "#" << std::endl;
- continue;
- }
- std::set<unsigned>::const_iterator l1, l2;
- for (l1 = s.begin(); l1 != s.end(); ++l1)
- {
- l2 = l1;
- for (++l2; l2 != s.end(); ++l2)
- adja[*l2][*l1] = true;
- }
- }
-
- unsigned count = 0;
- for (unsigned l1 = 2; l1 <= nlabels; ++l1)
- for (unsigned l2 = 1; l2 < l1; ++l2)
- if (adja[l1][l2])
- ++count;
- std::cout << "link count = " << count << std::endl;
-
- // Graph.
- util::graph<> g;
- // Nodes.
- for (unsigned i = 0; i <= nlabels; ++i)
- g.add_node();
- // Edges.
- for (unsigned l1 = 1; l1 <= nlabels; ++l1)
- for (unsigned l2 = l1 + 1; l2 <= nlabels; ++l2)
- if (adja[l1][l2])
- g.add_edge(l1, l2);
- g.print_debug (std::cout);
-
- }*/
-
-} // end of namespace mln
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- image2d<int_u8> irm;
- io::pgm::load(irm, "./+irm6cut.pgm");
-
-// io::pgm::save( morpho::gradient(irm, win::rectangle2d(3,3)),
-// "tmp_grad_3x3.pgm" );
-
- window2d c4p = convert::to_window(c4());
- c4p.insert(0,0);
-// debug::println(convert::to_image(c4p));
- image2d<int_u8> grad = morpho::gradient(irm, c4p);
- io::pgm::save( grad, "tmp_grad_c4p.pgm" );
-
- image2d<int_u8> clo;
- initialize(clo, irm);
-
- morpho::closing_area(grad, c4(), 100, clo);
- io::pgm::save( clo, "tmp_clo_a100.pgm" );
-
- unsigned nbasins;
- image2d<unsigned> wshed = morpho::meyer_wst(clo, c4(), nbasins);
- std::cout << "nbasins = " << nbasins << std::endl;
- io::pgm::save( level::transform(wshed, convert::to_fun(foo)),
- "tmp_wshed.pgm" );
-
-// doit(irm, wshed, nbasins);
-// mk_graph(wshed, c4(), nbasins);
-
-// std::vector< accu::mean_<unsigned> >
-
-}
Index: geraud/color/sum_pix.hh
--- geraud/color/sum_pix.hh (revision 3151)
+++ geraud/color/sum_pix.hh (working copy)
@@ -1,162 +0,0 @@
-// 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.
-
-#ifndef MLN_ACCU_SUM_PIX_HH
-# define MLN_ACCU_SUM_PIX_HH
-
-/// \file mln/accu/sum_pix.hh
-///
-/// Define an accumulator that computes a sum.
-
-# include <mln/core/concept/meta_accumulator.hh>
-# include <mln/accu/internal/base.hh>
-
-# include <mln/util/pix.hh> // To prevent accu::sum_pix to work on pixels
(ambiguous).
-
-# include <mln/trait/value_.hh> // For mln_sum_pix.
-# include <mln/value/builtin/all.hh> // In the case of summing builtin values.
-# include <mln/literal/zero.hh> // For initialization.
-
-
-namespace mln
-{
-
- namespace accu
- {
-
-
- /// Generic sum_pix accumulator class.
- /*!
- * Parameter \c T is the type of values that we sum. Parameter \c
- * S is the type to store the value sum; the default type of
- * \c S is the summation type (property) of \c T.
- */
- template <typename P, typename S = mln_sum(mln_value(P))>
- struct sum_pix : public mln::accu::internal::base< const S&,
sum_pix<P,S> >
- {
- typedef P argument;
-
- sum_pix();
-
- /// Manipulators.
- /// \{
- void init();
- void take(const argument& t);
- void take(const sum_pix<P,S>& other);
- /// \}
-
- void set_value(S v)
- {
- s_ = v;
- }
-
- /// Get the value of the accumulator.
- const S& to_result() const;
-
- /// Check whether this accu is able to return a result.
- /// Always true here.
- bool is_valid() const;
-
- protected:
-
- S s_;
- };
-
-
- namespace meta
- {
-
- /// Meta accumulator for sum_pix.
- struct sum_pix : public Meta_Accumulator< sum_pix >
- {
- template <typename P, typename S = mln_sum(mln_value(P))>
- struct with
- {
- typedef accu::sum_pix<P, S> ret;
- };
- };
-
- } // end of namespace mln::accu::meta
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename P, typename S>
- inline
- sum_pix<P,S>::sum_pix()
- {
- init();
- }
-
- template <typename P, typename S>
- inline
- void
- sum_pix<P,S>::init()
- {
- s_ = literal::zero;
- }
-
- template <typename P, typename S>
- inline
- void sum_pix<P,S>::take(const argument& p)
- {
- s_ += 1 + p.v();
- }
-
- template <typename P, typename S>
- inline
- void
- sum_pix<P,S>::take(const sum_pix<P,S>& other)
- {
- s_ += other.s_;
- }
-
- template <typename P, typename S>
- inline
- const S&
- sum_pix<P,S>::to_result() const
- {
- return s_;
- }
-
- template <typename P, typename S>
- inline
- bool
- sum_pix<P,S>::is_valid() const
- {
- return true;
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace mln::accu
-
-} // end of namespace mln
-
-
-#endif // ! MLN_ACCU_SUM_PIX_HH
Index: geraud/color/segment.cc
--- geraud/color/segment.cc (revision 3151)
+++ geraud/color/segment.cc (working copy)
@@ -1,639 +0,0 @@
-#include <cstdlib>
-
-#include <mln/core/var.hh>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/box3d.hh>
-
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/make/double_neighb2d.hh>
-
-#include <mln/core/image/image_if.hh>
-#include <mln/pw/all.hh>
-#include <mln/core/routine/extend.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/data/paste.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/load.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/math/diff_abs.hh>
-
-#include <mln/debug/println.hh>
-
-#include <mln/morpho/dilation.hh>
-#include <mln/morpho/erosion.hh>
-#include <mln/morpho/tree/data.hh>
-#include <mln/morpho/meyer_wst.hh>
-#include <mln/morpho/closing_attribute.hh>
-
-#include <mln/core/site_set/p_array.hh>
-#include <mln/level/sort_psites.hh>
-#include <mln/labeling/regional_minima.hh>
-
-
-#include <mln/accu/count.hh>
-#include <mln/accu/volume.hh>
-
-#include "sum_pix.hh"
-
-
-namespace mln
-{
-
- point3d color2point(const value::rgb8& c)
- {
- point3d p(c.red(), c.green(), c.blue());
- return p;
- }
-
-
- image2d<value::rgb8> blen_image;
-
-
- template <typename B>
- void accu_blen_take(B& b, const point2d& e)
- {
- if (e.row() % 2)
- {
- b.take(color2point(blen_image(e + up)));
- b.take(color2point(blen_image(e + down)));
- }
- else
- {
- b.take(color2point(blen_image(e + left)));
- b.take(color2point(blen_image(e + right)));
- }
- }
-
-}
-
-#include "blen_pix.hh"
-
-
-
-
-namespace mln
-{
-
- // Functions.
-
- inline
- bool is_row_odd(const point2d& p)
- {
- return p.row() % 2;
- }
-
- inline
- bool is_square(const point2d& p)
- {
- return p.row() % 2 == 0 && p.col() % 2 == 0;
- }
-
- inline
- bool is_edge(const point2d& p)
- {
- return p.row() % 2 + p.col() % 2 == 1;
- }
-
- inline
- bool is_point(const point2d& p)
- {
- return p.row() % 2 && p.col() % 2;
- }
-
-
- // Neighborhoods.
-
- typedef neighb< win::multiple<window2d, bool(*)(const point2d&)> >
dbl_neighb2d;
-
- const dbl_neighb2d& e2c()
- {
- static bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
- static bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
- static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2c_h, e2c_v);
- return nbh;
- }
-
- const dbl_neighb2d& e2e()
- {
- static bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
- static bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2e_h, e2e_v);
- return nbh;
- }
-
-
- // Transforms.
-
- template <typename T>
- image2d<T>
- image2full(const image2d<T>& input)
- {
- image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (int row = 0; row < input.nrows(); ++row)
- for (int col = 0; col < input.ncols(); ++col)
- opt::at(output, 2 * row, 2 * col) = opt::at(input, row, col);
- return output;
- }
-
- template <typename T>
- image2d<T>
- full2image(const image2d<T>& input)
- {
- image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (int row = 0; row < input.nrows(); row += 2)
- for (int col = 0; col < input.ncols(); col += 2)
- opt::at(output, row / 2, col / 2) =
- opt::at(input, row, col);
- return output;
- }
-
-
- // Display.
-
- template <typename I>
- I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-
-
- // Distance.
-
- value::int_u8 dist(const value::rgb8& c1, const value::rgb8& c2)
- {
- unsigned d = 0;
- d += (math::diff_abs(c1.red(), c2.red()) + 2) / 3;
- d += (math::diff_abs(c1.green(), c2.green()) + 2) / 3;
- d += (math::diff_abs(c1.blue(), c2.blue()) + 2) / 3;
- if (d > 255)
- d = 255;
- return d;
- }
-
- template <typename I, typename N>
- image2d<value::int_u8>
- dist(const I& input, const N& nbh)
- {
- image2d<value::int_u8> output;
- initialize(output, input);
- data::fill(output, 0);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- n.start();
- value::rgb8 c1 = input(n);
- n.next();
- value::rgb8 c2 = input(n);
- output(p) = dist(c1, c2);
- }
-
- return output;
- }
-
-
- // Sorting.
-
-
- template <typename I>
- struct my_less_
- {
- const I& ima_;
-
- inline
- my_less_(const I& ima)
- : ima_(ima)
- {
- }
-
- inline
- bool operator()(const mln_site(I)& lhs,
- const mln_site(I)& rhs) const
- {
- return util::ord_strict(ima_(lhs), ima_(rhs))
- || (ima_(lhs) == ima_(rhs)
- &&
- util::ord_strict(lhs, rhs));
- }
- };
-
-
- template <typename I, typename S>
- p_array<mln_site(I)> my_sort_increasing(const I& ima, const S& s)
- {
- p_array<mln_site(I)> v;
- convert::from_to(s, v);
- std::sort(v.hook_std_vector_().begin(), v.hook_std_vector_().end(),
- my_less_<I>(ima));
- return v;
- }
-
-
-
-
- // Tree -> attributes (on nodes only).
- // -----------------------------------
-
-
-
- template <typename A, typename T>
- inline
- mln_ch_value(typename T::function, mln_result(A))
- compute_attribute_on_nodes(const A& a, const T& t)
- {
- typedef typename T::function I;
-
- mln_ch_value(I, A) acc;
- mln_ch_value(I, mln_result(A)) attr;
-
- // Initialization of 'acc'.
- {
- initialize(acc, t.f());
- data::fill(acc, a); // Transfer "dynamic data" (state) of 'a'.
- }
-
- // Initialize every attribute with the corresponding pixel.
- {
- mln_piter(I) p(t.f().domain());
- for_all(p)
- acc(p).take_as_init(make::pix(t.f(), p));
- }
-
- // Propagate attribute from a site to its parent.
- {
- mln_fwd_piter(T) p(t.domain());
- for_all(p)
- if (! t.is_root(p))
- acc(t.parent(p)).take(acc(p));
- // No back-propagation to non-node sites.
- }
-
-
- // Change accumulator into its result.
- {
- initialize(attr, acc);
- typedef typename T::nodes_t N;
- mln_piter(N) p(t.nodes());
- for_all(p)
- {
- mln_invariant(t.is_a_node(p));
- attr(p) = acc(p).to_result();
- }
- }
-
- return attr;
- }
-
-
- template <typename A, typename T>
- inline
- mln_ch_value(typename T::function, mln_result(A))
- compute_rand_attribute_on_nodes(const A& a, const T& t)
- {
- typedef typename T::function I;
-
- mln_ch_value(I, mln_result(A)) attr;
- initialize(attr, t.f());
-
- // Initialize every attribute with the corresponding pixel.
- {
- mln_piter(I) p(t.f().domain());
- for_all(p)
- attr(p) = float(std::rand() % 10000) / 1000.f;
- }
-
- // Propagate attribute from a site to its parent.
- {
- mln_fwd_piter(T) p(t.domain());
- for_all(p)
- if (! t.is_root(p))
- attr(t.parent(p)) += attr(p);
- }
-
- return attr;
- }
-
-
-
- // Tree -> nchildren (on nodes).
- // -----------------------------
-
-
- template <typename T>
- inline
- mln_ch_value(typename T::function, unsigned)
- compute_nchildren(const T& t)
- {
- typedef typename T::function I;
- mln_ch_value(I, unsigned) nchildren;
- initialize(nchildren, t.f());
- data::fill(nchildren, 0);
-
- {
- mln_fwd_piter(T) p(t.domain());
- // Propagate attribute from a site to its parent.
- for_all(p)
- if (t.is_a_non_root_node(p))
- {
- mln_invariant(t.is_a_node(t.parent(p)));
- ++nchildren(t.parent(p)); // so parent(p) is a node
- }
- }
-
- return nchildren;
- }
-
-
-
-
- template <typename A, typename T, typename N>
- inline
- mln_concrete(typename T::function)
- filter(const A& a, const T& t, const N& nbh,
- unsigned n_objects,
- mln_value(A)& lambda,
- bool echo = false)
- {
- typedef typename T::function I;
-
- unsigned n_regmins_f; // This value can be obtained while computing the attributes!
- mln_ch_value(I, unsigned) regmins_f = labeling::regional_minima(t.f(), nbh,
n_regmins_f);
- if (echo)
- {
- debug::println("f =", t.f());
- debug::println("regmins(f) =", regmins_f);
- // debug::println("par on nodes = ", t.parent_image() | t.nodes());
- std::cout << "n regmins(f) = " << n_regmins_f << std::endl
- << std::endl;
- }
- if (n_objects >= n_regmins_f)
- {
- std::cout << "warning: number of expected objects is greater than number of
regmins!" << std::endl;
- std::cout << "aborting..." << std::endl;
- return duplicate(t.f());
- }
-
- lambda = mln_max(mln_value(A));
-
- mln_ch_value(typename T::function, unsigned) nchildren = compute_nchildren(t);
-
- typedef p_array<mln_site(I)> S;
- S s = my_sort_increasing(a, t.nodes());
-
- const typename T::parent_t& par = t.parent_image();
-
- unsigned
- count = n_regmins_f,
- less = 0;
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- if (a(p) < lambda && par(p) != p)
- {
- mln_assertion(nchildren(par(p)) > 0);
- --nchildren(par(p));
- if (nchildren(par(p)) != 0)
- {
- if (count <= n_objects)
- {
- ++less; // minus 1 object wrt the expected number!
- }
- --count;
- if (count == n_objects)
- {
- lambda = a(p) + 1;
- std::cout << "lambda = " << lambda << std::endl
- << std::endl;
- // break; // Stop iterations.
- }
- }
- }
- }
-
- if (less != 0)
- std::cerr << "WARNING: less objects (" << less <<
") than expected..." << std::endl
- << std::endl;
-
- if (echo)
- debug::println("nchildren =", nchildren | t.nodes());
-
-
- // Filtering.
- mln_concrete(I) g;
- {
- initialize(g, t.f());
- mln_bkd_piter(T) p(t.domain());
- for_all(p)
- if (t.is_a_node(p) && a(p) >= lambda)
- g(p) = t.f(p);
- else
- g(p) = g(par(p));
-
- if (echo)
- debug::println("g =", g);
- }
-
- if (echo)
- {
- unsigned n_regmins_g;
- debug::println( "regmin(g)", labeling::regional_minima(g, nbh, n_regmins_g)
);
- }
-
- return g;
- }
-
-
- template <typename A, typename I, typename N>
- void
- test_filter(A a, mln_result(A) lambda,
- const I& f, const I& g, const N& nbh,
- bool echo = false)
- {
- mln_concrete(I) g_ref = morpho::closing_attribute<A>(f, nbh, lambda);
- if (echo)
- debug::println("g_ref =", g_ref);
-
- unsigned n_regmins_g_ref;
- mln_ch_value(I, unsigned) regmin_g = labeling::regional_minima(g_ref, nbh,
n_regmins_g_ref);
- if (echo)
- std::cout << "n_regmins(g_ref) = " << n_regmins_g_ref
<< std::endl
- << std::endl;
-
- if (g != g_ref)
- std::cerr << "OOPS: g DIFFERS FROM ref!" << std::endl
- << std::endl;
-
-// bool consistency = (n_regmins_g_ref + less == n_objects);
-// if (consistency == false)
-// std::cerr << "OOPS: INCONSISTENCY (BUG...)!" << std::endl
-// << std::endl;
- }
-
-
-
-} // mln
-
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.ppm n
output.ppm" << std::endl;
- std::cerr << " n >= 2" << std::endl;
- abort();
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
- using value::rgb8;
-
- if (argc != 4)
- usage(argv);
-
-
- {
-
- // Color version.
- // --------------
-
-
- image2d<rgb8> input;
- io::ppm::load(input, argv[1]);
-
- unsigned n_objects = atoi(argv[2]);
-
-
- // Changing input into 'f on edges'.
-
- image2d<int_u8> f_;
- image2d<rgb8> input_ = image2full(input);
- {
- f_ = dist(extend(input_ | is_edge, pw::value(input_)),
- e2c());
- }
- mln_VAR(f, f_ | is_edge);
- typedef f_t I;
-
-
- // Filtering f -> g.
-
- typedef p_array<point2d> S;
- S s = level::sort_psites_decreasing(f);
-
- typedef morpho::tree::data<I,S> tree_t;
- tree_t t(f, s, e2e());
-
-// accu::count< util::pix<I> > a_;
-// accu::volume<I> a_;
- accu::sum_pix< util::pix<I> > a_;
-
-// blen_image = input_;
-// accu::blen_pix<I> a_;
-
- mln_VAR(a, compute_attribute_on_nodes(a_, t));
-
- mln_value_(a_t) lambda;
- f_t g = filter(a, t, e2e(), n_objects, lambda);
-
- test_filter(a_, lambda, f, g, e2e());
-
-
- // Watershed transform.
-
- int_u8 nbasins;
- mln_ch_value_(f_t, int_u8) w_edges = morpho::meyer_wst(g, e2e(), nbasins);
-
- // io::pgm::save(display_edge(w_edges.unmorph_(), 0, 3),
"temp_w_edges.pgm");
-
- image2d<int_u8> w_all = w_edges.unmorph_();
- {
- // edges -> squares
- mln_VAR(w_squares, w_all | is_square);
- data::paste(morpho::dilation(extend(w_squares, pw::value(w_all)),
- c4().win()),
- w_all);
- // edges -> points
- mln_VAR(w_points, w_all | is_point);
- data::paste(morpho::erosion(extend(w_points, pw::value(w_all)),
- c4().win()),
- w_all);
- }
-
- io::pgm::save(w_all, "temp_w_all.pgm");
-
- }
-
-
-// {
-// // Gray-level version.
-
-// image2d<int_u8> f_;
-// io::pgm::load(f_, argv[1]);
-
-// unsigned n_objects = atoi(argv[2]);
-
-// mln_VAR(f, f_ | is_edge);
-// typedef f_t I;
-
-// typedef p_array<point2d> S;
-// S s = level::sort_psites_decreasing(f);
-
-// typedef morpho::tree::data<I,S> tree_t;
-// tree_t t(f, s, e2e());
-
-// accu::count< util::pix<I> > a_;
-// mln_VAR(a, compute_attribute_on_nodes(a_, t));
-
-// f_t g = filter(a, t, e2e(), n_objects);
-
-// unsigned nbasins;
-// debug::println("wst =", morpho::meyer_wst(g, e2e(), nbasins));
-// }
-
-
-}
Index: geraud/color/blen_pix.hh
--- geraud/color/blen_pix.hh (revision 3151)
+++ geraud/color/blen_pix.hh (working copy)
@@ -1,174 +0,0 @@
-// 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.
-
-#ifndef MLN_ACCU_BLEN_PIX_HH
-# define MLN_ACCU_BLEN_PIX_HH
-
-/// \file mln/accu/blen_pix.hh
-///
-/// Define an accumulator that computes a sum.
-
-# include <mln/core/concept/meta_accumulator.hh>
-# include <mln/accu/bbox.hh>
-# include <mln/accu/internal/base.hh>
-
-# include <mln/util/pix.hh> // To prevent accu::blen_pix to work on pixels
(ambiguous).
-
-# include <mln/trait/value_.hh> // For mln_blen_pix.
-# include <mln/value/builtin/all.hh> // In the case of summing builtin values.
-# include <mln/literal/zero.hh> // For initialization.
-
-# include <mln/core/alias/point3d.hh>
-
-
-namespace mln
-{
-
-
- namespace accu
- {
-
-
- /// Generic blen_pix accumulator class.
- template <typename I>
- struct blen_pix : public mln::accu::internal::base< unsigned, blen_pix<I>
>
- {
- typedef util::pix<I> argument;
-
- blen_pix();
-
- /// Manipulators.
- /// \{
- void init();
- void take(const argument& t);
- void take(const blen_pix<I>& other);
- /// \}
-
- void set_value(unsigned v)
- {
- len_ = v;
- }
-
- /// Get the value of the accumulator.
- unsigned to_result() const;
-
- /// Check whether this accu is able to return a result.
- /// Always true here.
- bool is_valid() const;
-
- const accu::bbox<point3d>& b() const
- {
- return b_;
- }
-
- accu::bbox<point3d>& b()
- {
- return b_;
- }
-
- protected:
-
- accu::bbox<point3d> b_;
- unsigned len_;
- };
-
-
- template <typename B>
- unsigned max_len(const Box<B>& b_)
- {
- const B& b = exact(b_);
- typedef mln_site(B) P;
- enum { n = P::dim };
- unsigned len = b.len(0);
- for (unsigned i = 1; i < n; ++i)
- if (b.len(i) > len)
- len = b.len(i);
- return len;
- }
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename I>
- inline
- blen_pix<I>::blen_pix()
- {
- init();
- }
-
- template <typename I>
- inline
- void
- blen_pix<I>::init()
- {
- b_.init();
- len_ = 0;
- }
-
- template <typename I>
- inline
- void blen_pix<I>::take(const argument& pxl)
- {
- const mln_site(I)& p = pxl.p();
- accu_blen_take(b_, p);
- len_ = max_len(b_.to_result());
- }
-
- template <typename I>
- inline
- void
- blen_pix<I>::take(const blen_pix<I>& other)
- {
- b_.take(other.b());
- len_ = max_len(b_.to_result());
- }
-
- template <typename I>
- inline
- unsigned
- blen_pix<I>::to_result() const
- {
- return len_;
- }
-
- template <typename I>
- inline
- bool
- blen_pix<I>::is_valid() const
- {
- return true;
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace mln::accu
-
-} // end of namespace mln
-
-
-#endif // ! MLN_ACCU_BLEN_PIX_HH