
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox Index: ChangeLog from Ugo Jardonnet <jardonnet@lrde.epita.fr> Add stuff for report. * jardonnet/n_cmpt/tikz.hh: New. Generate tikz and various images. * jardonnet/n_cmpt/tikz.cc: New. tikz.cc | 63 +++++++++++++++ tikz.hh | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 317 insertions(+) Index: jardonnet/n_cmpt/tikz.hh --- jardonnet/n_cmpt/tikz.hh (revision 0) +++ jardonnet/n_cmpt/tikz.hh (revision 0) @@ -0,0 +1,254 @@ +// 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_N_CMPT3_HH +# define MLN_N_CMPT3_HH + +# include <mln/labeling/regional_minima.hh> +# include <mln/core/alias/neighb2d.hh> +# include <mln/util/set.hh> + +# include <mln/debug/println.hh> +# include <mln/debug/iota.hh> + +# include <mln/accu/volume.hh> +# include <mln/morpho/tree/data.hh> +# include <mln/morpho/tree/compute_attribute_image.hh> + +# include <mln/level/paste.hh> + +namespace mln +{ + + namespace n_cmpt + { + + template < typename I > + void n_cmpt5(const I& (((((((ima)))))))); + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + inline + mln_psite(I) + find_root(I& parent, + const mln_psite(I)& x) + { + if (parent(x) == x) + return x; + else + return parent(x) = find_root(parent, parent(x)); + } + + template < typename I, typename N> + I + n_cmpt3(const I& ima, const N& nbh, + unsigned lambda) + { + std::cout << "/ima/" << std::endl; + debug::println(ima); + io::tikz::save(ima, "ima.tex"); + + // compute volume image + //--------------------- + + typedef p_array<mln_psite(I)> S; + typedef mln_ch_value(I, value::int_u<16>) V; + typedef accu::volume<I> A; + + S sp = level::sort_psites_decreasing(ima); + morpho::tree::data<I,S> t(ima, sp, nbh); + + V volume(ima.domain()); + level::paste(morpho::tree::compute_attribute_image(A(), t), + volume); + + sp = level::sort_psites_increasing(volume); + std::cout << "/volume/" << std::endl; + debug::println(volume); + io::tikz::save(volume, "volume.tex"); + io::pgm::save(volume, "volume.pgm"); + + + // get /volume/ regional minima + //----------------------------- + + unsigned label; + mln_ch_value(I, unsigned) min_v = labeling::regional_minima(volume, nbh, label); + std::cout << "/volume/ regional minima" << std::endl; + debug::println(min_v); + + // number of minima + unsigned cmpts = label; + if (lambda > cmpts) + std::cout << "warning : lambda value is to hight." << std::endl; + + std::cout << cmpts << std::endl; + + + // two pass algo + //-------------- + + // init fused image + mln_ch_value(I, bool) fused; + initialize(fused, volume); + mln::level::fill(fused, false); + + // prepare union find + typedef mln_psite(V) P; + + //data + mln_ch_value(V, accu::volume<V>) data(volume.domain()); + + //deja_vu + mln_ch_value(V, bool) deja_vu(volume.domain()); + mln::level::fill(deja_vu, false); + + //parent + mln_ch_value(V, P) parent(volume.domain()); + { + mln_fwd_piter(S) p(sp); + 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 VOLUME + mln_fwd_piter(S) p(sp); + mln_niter(N) n(nbh, p); + for_all(p) + { + std::cout << p << std::endl; + //if (volume(p) > lambda) + // goto step2; + for_all(n) + { + if (volume.domain().has(n) && deja_vu(n)) + { + //do_union(n, p); + P r = find_root(parent, n); + if (r != p) + { + std::cout << "neighb: " << n << std::endl; + std::cout << "v(r): " << volume(r) << " v(p): " << volume(p) << " f(p): " << fused(p) << std::endl; + + //if (volume(r) != volume(p)) // r and p have different volumes + // This check was wrong. + // you just fused with a minima. + // then you fuse with a neighbor already fused that has the same volume as you + // a) 1 50 1 + // 2 2 2 + // we don't have ( volume(r) == volume(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 + { + cmpts--; + std::cout << "dec" << std::endl; + } + + mln_invariant(fused(r) || volume(r) == volume(p)); + + // Union made if + if (cmpts >= lambda || // union is still allowed or + not fused(r) || // r not fused or + not fused(p) || // p not fused or + min_v(p) != 0) // p is a minima + { + std::cout << "fuse" << p << n << std::endl; + parent(r) = p; + + // This test is mandatory. Sometimes (--_) points are fused + // tought 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 enought. + // 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) => ( volume(r) == volume(p) ) + mln_invariant(fused(r) || volume(r) == volume(p)); + // fused(r) and ( volume(r) == volume(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::cerr << "volume " << volume(p) << " - " << cmpts << std::endl; + //debug::println(fused); + } + } + } + } + deja_vu(p) = true; + } + + mln_ch_value(I,value::int_u<16>) iota(ima.domain()); + debug::iota(iota); + + std::cout << std::endl; + std::cout << "cmpts : " << cmpts << std::endl; + + // second pass + I output(ima.domain()); + { + mln_bkd_piter(S) p(sp); + 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 n_cmpt + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif /* MLN_N_CMPT3_HH */ + Index: jardonnet/n_cmpt/tikz.cc --- jardonnet/n_cmpt/tikz.cc (revision 0) +++ jardonnet/n_cmpt/tikz.cc (revision 0) @@ -0,0 +1,63 @@ + +#include <iostream> + +#include <mln/core/image/image2d.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/value/int_u8.hh> + +#include <mln/make/image.hh> +#include <mln/core/alias/neighb1d.hh> + +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> + +#include <mln/io/tikz/save.hh> + +#include <cmath> + +#include "tickz.hh" + +using namespace mln; +using namespace mln::value; + +bool usage(int argc, char ** argv) +{ + if (argc != 3) + { + std::cout << argv[0] << " ima.pgm lambda" << std::endl; + return false; + } + return true; +} + +int main(int argc, char ** argv) +{ + if (not usage(argc,argv)) + return 1; + + image2d<int_u8> ima; + io::pgm::load(ima, argv[1]); + unsigned lambda = atoi(argv[2]); + + image2d<int_u8> cos_(6,6); + for (int i = 0; i <= 6; i++) + for (int j = 0; j <= 6; j++) + cos_(point2d(i,j)) = (sin(i) * cos(j) + 1)/2*255; + io::pgm::save(cos_, "cos.pgm"); + + int_u8 tree[5][5] = + { + {100, 160, 160, 100, 100}, + {160, 220, 220, 100, 100}, + {160, 160, 220, 100, 100}, + {220, 160, 100, 100, 100}, + {100, 160, 100, 160, 160}, + }; + + io::tikz::save(make::image(tree), "tree.tex"); + + int_u8 tab[] = {2,3,1,0,2,3,4,5,1,1,0,5,6,8,7,1,1,2,3,4}; + image1d<int_u8> ima1= make::image(tab); + + n_cmpt::n_cmpt3(ima, c4(), lambda); +}
participants (1)
-
Ugo Jardonnet