r3773: Fixed watershed, now works on edges

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2009-05-07 Fabien Freling <fabien.freling@lrde.epita.fr> Fixed watershed, now works on edges. * fabien/igr/Makefile.rules: Optimization flag is now -O1. * fabien/igr/seg_fixed.cc: Fixed 'float' bug on edges. --- TODO | 7 +- igr/Makefile.rules | 2 igr/seg_fixed.cc | 171 +++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 167 insertions(+), 13 deletions(-) Index: trunk/milena/sandbox/fabien/igr/seg_fixed.cc =================================================================== --- trunk/milena/sandbox/fabien/igr/seg_fixed.cc (revision 3772) +++ trunk/milena/sandbox/fabien/igr/seg_fixed.cc (revision 3773) @@ -5,34 +5,53 @@ #include <mln/core/alias/neighb2d.hh> #include <mln/core/image/image3d.hh> #include <mln/core/image/slice_image.hh> +#include <mln/core/image/image_if.hh> #include <mln/core/routine/duplicate.hh> +#include <mln/core/routine/extend.hh> +#include <mln/core/var.hh> #include <mln/io/dump/all.hh> #include <mln/io/pgm/save.hh> +#include <mln/io/ppm/save.hh> #include <mln/value/int_u8.hh> #include <mln/value/int_u12.hh> #include <mln/value/label_16.hh> +#include <mln/value/rgb8.hh> +#include <mln/value/float01_8.hh> #include <mln/accu/sum.hh> #include <mln/data/fill.hh> +#include <mln/data/paste.hh> #include <mln/debug/quiet.hh> #include <mln/convert/from_to.hh> #include <mln/level/compute.hh> #include <mln/level/stretch.hh> +#include <mln/make/image2d.hh> +#include <mln/math/diff_abs.hh> +#include <mln/morpho/dilation.hh> +#include <mln/morpho/erosion.hh> #include <mln/morpho/closing/volume.hh> +#include <mln/morpho/elementary/gradient.hh> #include <mln/morpho/watershed/flooding.hh> +#include <mln/pw/all.hh> #include <mln/util/array.hh> #include <mln/world/inter_pixel/display_edge.hh> +#include <mln/world/inter_pixel/compute.hh> +#include <mln/world/inter_pixel/immerse.hh> #include <mln/world/inter_pixel/neighb2d.hh> -#include <mln/world/inter_pixel/dim2/is_edge.hh> +#include <mln/world/inter_pixel/is_pixel.hh> + +#include <mln/debug/colorize.hh> +#include <mln/debug/println.hh> using namespace mln; using value::int_u8; using value::int_u12; using value::label_16; +using value::float01_8; @@ -77,7 +96,7 @@ else res = 0.f; - //std::cout << "dist: " << res << std::endl; + res = res; return 1 - res; } @@ -132,6 +151,67 @@ } +// Dummy. +/////////////////////////////////////////////////////////////////////////////// +template <typename I, typename N> +inline +image2d<int> +dummy_dist_on_edges(const I& input, const N& nbh) +{ + image2d<int> 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(); + int c1 = input(n); + n.next(); + int c2 = input(n); + output(p) = math::diff_abs(c1, c2); + } + + return output; +} + + + +// Distance function. +//------------------- + +struct dist_t : Function_vv2v<dist_t> +{ + typedef float result; + + template <typename V> + float operator()(util::array<V> v1, util::array<V> v2) const + { + float res = 0.f; + + for (unsigned i = 0; i < v1.nelements(); ++i) + res += std::min(v1[i], v2[i]); + + image1d<V> tmp_ima; + accu::sum<V> accu_sum; + + convert::from_to(v1, tmp_ima); + float sum_v1 = level::compute(accu_sum, tmp_ima); + + convert::from_to(v2, tmp_ima); + float sum_v2 = level::compute(accu_sum, tmp_ima); + + res /= std::max(sum_v1, sum_v2); + + return 1 - res; + } +} dist; + + + + + @@ -146,10 +226,12 @@ if (argc != 3) return usage(argv[0]); + // Initialization. image3d<int_u12> input; io::dump::load(input, argv[1]); - image2d<util::array<int_u12> > ima_arr; + typedef image2d<util::array<int_u12> > I; + I ima_arr; initialize(ima_arr, slice(input, 0)); for (unsigned int i = 0; i < input.nslices(); ++i) { @@ -159,23 +241,92 @@ ima_arr(p).append(tmp_slice(p)); } - // Edges computation. - image2d<float> edges = dist_on_edges(ima_arr); + // Edges image creation. + //image2d<float> edges = dist_on_edges(ima_arr); + typedef image_if<I, world::inter_pixel::is_pixel> Ix; + Ix imax = world::inter_pixel::immerse(ima_arr); + + // Edges distance computation. + mln_VAR(edges, world::inter_pixel::compute(imax, dist)); + + { // Display. - image2d<float> display_ima = world::inter_pixel::display_edge(edges, 0.0, 3); + mln_VAR(display_ima, world::inter_pixel::display_edge(edges.unmorph_(), 0.0, 3)); io::pgm::save(level::stretch(int_u8(), display_ima), "edges.pgm"); + } + + // Save edges. + //mln_VAR(e, edges.unmorph_()); + //data::fill((e | (!world::inter_pixel::is_separator())).rw(), nbasins.next()); + //io::pgm::save(level::stretch(int_u8(), edges.unmorph_()), "edges_raw.pgm"); + + mln_VAR(e, level::stretch(int_u8(), edges)); + + { + // Display. + mln_VAR(display_ima, world::inter_pixel::display_edge(e.unmorph_(), 0.0, 3)); + io::pgm::save(level::stretch(int_u8(), display_ima), "e.pgm"); + } // Closing. - image2d<float> clo = morpho::closing::volume(edges, world::inter_pixel::e2e(), atoi(argv[2])); + mln_VAR(clo, morpho::closing::volume(e, world::inter_pixel::e2e(), atoi(argv[2]))); + + { + // Display. + mln_VAR(display_clo, world::inter_pixel::display_edge(clo.unmorph_(), 0.0, 3)); + io::pgm::save(level::stretch(int_u8(), display_clo), "edges2.pgm"); + } + + typedef label_16 L; + L nbasins; + mln_VAR(wst, morpho::watershed::flooding(clo, world::inter_pixel::e2e(), nbasins)); + + mln_VAR(w, wst.unmorph_()); + data::fill((w | (!world::inter_pixel::is_separator())).rw(), nbasins.next()); + io::ppm::save(debug::colorize(value::rgb8(), w, nbasins.next()), "result.ppm"); + + + + + + + + + + + + + /*mln_VAR(clo, morpho::closing::volume(edges | world::inter_pixel::dim2::is_edge(), world::inter_pixel::e2e(), atoi(argv[2]))); + + // Debug. + //debug::println("clo", clo); + + // Display. + image2d<float> display_ima2 = world::inter_pixel::display_edge(clo.unmorph_(), 0.0, 3); + io::pgm::save(level::stretch(int_u8(), display_ima2), "edges2.pgm"); // Watershed. - label_16 nbasins; - image2d<label_16> wst = morpho::watershed::flooding(clo, world::inter_pixel::e2e(), nbasins); + typedef label_16 L; + L nbasins; + mln_VAR(wst, morpho::watershed::flooding(clo, world::inter_pixel::e2e(), nbasins)); + + // Debug. + //debug::println("wst", wst); + + // Extension. + image2d<L> w_all = wst.unmorph_(); + // edges -> pixel + mln_VAR(w_pixels, w_all | world::inter_pixel::dim2::is_pixel()); + data::paste(morpho::dilation(extend(w_pixels, pw::value(w_all)), c4().win()), w_all); + // edges -> dots + mln_VAR(w_dots, w_all | world::inter_pixel::dim2::is_dot()); + data::paste(morpho::erosion(extend(w_dots, pw::value(w_all)), c4().win()), w_all); + // Save labels map. std::cout << "nbasins: " << nbasins << std::endl; - io::dump::save(wst, "watershed_fixed.dump"); + io::dump::save(wst.unmorph_(), "watershed_fixed.dump");*/ return 0; } Index: trunk/milena/sandbox/fabien/igr/Makefile.rules =================================================================== --- trunk/milena/sandbox/fabien/igr/Makefile.rules (revision 3772) +++ trunk/milena/sandbox/fabien/igr/Makefile.rules (revision 3773) @@ -1,5 +1,5 @@ CXX = g++ -CXXFLAGS = -Wall -Wextra -DNDEBUG -O3 +CXXFLAGS = -Wall -Wextra -DNDEBUG -O1 DICOM_INC = -I/usr/local/include/gdcm-2.0 DICOM_LIBS = -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib \ Index: trunk/milena/sandbox/fabien/TODO =================================================================== --- trunk/milena/sandbox/fabien/TODO (revision 3772) +++ trunk/milena/sandbox/fabien/TODO (revision 3773) @@ -7,5 +7,8 @@ ||----w | || || -[ ] Create values between pixels -[ ] Watershed between pixels +[X] Create values between pixels +[X] Watershed between pixels +[ ] Sum of watershed slices +[X] Fix display_edge +[ ] Save edges image
participants (1)
-
Fabien Freling