
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Clean erosion and dilation a bit. * doc/examples/tuto_one.cc: Cleanup. (argv): New argument for chosing neighborhood. * mln/border/resize.hh (todo): New. * mln/morpho/erosion.spe.hh, * mln/morpho/erosion.hh, * mln/morpho/dilation.hh, * mln/morpho/dilation_fast.hh: Use extension fill. Anticipate border adjust. * mln/extension/all.hh: New. * mln/morpho/includes.hh: Update. doc/examples/tuto_one.cc | 107 +++++++++++++++++++++++++------------------- mln/border/resize.hh | 3 + mln/extension/all.hh | 51 ++++++++++++++++++++ mln/morpho/dilation.hh | 12 ++++ mln/morpho/dilation_fast.hh | 6 +- mln/morpho/erosion.hh | 13 ++++- mln/morpho/erosion.spe.hh | 23 +++++++-- mln/morpho/includes.hh | 3 - 8 files changed, 160 insertions(+), 58 deletions(-) Index: doc/examples/tuto_one.cc --- doc/examples/tuto_one.cc (revision 2409) +++ doc/examples/tuto_one.cc (working copy) @@ -3,41 +3,35 @@ # 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/core/alias/window2d.hh> - -# include <mln/convert/to_p_set.hh> -# include <mln/convert/to_image.hh> -# include <mln/debug/println.hh> - # include <mln/make/double_neighb2d.hh> -# include <mln/io/pgm/load.hh> -# include <mln/io/pgm/save.hh> -# include <mln/io/pbm/save.hh> -# include <mln/io/ppm/save.hh> - # include <mln/level/transform.hh> # include <mln/literal/black.hh> -# include <mln/pw/all.hh> +# include <mln/debug/println.hh> # include <mln/morpho/closing_area.hh> # include <mln/morpho/gradient.hh> # include <mln/morpho/meyer_wst.hh> +using namespace mln; +using value::int_u8; -struct colorize : mln::Function_v2v< colorize > +struct colorize : Function_v2v< colorize > { - typedef mln::value::rgb8 result; + typedef value::rgb8 result; colorize(unsigned max) : lut(max + 1) { - lut[0] = mln::literal::black; + lut[0] = literal::black; for (unsigned i = 1; i <= max; ++i) lut[i] = result(100 + std::rand() % 150, 100 + std::rand() % 150, @@ -51,7 +45,7 @@ }; - bool is_chess(const mln::point2d& p) +bool is_chess(const point2d& p) { return p.col() % 2 == p.row() % 2; } @@ -59,23 +53,67 @@ void usage(char* argv[]) { - std::cerr << "usage: " << argv[0] << " input.pgm lambda output.ppm" << std::endl; + 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.win()); + + 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); + + 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[]) { - using namespace mln; - using value::int_u8; + 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); - if (argc != 4) + int lambda = atoi(argv[3]); + if (lambda < 0) usage(argv); - image2d<int_u8> lena; - io::pgm::load(lena, argv[1]); + 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 }; @@ -85,29 +123,6 @@ 1, 1, 0 }; mln_VAR( nbh, make::double_neighb2d(is_chess, vert, hori) ); -// mln_VAR(nbh, c4()); -// mln_VAR(nbh, c8()); - - image2d<int_u8> clo, grad = morpho::gradient(lena, nbh.win()); - // io::pgm::save(grad, "tmp_grad.pgm"); - - int lambda = atoi(argv[2]); - if (lambda > 1) - { - clo = morpho::closing_area(grad, nbh, lambda); - io::pgm::save(clo, "tmp_clo.pgm"); + do_it(ima, nbh, lambda, filename); } - else - clo = grad; - - unsigned l; - image2d<unsigned> wst = morpho::meyer_wst(clo, nbh, l); - - std::cout << "l = " << l << std::endl; - debug::println(wst); - - io::ppm::save(level::transform(wst, colorize(l)), argv[3]); - -// io::pbm::save((pw::value(wst) == pw::cst(0)) | lena.domain(), -// argv[3]); } Index: mln/border/resize.hh --- mln/border/resize.hh (revision 2409) +++ mln/border/resize.hh (working copy) @@ -34,6 +34,9 @@ * image. * * \todo Use level::fill!!! + * + * \todo Test with a primary image with no notion of border; I guess + * it does not work. */ # include <mln/core/concept/image.hh> Index: mln/morpho/erosion.spe.hh --- mln/morpho/erosion.spe.hh (revision 2409) +++ mln/morpho/erosion.spe.hh (working copy) @@ -45,7 +45,10 @@ * * \brief Specialization for mln::morpho::erosion. * + * \todo Warning: we should also have the "arbitrary" versions working + * on sets (not only on functions!) * + * \todo Activate the FIXMEs (border::adjust). */ # ifndef MLN_INCLUDE_ONLY @@ -91,9 +94,11 @@ const I& input = exact(input_); const W& win = exact(win_); + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_max(mln_value(I))); + O output; initialize(output, input); - extension::fill(input, mln_max(mln_value(I))); mln_pixter(const I) p(input); mln_pixter(O) o(output); @@ -122,9 +127,11 @@ const I& input = exact(input_); const W& win = exact(win_); + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, true); + O output; initialize(output, input); - extension::fill(input, true); mln_pixter(const I) p(input); mln_pixter(O) p_out(output); @@ -152,11 +159,13 @@ typedef mln_concrete(I) O; const I& input = exact(input_); const W& win = exact(win_); - O output; + // FIXME: border::adjust(input, win.delta()); extension::fill(input, true); + O output; output = clone(input); + mln_piter(I) p(input.domain()); mln_qiter(W) q(win, p); for_all(p) @@ -181,11 +190,13 @@ typedef mln_concrete(I) O; const I& input = exact(input_); const W& win = exact(win_); - O output; + // FIXME: border::adjust(input, win.delta()); extension::fill(input, true); + O output; output = clone(input); + mln_pixter(const I) p(input); mln_qixter(const I, W) q(p, win); mln_pixter(O) p_out(output); @@ -280,6 +291,8 @@ void init() { + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_max(mln_value(I))); initialize(output, input); min.init(); p = input.domain().pmin() + up; @@ -375,6 +388,8 @@ void init() { + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_max(mln_value(I))); initialize(output, input); min.init(); p = input.domain().pmin() + up; Index: mln/morpho/erosion.hh --- mln/morpho/erosion.hh (revision 2409) +++ mln/morpho/erosion.hh (working copy) @@ -30,6 +30,8 @@ /// \file mln/morpho/erosion.hh /// \brief Morphological erosion. +/// +/// \todo Activate the FIXMEs (border::adjust). # include <mln/morpho/includes.hh> @@ -70,16 +72,20 @@ const I& input = exact(input_); const W& win = exact(win_); + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_max(mln_value(I))); + mln_concrete(I) output; initialize(output, input); accu::min_<mln_value(I)> min; + mln_piter(I) p(input.domain()); mln_qiter(W) q(win, p); for_all(p) { min.init(); - for_all(q) if (input.domain().has(q)) + for_all(q) if (input.has(q)) min.take(input(q)); output(p) = min; } @@ -100,6 +106,9 @@ const I& input = exact(input_); const W& win = exact(win_); + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, true); + mln_concrete(I) output; initialize(output, input); @@ -107,7 +116,7 @@ mln_qiter(W) q(win, p); for_all(p) { - for_all(q) if (input.domain().has(q)) + for_all(q) if (input.has(q)) if (input(q) == false) break; output(p) = ! q.is_valid(); Index: mln/morpho/dilation.hh --- mln/morpho/dilation.hh (revision 2409) +++ mln/morpho/dilation.hh (working copy) @@ -30,6 +30,8 @@ /// \file mln/morpho/dilation.hh /// \brief Morphological dilation. +/// +/// \todo Activate the FIXMEs (border::adjust). # include <mln/morpho/includes.hh> @@ -92,6 +94,9 @@ const W& win = exact(win_); O& output = exact(output_); + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_min(mln_value(I))); + accu::max_<mln_value(I)> max; mln_piter(I) p(input.domain()); @@ -99,7 +104,7 @@ for_all(p) { max.init(); - for_all(q) if (input.domain().has(q)) + for_all(q) if (input.has(q)) max.take(input(q)); output(p) = max.to_result(); } @@ -116,13 +121,16 @@ const W& win = exact(win_); O& output = exact(output_); + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, false); + level::fill(output, input); mln_piter(I) p(input.domain()); mln_qiter(W) q(win, p); for_all(p) if (!input(p)) - for_all(q) if (input.domain().has(q)) + for_all(q) if (input.has(q)) if (input(q)) { output(p) = true; Index: mln/morpho/includes.hh --- mln/morpho/includes.hh (revision 2409) +++ mln/morpho/includes.hh (working copy) @@ -55,8 +55,7 @@ # include <mln/test/positive.hh> -// # include <mln/border/all.hh> -# include <mln/extension/fill.hh> +# include <mln/extension/all.hh> # include <mln/geom/sym.hh> # include <mln/set/inter.hh> Index: mln/morpho/dilation_fast.hh --- mln/morpho/dilation_fast.hh (revision 2409) +++ mln/morpho/dilation_fast.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// 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 @@ -30,7 +30,7 @@ /*! \file mln/morpho/dilation_fast.hh * - * \brief Ero filtering of an image. + * \brief Dilation filtering of an image with arbitrary s.e. * * \todo Add fastest versions. */ @@ -124,6 +124,8 @@ inline void init() { + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_min(mln_value(I))); max.init(); mln_qiter(W) q(win, p); for_all(q) if (input.has(q)) Index: mln/extension/all.hh --- mln/extension/all.hh (revision 0) +++ mln/extension/all.hh (revision 0) @@ -0,0 +1,51 @@ +// 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_EXTENSION_ALL_HH +# define MLN_EXTENSION_ALL_HH + +/*! \file mln/pw/all.hh + * + * \brief File that includes all extension materials. + * + * \todo Also include "extension images" + "extended"? + */ + + +namespace mln +{ + + /// Namespace of extension tools. + namespace extension {} + +} // end of namespace mln + + +# include <mln/extension/fill.hh> + + +#endif // ! MLN_EXTENSION_ALL_HH