• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

kmean_rgb.hh

00001 // Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_CLUSTERING_KMEAN_RGB_HH
00027 # define MLN_CLUSTERING_KMEAN_RGB_HH
00028 
00093 
00094 # include <limits.h>
00095 # include <iostream>
00096 
00097 # include <mln/accu/stat/histo3d_rgb.hh>
00098 
00099 # include <mln/algebra/vec.hh>
00100 
00101 # include <mln/core/concept/image.hh>
00102 # include <mln/core/contract.hh>
00103 # include <mln/core/image/image2d.hh>
00104 # include <mln/core/macros.hh>
00105 
00106 # include <mln/data/compute.hh>
00107 # include <mln/data/fill.hh>
00108 # include <mln/data/transform.hh>
00109 
00110 # include <mln/debug/println.hh>
00111 
00112 # include <mln/io/ppm/save.hh>
00113 # include <mln/io/pgm/save.hh>
00114 
00115 # include <mln/labeling/colorize.hh>
00116 # include <mln/labeling/mean_values.hh>
00117 
00118 # include <mln/literal/zero.hh>
00119 # include <mln/literal/one.hh>
00120 
00121 # include <mln/math/min.hh>
00122 # include <mln/math/sqr.hh>
00123 
00124 # include <mln/norm/l2.hh>
00125 
00126 # include <mln/opt/at.hh>
00127 
00128 # include <mln/trace/entering.hh>
00129 # include <mln/trace/exiting.hh>
00130 
00131 # include <mln/trait/value_.hh>
00132 
00133 # include <mln/util/array.hh>
00134 
00135 # include <mln/value/int_u.hh>
00136 # include <mln/value/rgb8.hh>
00137 # include <mln/value/label_8.hh>
00138 
00139 
00140 //--------------------------------------------------------------------------
00141 // FUNCTIONAL CODE
00142 //--------------------------------------------------------------------------
00143 
00144 
00145 namespace mln
00146 {
00147 
00148   namespace clustering
00149   {
00168     template <typename T, unsigned n, typename I>
00169     inline
00170     mln_ch_value(I,value::label_8)
00171     kmean_rgb(const Image<I>& point,
00172               const unsigned  k_center,
00173               const unsigned  watch_dog,
00174               const unsigned  n_times);
00175 
00176   } // end of namespace mln::clustering
00177 
00178   namespace clustering
00179   {
00180 
00181 
00182 # ifndef MLN_INCLUDE_ONLY
00183 
00184     //--------------------------------------------------------------------------
00185     // Internal.
00186     //--------------------------------------------------------------------------
00187 
00188     namespace internal
00189     {
00190 
00191       //------------------------------------------------------------------------
00192       // Debugging tools
00193       //------------------------------------------------------------------------
00194 
00195       /*
00196     template <typename T, unsigned n>
00197     inline
00198     void kmean3d_a<T,n>::build_label_dbg()
00199     {
00200       trace::entering("mln::clustering::kmean3d_a::build_label_dbg");
00201 
00202       mln_piter(t_point_img) pi(_point.domain());
00203       mln_piter(t_label_dbg) po(_label_dbg.domain());
00204 
00205       for_all_2(pi, po)
00206       {
00207           t_value    val = _point(pi);
00208           t_label    grp = _group(point3d(val.blue(), val.red(), val.green()));
00209 
00210           // As label zero has got a particular semantic, the first label is one
00211           _label_dbg(po) = ++grp;
00212       }
00213 
00214       trace::exiting("mln::clustering::kmean3d_a::build_label_dbg");
00215     }
00216 
00217     template <typename T, unsigned n>
00218     inline
00219     void kmean3d_a<T,n>::build_mean_dbg()
00220     {
00221       trace::entering("mln::clustering::kmean3d_a::build_mean_dbg");
00222 
00223       mln_piter(t_mean_dbg)  p(_mean_dbg.domain());
00224 
00225       for_all(p)
00226       {
00227         _mean_dbg(p).red()   = static_cast<unsigned>(_mean[_label_dbg(p)][0]);
00228         _mean_dbg(p).green() = static_cast<unsigned>(_mean[_label_dbg(p)][1]);
00229         _mean_dbg(p).blue()  = static_cast<unsigned>(_mean[_label_dbg(p)][2]);
00230       }
00231 
00232       trace::exiting("mln::clustering::kmean3d_a::build_mean_dbg");
00233     }
00234 
00235 
00236     template <typename T, unsigned n>
00237     inline
00238     void kmean3d_a<T,n>::build_all_dbg()
00239     {
00240       trace::entering("mln::clustering::kmean3d_a::build_all_dbg");
00241       build_label_dbg();
00242       //build_mean_dbg();
00243       _mean_dbg  = labeling::mean_values(_point, _label_dbg, _k_center);
00244       _color_dbg = labeling::colorize(value::rgb8(), _label_dbg);
00245 
00246       trace::exiting("mln::clustering::kmean3d_a::build_all_dbg");
00247     }
00248 
00249     template <typename T, unsigned n>
00250     inline
00251     void kmean3d_a<T,n>::update_cnv()
00252     {
00253       trace::entering("mln::clustering::kmean3d_a::update_cnv");
00254 
00255       _variance_cnv[_current_launching](point1d(_current_step))
00256         = _within_variance;
00257 
00258       mln_eiter(t_mean_img) l(_mean);
00259 
00260       for_all(l)
00261       {
00262         _mean_cnv[l.index_()][_current_launching](point1d(_current_step))
00263           = _mean[l.index_()];
00264       }
00265 
00266       trace::exiting("mln::clustering::kmean3d_a::update_cnv");
00267     }
00268 
00269     template <typename T, unsigned n>
00270     inline
00271     void kmean3d_a<T,n>::finalize_cnv()
00272     {
00273       trace::entering("mln::clustering::kmean3d_a::finalize_cnv");
00274 
00275       // saturate the curv with the within variance
00276       for (unsigned i = _current_step; i < _watch_dog; ++i)
00277         _variance_cnv[_current_launching](point1d(i)) = _within_variance;
00278 
00279       for (unsigned i = _current_step; i < _watch_dog; ++i)
00280       {
00281         mln_eiter(t_mean_img) l(_mean);
00282 
00283         for_all(l)
00284         {
00285           _mean_cnv[l.index_()][_current_launching](point1d(i))
00286             = _mean[l.index_()];
00287         }
00288       }
00289 
00290       trace::exiting("mln::clustering::kmean3d_a::finalize_cnv");
00291     }
00292 
00293 
00294 
00295 
00296     //--------------------------------------------------------------------------
00297     // Printing temporary results
00298     //--------------------------------------------------------------------------
00299 
00300     template <typename T, unsigned n>
00301     inline
00302     void kmean3d_a<T,n>::print_mean()
00303     {
00304       trace::entering("mln::clustering::kmean3d_a::print_mean");
00305 
00306       mln_eiter(t_mean_img)  l(_mean);
00307 
00308       for_all(l)
00309       {
00310         std::cout << "mean("      << l.index_();
00311         std::cout << ") = [r="    << _mean[l.index_()][0];
00312         std::cout << ", g="       << _mean[l.index_()][1];
00313         std::cout << ", b="       << _mean[l.index_()][2];
00314         std::cout << "]"          << std::endl;
00315       }
00316 
00317       trace::exiting("mln::clustering::kmean3d_a::print_mean");
00318     }
00319 
00320     template <typename T, unsigned n>
00321     inline
00322     void kmean3d_a<T,n>::print_number()
00323     {
00324       trace::entering("mln::clustering::kmean3d_a::print_number");
00325 
00326       mln_eiter(t_number_img)  l(_number);
00327 
00328       for_all(l)
00329       {
00330         std::cout << "number(" << l.index_();
00331         std::cout << ") = "    << _number[l.index_()];
00332         std::cout << std::endl;
00333       }
00334 
00335       trace::exiting("mln::clustering::kmean3d_a::print_number");
00336     }
00337 
00338     template <typename T, unsigned n>
00339     inline
00340     void kmean3d_a<T,n>::print_variance()
00341     {
00342       trace::entering("mln::clustering::kmean3d_a::print_variance");
00343 
00344       mln_eiter(t_variance_img)  l(_number);
00345 
00346       for_all(l)
00347       {
00348         std::cout << "variance(" << l.index_();
00349         std::cout << ") = "      << _variance[l.index_()];
00350         std::cout << std::endl;
00351       }
00352 
00353       trace::exiting("mln::clustering::kmean3d_a::print_variance");
00354     }
00355 
00356     template <typename T, unsigned n>
00357     inline
00358     void kmean3d_a<T,n>::print_histo()
00359     {
00360       trace::entering("mln::clustering::kmean3d_a::print_histo");
00361 
00362       mln_piter(t_histo_img)  rgb(_histo.domain());
00363 
00364       for_all(rgb)
00365       {
00366         if (0 < _histo(rgb))
00367         {
00368           std::cout << "histo(r="  << rgb.row();
00369           std::cout << ", g="      << rgb.col();
00370           std::cout << ", b="      << rgb.sli();
00371           std::cout << ")= "       << _histo(rgb);
00372           std::cout << std::endl;
00373         }
00374       }
00375 
00376       trace::exiting("mln::clustering::kmean3d_a::print_histo");
00377     }
00378 
00379     template <typename T, unsigned n>
00380     inline
00381     void kmean3d_a<T,n>::print_group()
00382     {
00383       trace::entering("mln::clustering::kmean3d_a::print_group");
00384 
00385       mln_piter(t_group_img)  rgb(_group.domain());
00386 
00387       for_all(rgb)
00388       {
00389         if (0 < _histo(rgb))
00390         {
00391           std::cout << "group(r="  << rgb.row();
00392           std::cout << ", g="      << rgb.col();
00393           std::cout << ", b="      << rgb.sli();
00394           std::cout << ")= "       << _group(rgb);
00395           std::cout << std::endl;
00396         }
00397       }
00398 
00399       trace::exiting("mln::clustering::kmean3d_a::print_group");
00400     }
00401 
00402     template <typename T, unsigned n>
00403     inline
00404     void kmean3d_a<T,n>::print_distance()
00405     {
00406       trace::entering("mln::clustering::kmean3d_a::print_distance");
00407 
00408       mln_eiter(t_distance_img)  l(_distance);
00409 
00410       for_all(l)
00411       {
00412         mln_piter(t_distance_val)  rgb(_distance[l.index_()].domain());
00413 
00414         for_all(rgb)
00415         {
00416           if (0 < _histo(rgb))
00417           {
00418             std::cout << "distance(l="  << l.index_();
00419             std::cout << ",r="          << rgb.row();
00420             std::cout << ", g="         << rgb.col();
00421             std::cout << ", b="         << rgb.sli();
00422             std::cout << ")= "          << _distance[l.index_()](rgb);
00423             std::cout << std::endl;
00424           }
00425         }
00426       }
00427 
00428       trace::exiting("mln::clustering::kmean3d_a::print_distance");
00429     }
00430 
00431     template <typename T, unsigned n>
00432     inline
00433     void kmean3d_a<T,n>::print_point()
00434     {
00435       trace::entering("mln::clustering::kmean3d_a::print_point");
00436 
00437       mln_piter(t_point_img)  p(_point.domain());
00438 
00439       for_all(p)
00440       {
00441         std::cout << "point(r="  << p.row();
00442         std::cout << ", c="      << p.col();
00443         std::cout << ")= "       << _point(p);
00444         std::cout << std::endl;
00445       }
00446 
00447       trace::exiting("mln::clustering::kmean3d_a::print_point");
00448     }
00449 
00450 
00451 
00452       template <typename T, unsigned n>
00453       inline
00454       void rgb_rand_init(t_mean_img mean)
00455       {
00456         typedef value::rgb<n>                      t_value;
00457         typedef mln_trait_value_comp(t_value,0)    t_value_comp0;
00458         typedef mln_trait_value_comp(t_value,1)    t_value_comp1;
00459         typedef mln_trait_value_comp(t_value,2)    t_value_comp2;
00460         typedef algebra::vec<3,T>                  t_result3d;
00461         typedef util::array<t_result3d>            t_mean_img;
00462 
00463         t_value_comp0         min_comp0 = mln_min(t_value_comp0);
00464         t_value_comp0         max_comp0 = mln_max(t_value_comp0);
00465         t_value_comp1         min_comp1 = mln_min(t_value_comp1);
00466         t_value_comp1         max_comp1 = mln_max(t_value_comp1);
00467         t_value_comp2         min_comp2 = mln_min(t_value_comp2);
00468         t_value_comp2         max_comp2 = mln_max(t_value_comp2);
00469         mln_eiter(t_mean_img) l(mean);
00470 
00471         for_all(l)
00472         {
00473           mean[l.index_()][0] = (rand() % (max_comp0 - min_comp0)) + min_comp0;
00474           mean[l.index_()][1] = (rand() % (max_comp1 - min_comp1)) + min_comp1;
00475           mean[l.index_()][2] = (rand() % (max_comp2 - min_comp2)) + min_comp2;
00476         }
00477 
00478         return mean;
00479       }
00480 
00481       */
00482 
00483     } // end of namespace mln::clustering::internal
00484 
00485 
00486     //--------------------------------------------------------------------------
00487     // Impl.
00488     //--------------------------------------------------------------------------
00489 
00490     namespace impl
00491     {
00492 
00493       //------------------------------------------------------------------------
00494       // kmean_image2d_rgb(const t_point_img& point,
00495       //                   const unsigned     k_center,
00496       //                   const unsigned     watch_dog = 10,
00497       //                   const unsigned     n_times   = 10)
00498       //------------------------------------------------------------------------
00499 
00500       template <unsigned n>
00501       struct rgbn_to_lbl8 : Function_v2v< rgbn_to_lbl8<n> >
00502       {
00503         typedef value::rgb<n>    argument;
00504         typedef value::label_8   result;
00505         typedef value::label_8   t_label;
00506         typedef image3d<t_label> t_group_img;
00507 
00508         t_group_img _group;
00509 
00510         rgbn_to_lbl8(t_group_img group) : _group(group) {}
00511 
00512         result operator()(const argument& c) const
00513         {
00514           value::label_8 tmp = opt::at(_group, c.blue(), c.red(), c.green());
00515 
00516           // FIXME WHY DO WE NOT USE +1
00517           return ++tmp;
00518         }
00519       };
00520 
00521       template <typename T, unsigned n>
00522       struct rgb_to_dist : Function_v2v< rgb_to_dist<T,n> >
00523       {
00524         typedef value::rgb<n>       argument;
00525         typedef T                   result;
00526         typedef T                   t_result1d;
00527         typedef algebra::vec<3,T>   t_result3d;
00528         typedef image3d<unsigned>   t_histo_img;
00529 
00530         t_result3d  _mean;
00531         t_histo_img _histo;
00532 
00533         rgb_to_dist(t_result3d mean, t_histo_img histo) : _mean(mean),
00534                                                           _histo(histo) {}
00535 
00536         result operator()(const argument& c) const
00537         {
00538           t_result1d diff2_row = math::sqr(c.row() - _mean[0]);
00539           t_result1d diff2_col = math::sqr(c.col() - _mean[1]);
00540           t_result1d diff2_sli = math::sqr(c.sli() - _mean[2]);
00541           t_result1d tmp       = _histo(c)*(diff2_row + diff2_col + diff2_sli);
00542 
00543           return tmp;
00544         }
00545       };
00546 
00547       template <typename T, unsigned n, typename I>
00548       inline
00549       mln_ch_value(I,value::label_8)
00550       kmean_image2d_rgb(const Image<I>& point__,
00551                         const unsigned  k_center,
00552                         const unsigned  watch_dog = 10,
00553                         const unsigned  n_times   = 10)
00554       {
00555         trace::entering("mln::clustering::impl::kmean_image2d_rgb");
00556 
00557         const I& point = exact(point__);
00558         typedef mln_value(I) V;
00559         mlc_is(V, value::rgb<n>)::check();
00560         mlc_bool(mln_site_(I)::dim == 2u)::check();
00561         mln_precondition(point.is_valid());
00562 
00563         // BEGIN TYPEDEF
00564         typedef value::rgb<8>                      t_rgb;
00565         typedef value::label<8>                    t_label;
00566         typedef value::rgb<n>                      t_value;
00567         typedef mln_trait_value_comp(t_value,0)    t_value_comp0;
00568         typedef mln_trait_value_comp(t_value,1)    t_value_comp1;
00569         typedef mln_trait_value_comp(t_value,2)    t_value_comp2;
00570         typedef T                                  t_result1d;
00571         typedef algebra::vec<3,T>                  t_result3d;
00572 
00573         typedef I                                  t_point_img;
00574         typedef image3d<unsigned>                  t_histo_img;
00575         typedef util::array<t_result1d>            t_number_img;
00576         typedef util::array<t_result3d>            t_mean_img;
00577         typedef util::array<t_result1d>            t_variance_img;
00578 
00579         typedef image3d<t_label>                   t_group_img;
00580         typedef image3d<t_result1d>                t_distance_val;
00581         typedef util::array<t_distance_val>        t_distance_img;
00582 
00583         typedef mln_ch_value(I,t_label)            t_label_dbg;
00584         typedef image2d<t_rgb>                     t_color_dbg;
00585         typedef image2d<t_value>                   t_mean_dbg;
00586 
00587         typedef image1d<t_result3d>                t_mean_val;
00588         typedef util::array<t_mean_val>            t_mean_set;
00589         typedef util::array<t_mean_set>            t_mean_cnv;
00590         typedef image1d<t_result1d>                t_variance_val;
00591         typedef util::array<t_variance_val>        t_variance_cnv;
00592         // END TYPEDEF
00593 
00594         // BEGIN INITIALISATION
00595         mln_precondition(point.is_valid());
00596 
00597         static const unsigned _N_TRIES    = 3;
00598 
00599         typedef accu::meta::stat::histo3d_rgb t_histo3d_rgb;
00600 
00601         t_result1d     _within_variance;
00602 
00603         unsigned       _k_center          = k_center;
00604         unsigned       _watch_dog         = watch_dog;
00605         unsigned       _n_times           = n_times;
00606         t_point_img    _point             = point;
00607 
00608         // HISTOGRAM INIT
00609         t_histo_img    _histo             = data::compute(t_histo3d_rgb(),
00610                                                           _point);
00611 
00612         // CENTER STATS INIT
00613         t_number_img   _number;
00614         t_mean_img     _mean;
00615         t_variance_img _variance;
00616 
00617         for (unsigned i = 0; i < _k_center; ++i)
00618         {
00619           _number.append(literal::zero);
00620           _mean.append(literal::zero);
00621           _variance.append(literal::zero);
00622         }
00623 
00624 
00625         unsigned       _current_step      = 0;
00626         unsigned       _current_launching = 0;
00627         bool           _is_number_valid   = false;
00628 
00629         unsigned       _launching_min;
00630         t_result1d     _variance_min;
00631         t_mean_img     _mean_min;
00632 
00633 
00634 
00635         t_group_img    _group;
00636         t_distance_img _distance;
00637 
00638 
00639         t_label_dbg    _label_dbg;
00640         t_color_dbg    _color_dbg;
00641         t_mean_dbg     _mean_dbg;
00642 
00643 
00644         t_mean_cnv     _mean_cnv;
00645         t_variance_cnv _variance_cnv;
00646 
00647 
00648 
00649 
00650         _group.init_(box3d(point3d(mln_min(t_value_comp2),
00651                                    mln_min(t_value_comp0),
00652                                    mln_min(t_value_comp1)),
00653                            point3d(mln_max(t_value_comp2),
00654                                    mln_max(t_value_comp0),
00655                                    mln_max(t_value_comp1))));
00656 
00657         for (unsigned i = 0; i < _k_center; ++i)
00658         {
00659           t_distance_val img(box3d(point3d(mln_min(t_value_comp2),
00660                                            mln_min(t_value_comp0),
00661                                            mln_min(t_value_comp1)),
00662                                    point3d(mln_max(t_value_comp2),
00663                                            mln_max(t_value_comp0),
00664                                            mln_max(t_value_comp1))));
00665 
00666           _distance.append(img);
00667         }
00668 
00669         // Debugging, calibrating and testing
00670         initialize(_label_dbg, _point);
00671         initialize(_color_dbg, _point);
00672         initialize(_mean_dbg,  _point);
00673 
00674         // Observing the convergence
00675 
00676         for (unsigned i = 0; i < _n_times; ++i)
00677         {
00678           t_variance_val img(box1d(point1d(0), point1d(_watch_dog-1)));
00679 
00680           data::fill(img, literal::zero);
00681 
00682           _variance_cnv.append(img);
00683         }
00684 
00685         for (unsigned i = 0; i < _k_center; ++i)
00686         {
00687           t_mean_set mean_set;
00688 
00689           for (unsigned j = 0; j < _n_times; ++j)
00690           {
00691             t_mean_val img(box1d(point1d(0), point1d(_watch_dog-1)));
00692 
00693             data::fill(img, literal::zero);
00694 
00695             mean_set.append(img);
00696           }
00697 
00698           _mean_cnv.append(mean_set);
00699         }
00700         // END INITIALISATION
00701 
00702         // BEGIN LOOP N TIMES
00703         {
00704           unsigned tries     = 0;
00705           _variance_min      = mln_max(t_result1d);
00706           _current_launching = 0;
00707 
00708           while (_current_launching < _n_times)
00709           {
00710             // BEGIN LAUNCH ONE TIME
00711             trace::entering("Launch one time");
00712             {
00713               t_result1d old_variance = mln_max(t_result1d);
00714               _within_variance        = mln_max(t_result1d);
00715               _current_step           = 0;
00716 
00717               // BEGIN INIT_MEAN
00718               trace::entering("init mean");
00719               {
00720                 t_value_comp0           min_comp0 = mln_min(t_value_comp0);
00721                 t_value_comp0           max_comp0 = mln_max(t_value_comp0);
00722                 t_value_comp1           min_comp1 = mln_min(t_value_comp1);
00723                 t_value_comp1           max_comp1 = mln_max(t_value_comp1);
00724                 t_value_comp2           min_comp2 = mln_min(t_value_comp2);
00725                 t_value_comp2           max_comp2 = mln_max(t_value_comp2);
00726                 mln_eiter(t_mean_img)   l(_mean);
00727 
00728                 for_all(l)
00729                 {
00730                   _mean[l.index_()][0]=(rand()%(max_comp0-min_comp0))+min_comp0;
00731                   _mean[l.index_()][1]=(rand()%(max_comp1-min_comp1))+min_comp1;
00732                   _mean[l.index_()][2]=(rand()%(max_comp2-min_comp2))+min_comp2;
00733                 }
00734               }
00735               trace::exiting("init mean");
00736               // END INIT MEAN
00737 
00738 
00739               // UPDATE DISTANCE
00740               trace::entering("update distance");
00741 
00742               for (unsigned i = 0; i < _k_center; ++i)
00743               {
00744 
00745                 // _distance[i] = data::transform(_histo,
00746                 //                             rgb_to_dist<T,n>(_mean[i],
00747                 //                                              _histo));
00748 
00749                 mln_piter(t_distance_val) d(_distance[i].domain());
00750 
00751                 for_all(d)
00752                 {
00753                   t_result1d diff2_row = math::sqr(d.row() - _mean[i][0]);
00754                   t_result1d diff2_col = math::sqr(d.col() - _mean[i][1]);
00755                   t_result1d diff2_sli = math::sqr(d.sli() - _mean[i][2]);
00756                   _distance[i](d)      = _histo(d)*
00757                     (diff2_row + diff2_col + diff2_sli);
00758                 }
00759               }
00760 
00761               trace::exiting("update distance");
00762               // END UPDATE DISTANCE
00763 
00764               do
00765               {
00766                 old_variance = _within_variance;
00767 
00768                 // BEGIN UPDATE GROUP
00769                 trace::entering("update group");
00770                 {
00771                     mln_piter(t_group_img) rgb(_group.domain());
00772 
00773                     for_all(rgb)
00774                     {
00775                       mln_eiter(t_distance_img) l(_distance);
00776                       t_result1d                min   = mln_max(t_result1d);
00777                       t_label                   label = mln_max(t_label);
00778 
00779                       for_all(l)
00780                       {
00781                         if (min > _distance[l.index_()](rgb))
00782                         {
00783                           min   = _distance[l.index_()](rgb);
00784                           label = l.index_();
00785                         }
00786                       }
00787 
00788                       _group(rgb) =  label;
00789                     }
00790 
00791                 }
00792                 trace::exiting("update group");
00793                 // END UPDATE GROUP
00794 
00795                 // BEGIN UPDATE MEAN
00796                 trace::entering("update mean");
00797                 {
00798                   mln_eiter(t_number_img) en(_number);
00799                   mln_eiter(t_mean_img)   em(_mean);
00800 
00801                   for_all_2(en,em)
00802                   {
00803                     _number[en.index_()] = literal::zero;
00804                     _mean[em.index_()]   = literal::zero;
00805                   }
00806 
00807                   mln_piter(t_group_img)  rgb(_group.domain());
00808 
00809                   for_all(rgb)
00810                   {
00811                     _mean[_group(rgb)][0] += rgb.row() * _histo(rgb);
00812                     _mean[_group(rgb)][1] += rgb.col() * _histo(rgb);
00813                     _mean[_group(rgb)][2] += rgb.sli() * _histo(rgb);
00814                     _number(_group(rgb))  += _histo(rgb);
00815                   }
00816 
00817                   mln_eiter(t_mean_img)   l(_mean);
00818 
00819                   for_all(l)
00820                   {
00821                     _is_number_valid = (0 != _number[l.index_()]);
00822 
00823                     if (!_is_number_valid)
00824                       break;
00825 
00826                       _mean[l.index_()] /= _number[l.index_()];
00827                   }
00828                 }
00829                 trace::exiting("update mean");
00830                 // END UPDATE MEAN
00831 
00832 
00833                 // Stopping Nan propagation
00834                 if (!_is_number_valid)
00835                   break;
00836 
00837                 // UPDATE DISTANCE
00838                 trace::entering("update distance");
00839 
00840                 for (unsigned i = 0; i < _k_center; ++i)
00841                 {
00842                   mln_piter(t_distance_val) d(_distance[i].domain());
00843 
00844                   for_all(d)
00845                   {
00846                     // the square distance
00847                     t_result1d diff2_row = math::sqr(d.row() - _mean[i][0]);
00848                     t_result1d diff2_col = math::sqr(d.col() - _mean[i][1]);
00849                     t_result1d diff2_sli = math::sqr(d.sli() - _mean[i][2]);
00850                     _distance[i](d)      = _histo(d)*
00851                       (diff2_row + diff2_col + diff2_sli);
00852                   }
00853                 }
00854                 trace::exiting("update distance");
00855                 // END UPDATE DISTANCE
00856 
00857                 // BEGIN UPDATE VARIANCE
00858                 trace::entering("update variance");
00859                 {
00860                   _within_variance          = literal::zero;
00861                   mln_eiter(t_variance_img) l(_variance);
00862 
00863                   for_all(l)
00864                   {
00865                     _variance[l.index_()] = literal::zero;
00866 
00867                     mln_piter(t_group_img) rgb(_group.domain());
00868 
00869                     for_all(rgb)
00870                     {
00871                       if (l.index_() == _group(rgb))
00872                         _variance[l.index_()] += _distance[l.index_()](rgb);
00873                     }
00874 
00875                     _within_variance += _variance[l.index_()];
00876                   }
00877 
00878                 }
00879                 trace::exiting("update variance");
00880                 // END UPDATE VARIANCE
00881 
00882                 //update_cnv();
00883 
00884                 ++_current_step;
00885               }
00886               while (_current_step < _watch_dog &&
00887                      _within_variance < old_variance);
00888 
00889               //finalize_cnv();
00890               //build_all_dbg();
00891             }
00892             trace::exiting("Launch one time");
00893             // END LAUNCH ONE TIME
00894 
00895             if ((_is_number_valid && (_current_step < _watch_dog))||
00896                 _N_TRIES < tries)
00897             {
00898               if (_within_variance < _variance_min)
00899               {
00900                 _variance_min  = _within_variance;
00901                 _mean_min      = _mean;
00902                 _launching_min = _current_launching;
00903               }
00904 
00905               // Reinitialize the number of echecs possible
00906               tries = 0;
00907 
00908               //std::cout << "_current_launching : " << _current_launching
00909               //            << std::endl;
00910 
00911               //std::cout << "within_variance[" << _current_launching << "] = "
00912               //            << _within_variance << std::endl;
00913 
00914               ++_current_launching;
00915             }
00916             else
00917               ++tries;
00918             }
00919 
00920           //Debugging code
00921           //build_all_dbg();
00922 
00923         }
00924         // END LOOP N TIMES
00925 
00926         // BEGIN BUILD LABEL IMAGE
00927         _label_dbg = data::transform(_point, rgbn_to_lbl8<n>(_group));
00928 
00929 //      {
00930 //        mln_piter(t_point_img) pi(_point.domain());
00931 //        mln_piter(t_label_dbg) po(_label_dbg.domain());
00932 
00933 //        for_all_2(pi, po)
00934 //        {
00935 //          t_value    val = _point(pi);
00936 //          t_label    grp = _group(point3d(val.blue(),val.red(),val.green()));
00937 
00938 //          _label_dbg(po) = ++grp;
00939 //        }
00940 //      }
00941 
00942         // END BUILD LABEL IMAGE
00943         trace::exiting("mln::clustering::impl::kmean_image2d_rgb");
00944 
00945         return _label_dbg;
00946 
00947         }
00948 
00949     } // end of namespace mln::clustering::impl
00950 
00951 
00952 
00953 
00954 
00955     //--------------------------------------------------------------------------
00956     // Internal.
00957     //--------------------------------------------------------------------------
00958 
00959     namespace internal
00960     {
00961 
00962       template <typename T, unsigned n, typename I>
00963       inline
00964       mln_ch_value(I,value::label_8)
00965       kmean_rgb_dispatch(const Image<I>& img,
00966                          const unsigned  k_center,
00967                          const unsigned  watch_dog,
00968                          const unsigned  n_times,
00969                          const value::rgb<n>&,
00970                          const point2d&)
00971       {
00972         return impl::kmean_image2d_rgb<T,n>(img, k_center, watch_dog, n_times);
00973       }
00974 
00975       template <typename T, unsigned n, typename I, typename V, typename P>
00976       inline
00977       mln_ch_value(I,value::label_8)
00978       kmean_rgb_dispatch(const Image<I>& img,
00979                          const unsigned  k_center,
00980                          const unsigned  watch_dog,
00981                          const unsigned  n_times,
00982                          const V&,
00983                          const P&)
00984       {
00985         // No kmean implementation found.
00986         mlc_abort(I)::check();
00987 
00988         typedef mln_ch_value(I, value::label_8) output_t;
00989         return output_t();
00990       }
00991 
00992 
00993       template <typename T, unsigned n, typename I>
00994       inline
00995       mln_ch_value(I,value::label_8)
00996       kmean_rgb_dispatch(const Image<I>& img,
00997                          const unsigned  k_center,
00998                          const unsigned  watch_dog,
00999                          const unsigned  n_times)
01000       {
01001         typedef mln_value(I) V;
01002         typedef mln_site(I) P;
01003         return kmean_rgb_dispatch<T,n>(img, k_center, watch_dog,
01004                                        n_times, V(), P());
01005       }
01006 
01007 
01008     } // end of namespace mln::clustering::internal
01009 
01010 
01011     //--------------------------------------------------------------------------
01012     // Facade.
01013     //--------------------------------------------------------------------------
01014 
01015     template <typename T, unsigned n, typename I>
01016     inline
01017     mln_ch_value(I,value::label_8)
01018     kmean_rgb(const Image<I>& point,
01019               const unsigned  k_center,
01020               const unsigned  watch_dog,
01021               const unsigned  n_times)
01022     {
01023       trace::entering("mln::clustering::kmean_rgb");
01024 
01025       mln_ch_value(I, value::label_8)
01026         output = internal::kmean_rgb_dispatch<T,n>(point, k_center,
01027                                                    watch_dog, n_times);
01028       trace::exiting("mln::clustering::kmean_rgb");
01029 
01030       return output;
01031     }
01032 
01033 
01034 # endif // ! MLN_INCLUDE_ONLY
01035 
01036   } // end of namespace mln::clustering
01037 
01038 } // end of namespace mln
01039 
01040 #endif // ! MLN_CLUSTERING_KMEAN_RGB_HH

Generated on Tue Oct 4 2011 15:24:01 for Milena (Olena) by  doxygen 1.7.1