
Optimize regional maxima processing for statistical counts and outputs. * green/demo/labeling/regional_maxima/Makefile.am: Add some compilation directives. * green/demo/labeling/regional_maxima/regional_maxima.cc (t_channel,t_labeling_rgbn,label_image,unquant,print_count2): New. * green/demo/labeling/regional_maxima/regional_maxima.cc (print_count, merge, do_demo) : Update. --- milena/sandbox/ChangeLog | 14 +- .../demo/labeling/regional_maxima/Makefile.am | 2 + .../labeling/regional_maxima/regional_maxima.cc | 661 ++++++++++++++------ 3 files changed, 471 insertions(+), 206 deletions(-) diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog index 37cce8a..aed61bf 100644 --- a/milena/sandbox/ChangeLog +++ b/milena/sandbox/ChangeLog @@ -1,9 +1,21 @@ 2009-12-02 Yann Jacquelet <jacquelet@lrde.epita.fr> + Optimize regional maxima processing for statistical counts and outputs. + + * green/demo/labeling/regional_maxima/Makefile.am: Add some compilation + directives. + * green/demo/labeling/regional_maxima/regional_maxima.cc + (t_channel,t_labeling_rgbn,label_image,unquant,print_count2): New. + * green/demo/labeling/regional_maxima/regional_maxima.cc + (print_count, merge, do_demo) : Update. + + +2009-12-02 Yann Jacquelet <jacquelet@lrde.epita.fr> + Test experimentation with regmax code on annoting database. * green/exp/labeling/regional_maxima/Makefile.am: New Makefile. - * green/exp/clustering/regional_maxima/regional_maxima.cc: New directory + * green/exp/labeling/regional_maxima/regional_maxima.cc: New directory oriented demonstration code. 2009-12-02 Yann Jacquelet <jacquelet@lrde.epita.fr> diff --git a/milena/sandbox/green/demo/labeling/regional_maxima/Makefile.am b/milena/sandbox/green/demo/labeling/regional_maxima/Makefile.am index 91230b6..1dd1cfb 100644 --- a/milena/sandbox/green/demo/labeling/regional_maxima/Makefile.am +++ b/milena/sandbox/green/demo/labeling/regional_maxima/Makefile.am @@ -8,6 +8,8 @@ INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES) +#CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES) ECHO= echo RM= rm MKDIR= mkdir -p diff --git a/milena/sandbox/green/demo/labeling/regional_maxima/regional_maxima.cc b/milena/sandbox/green/demo/labeling/regional_maxima/regional_maxima.cc index 34801ed..266fbfe 100644 --- a/milena/sandbox/green/demo/labeling/regional_maxima/regional_maxima.cc +++ b/milena/sandbox/green/demo/labeling/regional_maxima/regional_maxima.cc @@ -1,66 +1,257 @@ // DEMO ON REGIONAL MAXIMA -#include <mln/clustering/kmean2d.hh> - #include <iostream> #include <sstream> #include <mln/img_path.hh> -#include <mln/pw/value.hh> -#include <mln/value/label_8.hh> -#include <mln/value/rgb8.hh> +#include <mln/accu/math/sum.hh> +#include <mln/accu/stat/histo3d_rgb.hh> +#include <mln/accu/stat/mean.hh> +#include <mln/accu/stat/variance.hh> + +#include <mln/algebra/vec.hh> + +// #include <mln/arith/revert.hh> +#include <mln/arith/diff_abs.hh> #include <mln/core/macros.hh> +#include <mln/core/alias/neighb3d.hh> #include <mln/core/image/image2d.hh> #include <mln/core/image/image3d.hh> +#include <mln/core/routine/initialize.hh> +#include <mln/data/compute.hh> +#include <mln/data/fill.hh> +// #include <mln/data/stretch.hh> #include <mln/data/transform.hh> + +// #include <mln/display/display_histo.hh> + #include <mln/fun/v2v/rgb8_to_rgbn.hh> -#include <mln/io/ppm/load.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/io/plot/save_image_sh.hh> - -#include <mln/accu/stat/histo3d_rgb.hh> -#include <mln/data/compute.hh> +// #include <mln/io/plot/save_image_sh.hh> -#include <mln/arith/revert.hh> #include <mln/labeling/regional_maxima.hh> -#include <mln/core/alias/neighb3d.hh> -#include <mln/core/routine/initialize.hh> +#include <mln/labeling/mean_values.hh> +#include <mln/labeling/compute.hh> + #include <mln/literal/colors.hh> -#include <mln/morpho/watershed/flooding.hh> + +// #include <mln/morpho/watershed/flooding.hh> #include <mln/morpho/opening/volume.hh> #include <mln/morpho/elementary/dilation.hh> -#include <mln/data/stretch.hh> -#include <mln/display/display_histo.hh> -#include <mln/labeling/mean_values.hh> +#include <mln/opt/at.hh> + +// #include <mln/pw/value.hh> + +#include <mln/util/array.hh> +#include <mln/util/timer.hh> + +#include <mln/value/label_8.hh> +#include <mln/value/rgb8.hh> +#include <mln/value/rgb.hh> +#include <mln/value/int_u.hh> + + +template <unsigned n, unsigned ch> +struct t_channel : mln::Function_v2v< t_channel<n,ch> > +{ + typedef mln::value::rgb<n> t_rgbn; + typedef mln::value::int_u<n> t_int_un; + typedef t_rgbn argument; + typedef t_int_un result; + + result operator()(const argument& c) const + { + result tmp; + + switch(ch) + { + case 0: tmp = c.red(); break; + case 1: tmp = c.green(); break; + case 2: tmp = c.blue(); break; + } + + return tmp; + } +}; + + +// version optimisée de labeling + +template <unsigned n> +struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> > +{ + typedef mln::value::rgb<n> t_rgbn; + typedef mln::value::label_8 t_lbl8; + typedef t_rgbn argument; + typedef t_lbl8 result; + typedef mln::image3d<t_lbl8> t_label; + + const t_label& _label; + + t_labeling_rgbn(const t_label& label) : _label(label) {} + + result operator()(const argument& c) const + { + t_lbl8 tmp = mln::opt::at(_label, c.blue(), c.red(), c.green()); + + return tmp; + } +}; + +// version non optimisée de label + +template <unsigned n> mln::image2d<mln::value::label_8> -label_image(const mln::image2d<mln::value::rgb<5> >& input, - const mln::image3d<mln::value::label_8>& label) +label_image(const mln::image2d< mln::value::rgb<n> >& input, + const mln::image3d< mln::value::label_8>& label) { - mln::image2d<mln::value::label_8> output(input.nrows(), - input.ncols()); + mln::image2d<mln::value::label_8> output; + + initialize(output, input); - mln_piter_(mln::image2d<mln::value::label_8>) po(output.domain()); - mln_piter_(mln::image2d<mln::value::rgb<5> >) pi(input.domain()); + mln_piter(mln::image2d< mln::value::label_8 >) po(output.domain()); + mln_piter(mln::image2d< mln::value::rgb<n> >) pi(input.domain()); for_all_2(po, pi) { - output(po) = label(mln::point3d(input(pi).blue(), - input(pi).red(), - input(pi).green())); + const mln::value::rgb<n>& vi = input(pi); + + output(po) = mln::opt::at(label, vi.blue(), vi.red(), vi.green()); } return output; } +template <unsigned n> +unsigned unquant(const float& value) +{ + unsigned size = pow(2,(8-n)); + unsigned result = value * size; + + return result; +} + +template <unsigned n> +void print_count2(const mln::image2d<mln::value::rgb<n> >& input_rgbn, + const mln::image3d<unsigned>& histo, + const mln::image3d<mln::value::label_8>& label, + const unsigned n_labels) +{ + typedef mln::value::label_8 t_lbl8; + typedef mln::value::rgb<n> t_rgbn; + typedef mln::value::int_u<n> t_int_un; + typedef mln::algebra::vec<3,float> t_vec3f; + typedef mln::accu::math::sum<unsigned,unsigned> t_sum; + typedef mln::accu::stat::mean<t_vec3f,t_vec3f,t_vec3f> t_mean; + typedef mln::accu::math::sum<t_vec3f,t_vec3f> t_diff; + typedef mln::accu::stat::variance<float,float,float> t_var; + typedef mln::image2d<t_lbl8> t_image2d_lbl8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; + typedef mln::image2d<t_int_un> t_image2d_int_un; + + mln::util::array<t_mean> mean((unsigned)(n_labels)+1); +// mln::util::array<t_diff> diff((unsigned)(n_labels)+1); + mln::util::array<t_var> var_red((unsigned)(n_labels)+1); + mln::util::array<t_var> var_green((unsigned)(n_labels)+1); + mln::util::array<t_var> var_blue((unsigned)(n_labels)+1); + mln::util::array<t_sum> count((unsigned)(n_labels)+1); + mln::util::array<float> abs((unsigned)(n_labels)+1); + mln::util::array<float> rel((unsigned)(n_labels)+1); + unsigned nb = 0; + + for (unsigned i = 0; i <= n_labels; ++i) + { + count(i).init(); + mean(i).init(); +// diff(i).init(); + var_red(i).init(); + var_green(i).init(); + var_blue(i).init(); + abs[i] = 0.0; + rel[i] = 0.0; + } + + mln::labeling::compute(count, histo, label, n_labels); + + for (unsigned i = 0; i <= n_labels; ++i) + { + unsigned c = count[i]; + nb += c; + } + + for (unsigned i = 0; i <= n_labels; ++i) + if (0 < count[i]) + { + abs[i] = ((float)count[i] / nb)*100.0; + rel[i] = ((float)count[i] / (nb - count[0]))*100.0; + } + + t_image2d_lbl8 label_img = mln::data::transform(input_rgbn, + t_labeling_rgbn<n>(label)); + + mln::labeling::compute(mean, input_rgbn, label_img, n_labels); + + +// t_image2d_rgbn mean_rgbn = mln::labeling::mean_values(input_rgbn, +// label_img, +// n_labels); +// t_image2d_int_un mean_red =mln::data::transform(mean_rgbn,t_channel<n>()); +// t_image2d_int_un mean_green=mln::data::transform(mean_rgbn,t_channel<n>()); +// t_image2d_int_un mean_blue =mln::data::transform(mean_rgbn,t_channel<n>()); + + t_image2d_int_un input_red =mln::data::transform(input_rgbn, + t_channel<n,0>()); + t_image2d_int_un input_green=mln::data::transform(input_rgbn, + t_channel<n,1>()); + t_image2d_int_un input_blue =mln::data::transform(input_rgbn, + t_channel<n,2>()); + +// FIXME VARIANCE NEGATIVE DANS LES RESULTATS !! + +// mln::labeling::compute(var_red, input_rgbn, label_img, n_labels); +// mln::labeling::compute(var_green, input_rgbn, label_img, n_labels); +// mln::labeling::compute(var_blue, input_rgbn, label_img, n_labels); + +// t_image2d_rgbn diff_rgbn = mln::arith::diff_abs(input_rgbn, mean_rgbn); + + std::cout << mln::labeling::compute(var_red, input_red, label_img, n_labels)(29) << std::endl; +// mln::labeling::compute(t_var(), input_red, label_img, n_labels); + mln::labeling::compute(var_green, input_green, label_img, n_labels); + mln::labeling::compute(var_blue, input_blue, label_img, n_labels); + + for (unsigned i = 0; i <= n_labels; ++i) + { + if (5.0 < abs[i] && 10.0 < rel[i]) + { + const t_vec3f& mean_v = mean[i]; +// const t_vec3f& diff_v = diff[i]; + + std::cout << i << " :[" << unquant<n>(mean_v[0]) +// << "(" << diff_v[0] + << "(" << var_red[i] + << ")," << unquant<n>(mean_v[1]) +// << "(" << diff_v[1] + << "(" << var_green[i] + << ")," << unquant<n>(mean_v[2]) +// << "(" << diff_v[2] + << "(" << var_blue[i] + << ")]- " << count[i] + << " - " << abs[i] + << " - " << rel[i] + << std::endl; + } + } +} void print_count(const mln::image3d<unsigned>& histo, const mln::image3d<mln::value::label_8>& label, @@ -70,66 +261,116 @@ void print_count(const mln::image3d<unsigned>& histo, unsigned red[255]; unsigned green[255]; unsigned blue[255]; + unsigned nb = 0; + unsigned tmp = 0; - for (unsigned i = 0; i < n_labels; ++i) + for (unsigned i = 0; i <= n_labels; ++i) { count[i] = 0; - red[i] = 0.0; - green[i] = 0.0; - blue[i] = 0.0; + red[i] = 0; + green[i] = 0; + blue[i] = 0; } - mln_piter_(mln::image3d<unsigned>) ph(histo.domain()); - mln_piter_(mln::image3d<mln::value::label_8>) pl(label.domain()); + mln_piter_(mln::image3d<unsigned>) p(histo.domain()); - for_all_2(ph, pl) + for_all(p) { - count[label(pl)] += histo(ph); - red[label(pl)] += histo(ph) * pl.row(); - green[label(pl)] += histo(ph) * pl.col(); - blue[label(pl)] += histo(ph) * pl.sli(); + count[label(p)] += histo(p); + red[label(p)] += histo(p) * p.row(); + green[label(p)] += histo(p) * p.col(); + blue[label(p)] += histo(p) * p.sli(); + nb += histo(p); + ++tmp; } std::cout << std::endl; - for (unsigned i = 0; i < n_labels; ++i) - { - red[i] = red[i] / count[i]; - green[i] = green[i] / count[i]; - blue[i] = blue[i] / count[i]; + std::cout << "nb : " << nb << std::endl; + std::cout << "tmp : " << tmp << std::endl; - std::cout << "count[" << i << "](" - << red[i] << ", " << green[i] << ", " - << blue[i] << ") = " << count[i] << std::endl; - } + std::cout << std::endl; + + for (unsigned i = 0; i <= n_labels; ++i) + if (0 < count[i]) + { + float percentage_abs = ((float)count[i] / nb)*100.0; + float percentage_rel = ((float)count[i] / (nb - count[0]))*100.0; + + red[i] = red[i] / count[i]; + green[i] = green[i] / count[i]; + blue[i] = blue[i] / count[i]; + + std::cout << "count[" << i << "](" + << red[i] << ", " << green[i] << ", " + << blue[i] << ") = " << count[i] << "(" + << percentage_abs << "%)"; + + if (0 < i) + std::cout << "[" << percentage_rel << "%]"; + + std::cout << std::endl; + } std::cout << std::endl; } -mln::image2d<mln::value::rgb<5> > -merge(const mln::image2d<mln::value::rgb<5> >& input, - const mln::image3d<mln::value::label_8>& label) +// Version optimisée de merge + +template <unsigned n> +struct t_merge_lbl8_with_rgbn : mln::Function_v2v< t_merge_lbl8_with_rgbn<n> > { - mln::image2d<mln::value::rgb<5> > output; + typedef mln::value::rgb<n> t_rgbn; + typedef mln::value::label_8 t_lbl8; + typedef t_rgbn argument; + typedef t_rgbn result; + typedef mln::image3d<t_lbl8> t_label; + + const t_label& _label; + + t_merge_lbl8_with_rgbn(const t_label& label) : _label(label) {} + + result operator()(const argument& c) const + { + t_rgbn tmp = c; + + if (0 == mln::opt::at(_label, c.blue(), c.red(), c.green())) + { + tmp = mln::literal::black; + } + + return tmp; + } +}; + +// version non optimisée de merge + +template <unsigned n> +mln::image2d< mln::value::rgb<n> > +merge(const mln::image2d< mln::value::rgb<n> >& input, + const mln::image3d< mln::value::label_8 >& label) +{ + mln::image2d<mln::value::rgb<n> > output; mln::initialize(output, input); + // mln::data::fill(output, mln::literal::green); - mln_piter_(mln::image2d<mln::value::rgb<5> >) pi(input.domain()); - mln_piter_(mln::image2d<mln::value::rgb<5> >) po(output.domain()); + mln_piter(mln::image2d< mln::value::rgb<n> >) pi(input.domain()); + mln_piter(mln::image2d< mln::value::rgb<n> >) po(output.domain()); for_all_2(pi, po) { - if (0 < label(mln::point3d(input(pi).blue(), - input(pi).red(), - input(pi).green()))) + const mln::value::rgb<n>& vi = input(pi); + mln::value::rgb<n>& vo = output(po); + + if (0 < mln::opt::at(label,vi.blue(),vi.red(),vi.green())) { - output(po).red() = input(pi).red(); - output(po).green() = input(pi).green(); - output(po).blue() = input(pi).blue(); + vo.red() = vi.red(); + vo.green() = vi.green(); + vo.blue() = vi.blue(); } else - output(po) = mln::literal::red; - //output(po) = mln::literal::black; + vo = mln::literal::black; } return output; @@ -137,78 +378,180 @@ merge(const mln::image2d<mln::value::rgb<5> >& input, // -// Regional maxima image processing chain. -// RGB8 +// Theo regional maxima image processing chain. // -void do_demo(const std::string& image) + +// FIXME C'est la dilatation qui fait apparaître des classes < min_volume. +// Une couleur se dilate au détriment du fond et des autres couleurs. + +int main2() { + const unsigned min_volume = 1000; + //const std::string& image = OLENA_IMG_PATH"/fly.ppm"; + const std::string& image = SCRIBO_PPM_IMG_PATH"/mp00082c_50p.ppm"; + //const std::string& image = OLENA_IMG_PATH"/tiny.ppm"; + typedef mln::value::label_8 t_lbl8; - typedef mln::value::int_u8 t_int_u8; typedef mln::value::rgb8 t_rgb8; typedef mln::value::rgb<5> t_rgb5; - typedef mln::image3d<t_lbl8> t_image3d_lbl8; - typedef mln::image2d<t_lbl8> t_image2d_lbl8; typedef mln::image2d<t_rgb8> t_image2d_rgb8; typedef mln::image2d<t_rgb5> t_image2d_rgb5; - typedef mln::image2d<t_int_u8> t_image2d_int_u8; - typedef mln::image3d<unsigned> t_histo3d; - typedef mln::image2d<unsigned> t_histo2d; - typedef mln::fun::v2v::rgb8_to_rgbn<5> t_rgb8_to_rgbn; + typedef mln::image3d<t_lbl8> t_image3d_lbl8; + typedef mln::image3d<unsigned> t_image3d_unsigned; + typedef mln::fun::v2v::rgb8_to_rgbn<5> t_rgb8_to_rgb5; typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; + typedef mln::accu::math::sum<unsigned,unsigned> t_sum; + + mln::util::timer timer; + + // START IMAGE PROCESSING CHAIN + timer.start(); t_image2d_rgb8 input_rgb8; t_image2d_rgb5 input_rgb5; - t_image2d_rgb5 output_rgb5; - t_image2d_rgb5 mean_rgb5; - t_histo3d histo; - t_image2d_int_u8 projected; - t_image2d_int_u8 filtered; - t_histo3d opened; + t_image3d_unsigned histo; + t_image3d_unsigned opened; t_image3d_lbl8 label; - t_image2d_lbl8 label_img; t_image3d_lbl8 dilated; t_lbl8 n_labels; - t_rgb5 value_rgb5; - // IMAGE LOADING PHASE - std::cout << "Image loading phase ..." << std::endl; mln::io::ppm::load(input_rgb8, image.c_str()); - input_rgb5 = mln::data::transform(input_rgb8, t_rgb8_to_rgbn()); - mln::io::ppm::save(input_rgb5, "input_rgb5.ppm"); + input_rgb5 = mln::data::transform(input_rgb8, t_rgb8_to_rgb5()); + histo = mln::data::compute(t_histo3d_fun(), input_rgb5); + opened = mln::morpho::opening::volume(histo, mln::c6(), min_volume); + label = mln::labeling::regional_maxima(opened, mln::c6(), n_labels); + dilated = mln::morpho::elementary::dilation(label, mln::c26()); + + mln::util::array<t_sum> length((unsigned)(n_labels)+1); + + for (unsigned i = 0; i <= n_labels; ++i) + length(i).init(); + mln::labeling::compute(length, histo, dilated, n_labels); - // HISTO COMPUTING PHASE - std::cout << "Histo computing phase ..." << std::endl; - histo = mln::data::compute(t_histo3d_fun(), input_rgb5); - projected = mln::display::display_histo3d_unsigned(histo); + timer.stop(); + // STOP IMAGE PROCESSING CHAIN + + std::cout << "Done in " << timer.read() << " ms" << std::endl; + std::cout << "n_labels : " << n_labels << std::endl; + + for (unsigned i = 0; i <= n_labels; ++i) + { + std::cout << "count[" << i << "] = " << length[i] << std::endl; + } + + print_count(histo,label,n_labels); - mln::io::pgm::save(projected, "histo.pgm"); //mln::io::plot::save_image_sh(histo, "histo.sh"); + //mln::io::plot::save_image_sh(histo, "opened.sh"); + //mln::io::plot::save_image_sh(label, "label.sh"); - // HISTO FILTERING PHASE - std::cout << "Histo filtering phase ..." << std::endl;; - opened = mln::morpho::opening::volume(histo, mln::c6(), 1000); - mln::io::plot::save_image_sh(opened, "opened.sh"); - filtered = mln::display::display_histo3d_unsigned(opened); - mln::io::pgm::save(filtered, "filtered.pgm"); + return 0; +} +// n < 8, n is the degree of quantification +template <unsigned n> +void demo() +{ + const unsigned min_volume = 1000; + //const std::string& image = OLENA_IMG_PATH"/fly.ppm"; + const std::string& image = SCRIBO_PPM_IMG_PATH"/mp00082c_50p.ppm"; + //const std::string& image = OLENA_IMG_PATH"/tiny.ppm"; - // HISTO LABELING PHASE - std::cout << "Histo labeling phase ..." << std::endl; - label = mln::labeling::regional_maxima(opened, mln::c6(), n_labels); - mln::io::plot::save_image_sh(label, "label.sh"); + typedef mln::value::label_8 t_lbl8; + typedef mln::value::int_u8 t_int_u8; + typedef mln::value::rgb8 t_rgb8; + typedef mln::value::rgb<n> t_rgbn; + typedef mln::image3d<t_lbl8> t_image3d_lbl8; + typedef mln::image2d<t_lbl8> t_image2d_lbl8; + typedef mln::image2d<t_rgb8> t_image2d_rgb8; + typedef mln::image2d<t_rgbn> t_image2d_rgbn; + typedef mln::image2d<t_int_u8> t_image2d_int_u8; + typedef mln::image3d<unsigned> t_histo3d; + typedef mln::image2d<unsigned> t_histo2d; + typedef mln::fun::v2v::rgb8_to_rgbn<n> t_rgb8_to_rgbn; + typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun; + mln::util::timer timer; - // HISTO DILATING PHASE - std::cout << "Histo dilating phase ..." << std::endl; - dilated = mln::morpho::elementary::dilation(label, mln::c18()); - mln::io::plot::save_image_sh(dilated, "dilated.sh"); + // START OF IMAGE PROCESSING CHAIN + timer.start(); - // PRINTING PHASE - std::cout << "Labels : " << n_labels << std::endl; - print_count(histo, dilated, n_labels); + t_image2d_rgb8 input_rgb8; + t_image2d_rgbn input_rgbn; + t_image2d_rgbn output_rgbn; + // t_image2d_rgbn mean_rgb5; + t_histo3d histo; + // t_image2d_int_u8 projected; + // t_image2d_int_u8 filtered; + t_histo3d opened; + t_image3d_lbl8 label; + t_image2d_lbl8 label_img; + t_image3d_lbl8 dilated; + t_lbl8 n_labels; + // t_rgbn value_rgbn; + mln::io::ppm::load(input_rgb8, image.c_str()); + input_rgbn = mln::data::transform(input_rgb8, t_rgb8_to_rgbn()); + histo = mln::data::compute(t_histo3d_fun(), input_rgbn); + opened = mln::morpho::opening::volume(histo, mln::c6(), min_volume); + label = mln::labeling::regional_maxima(opened, mln::c6(), n_labels); + dilated = mln::morpho::elementary::dilation(label, mln::c26()); + + timer.stop(); + // END OF IMAGE PROCESSING CHAIN + + std::ostringstream name; + std::ostringstream name2; + std::ostringstream name3; + + name << "input_rgb" << n << ".ppm"; + name2 << "output_rgb" << n << ".ppm"; + name3 << "label_img" << n << ".pgm"; + + std::cout << "Done in : " << timer.read() << " s" << std::endl; + std::cout << "Labels : " << n_labels << std::endl; + std::cout << "Name : " << name.str() << std::endl; + + mln::io::ppm::save(input_rgbn, name.str()); + + mln::util::timer timer2; + + timer2.start(); + print_count2(input_rgbn, histo, dilated, n_labels); + timer2.stop(); + std::cout << "timer2 : " << timer2.read() << std::endl; + output_rgbn = mln::data::transform(input_rgbn, + t_merge_lbl8_with_rgbn<n>(label)); + // output_rgbn = merge<n>(input_rgbn, dilated); + mln::io::ppm::save(output_rgbn, name2.str()); + + label_img = mln::data::transform(input_rgbn, + t_labeling_rgbn<n>(label)); + // label_img = label_image<n>(input_rgbn, dilated); + mln::io::pgm::save(label_img, name3.str()); + + + // localiser les couleurs sur l'image (fond en black, le reste) + + // La dilatation englobe beaucoup plus de couleur, mais celles-ci ne + // sont pas forcément présentes dans l'image. Du coup, les classes ne + // bougent pas démeusurément. + +// mln::io::ppm::save(input_rgb5, "input_rgb5.ppm"); +// mln::io::plot::save_image_sh(input_rgb8, "input_rgb8.sh"); +// mln::io::plot::save_image_sh(input_rgb5, "input_rgb5.sh"); +// projected = mln::display::display_histo3d_unsigned(histo); +// mln::io::pgm::save(projected, "histo.pgm"); +// mln::io::plot::save_image_sh(histo, "histo.sh"); +// mln::io::plot::save_image_sh(opened, "opened.sh"); +// filtered = mln::display::display_histo3d_unsigned(opened); +// mln::io::pgm::save(filtered, "filtered.pgm"); +// mln::io::plot::save_image_sh(label, "label.sh"); + // mln::io::plot::save_image_sh(dilated, "dilated.sh"); + + /* // OUTPUT PHASE std::cout << "Output phase ..." << std::endl; output_rgb5 = merge(input_rgb5, dilated); @@ -221,113 +564,21 @@ void do_demo(const std::string& image) label_img = label_image(input_rgb5, dilated); mln::io::pgm::save(label_img, "label_img.pgm"); - // BUILDING MEAN VALUES std::cout << "Building mean values phase ..." << std::endl; mean_rgb5 = mln::labeling::mean_values(input_rgb5, label_img, n_labels); mln::io::ppm::save(mean_rgb5, "mean.ppm"); + */ } -void demo(const std::string& image = SCRIBO_PPM_IMG_PATH"/mp00082c_50p.ppm", - //const std::string& image = OLENA_IMG_PATH"/house.ppm", - const unsigned k_center = 2, - //const unsigned k_center = 3, - const unsigned n_times = 10, - const unsigned watch_dog = 10) -{ - std::cout << "----------------------------------------" << std::endl; - std::cout << "Launching the demo with these parameters" << std::endl; - std::cout << "image : " << image << std::endl; - std::cout << "k_center : " << k_center << std::endl; - std::cout << "n_times : " << n_times << std::endl; - std::cout << "watch_dog : " << watch_dog << std::endl; - std::cout << "----------------------------------------" << std::endl; - - do_demo(image); -} - -void usage(const int argc, const char *args[]) -{ - std::cout << "----------------------------------------" << std::endl; - std::cout << "argc : " << argc << std::endl; - - for (int i = 0; i < argc; ++i) - std::cout << "args[" << i << "] : " << args[i] << std::endl; - - std::cout << "----------------------------------------" << std::endl; - std::cout << "usage: kmean2d [image [k_center [n_times [watch_dog]]]]" - << std::endl; - std::cout << "pbm image (points to work with)" << std::endl; - std::cout << "unsigned k_center (number of centers)" << std::endl; - std::cout << "unsigned n_times (number of launching)" << std::endl; - std::cout << "unsigned watch_dog (convergence loop)" << std::endl; - std::cout << "----------------------------------------" << std::endl; -} - -bool char_to_unsigned(const bool status, const char *arg, unsigned& val) -{ - bool result = false; - - if (status) - { - std::istringstream arg_stream(arg); - - arg_stream >> val; - - result = !arg_stream.fail(); - } - - return result; -} - -bool char_to_string(const bool status, const char *arg, std::string& val) -{ - bool result = false; - - if (status) - { - std::istringstream arg_stream(arg); - - arg_stream >> val; - - return !arg_stream.fail(); - } - - return result; -} - -int main(const int argc, const char *args[]) +int main() { - std::string image("top"); - unsigned k_center; - unsigned watch_dog; - unsigned n_times; - bool status = true; - - switch (argc) - { - case 5: status = char_to_unsigned(status, args[4], watch_dog); - case 4: status = char_to_unsigned(status, args[3], n_times); - case 3: status = char_to_unsigned(status, args[2], k_center); - case 2: status = char_to_string(status, args[1], image); break; - case 1: status = true; break; - default: status = false; - } - - if (status) - { - switch (argc) - { - case 1: demo(); break; - case 2: demo(image); break; - case 3: demo(image, k_center); break; - case 4: demo(image, k_center, n_times); break; - case 5: demo(image, k_center, n_times, watch_dog); break; - } - } - else - usage(argc, args); - - return 0; + demo<2>(); // 2.26 s + demo<3>(); // 2.29 s + demo<4>(); // 2.29 s + demo<5>(); // 2.37 s + demo<6>(); // 3.19 s + demo<7>(); // 11.43 s + demo<8>(); // 96.19 s } -- 1.5.6.5