26 #ifndef MLN_CLUSTERING_KMEAN_RGB_HH
27 # define MLN_CLUSTERING_KMEAN_RGB_HH
97 # include <mln/accu/stat/histo3d_rgb.hh>
99 # include <mln/algebra/vec.hh>
101 # include <mln/core/concept/image.hh>
102 # include <mln/core/contract.hh>
103 # include <mln/core/image/image2d.hh>
104 # include <mln/core/macros.hh>
106 # include <mln/data/compute.hh>
107 # include <mln/data/fill.hh>
108 # include <mln/data/transform.hh>
110 # include <mln/debug/println.hh>
112 # include <mln/io/ppm/save.hh>
113 # include <mln/io/pgm/save.hh>
115 # include <mln/labeling/colorize.hh>
116 # include <mln/labeling/mean_values.hh>
118 # include <mln/literal/zero.hh>
119 # include <mln/literal/one.hh>
121 # include <mln/math/min.hh>
122 # include <mln/math/sqr.hh>
124 # include <mln/norm/l2.hh>
126 # include <mln/opt/at.hh>
128 # include <mln/trace/entering.hh>
129 # include <mln/trace/exiting.hh>
131 # include <mln/trait/value_.hh>
133 # include <mln/util/array.hh>
135 # include <mln/value/int_u.hh>
136 # include <mln/value/rgb8.hh>
137 # include <mln/value/label_8.hh>
168 template <
typename T,
unsigned n,
typename I>
171 kmean_rgb(const Image<I>& point,
172 const
unsigned k_center,
173 const
unsigned watch_dog,
174 const
unsigned n_times);
182 # ifndef MLN_INCLUDE_ONLY
500 template <
unsigned n>
501 struct rgbn_to_lbl8 : Function_v2v< rgbn_to_lbl8<n> >
503 typedef value::rgb<n> argument;
506 typedef image3d<t_label> t_group_img;
510 rgbn_to_lbl8(t_group_img group) : _group(group) {}
512 result operator()(
const argument& c)
const
521 template <
typename T,
unsigned n>
522 struct rgb_to_dist : Function_v2v< rgb_to_dist<T,n> >
524 typedef value::rgb<n> argument;
526 typedef T t_result1d;
527 typedef algebra::vec<3,T> t_result3d;
528 typedef image3d<unsigned> t_histo_img;
533 rgb_to_dist(t_result3d mean, t_histo_img histo) : _mean(mean),
536 result operator()(
const argument& c)
const
538 t_result1d diff2_row = math::sqr(c.row() - _mean[0]);
539 t_result1d diff2_col = math::sqr(c.col() - _mean[1]);
540 t_result1d diff2_sli = math::sqr(c.sli() - _mean[2]);
541 t_result1d tmp = _histo(c)*(diff2_row + diff2_col + diff2_sli);
547 template <
typename T,
unsigned n,
typename I>
550 kmean_image2d_rgb(const Image<I>& point__,
551 const
unsigned k_center,
552 const
unsigned watch_dog = 10,
553 const
unsigned n_times = 10)
555 trace::entering(
"mln::clustering::impl::kmean_image2d_rgb");
557 const I& point = exact(point__);
558 typedef mln_value(I) V;
559 mlc_is(V, value::rgb<n>)::check();
560 mlc_bool(mln_site_(I)::dim == 2u)::check();
561 mln_precondition(point.is_valid());
564 typedef value::rgb<8> t_rgb;
565 typedef value::label<8> t_label;
566 typedef value::rgb<n> t_value;
567 typedef mln_trait_value_comp(t_value,0) t_value_comp0;
568 typedef mln_trait_value_comp(t_value,1) t_value_comp1;
569 typedef mln_trait_value_comp(t_value,2) t_value_comp2;
570 typedef T t_result1d;
571 typedef algebra::vec<3,T> t_result3d;
573 typedef I t_point_img;
574 typedef image3d<
unsigned> t_histo_img;
575 typedef util::array<t_result1d> t_number_img;
576 typedef util::array<t_result3d> t_mean_img;
577 typedef util::array<t_result1d> t_variance_img;
579 typedef image3d<t_label> t_group_img;
580 typedef image3d<t_result1d> t_distance_val;
581 typedef util::array<t_distance_val> t_distance_img;
583 typedef mln_ch_value(I,t_label) t_label_dbg;
584 typedef image2d<t_rgb> t_color_dbg;
585 typedef image2d<t_value> t_mean_dbg;
587 typedef image1d<t_result3d> t_mean_val;
588 typedef util::array<t_mean_val> t_mean_set;
589 typedef util::array<t_mean_set> t_mean_cnv;
590 typedef image1d<t_result1d> t_variance_val;
591 typedef util::array<t_variance_val> t_variance_cnv;
595 mln_precondition(point.is_valid());
597 static const
unsigned _N_TRIES = 3;
599 typedef accu::meta::stat::histo3d_rgb t_histo3d_rgb;
601 t_result1d _within_variance;
603 unsigned _k_center = k_center;
604 unsigned _watch_dog = watch_dog;
605 unsigned _n_times = n_times;
606 t_point_img _point = point;
609 t_histo_img _histo =
data::compute(t_histo3d_rgb(),
613 t_number_img _number;
615 t_variance_img _variance;
617 for (
unsigned i = 0; i < _k_center; ++i)
625 unsigned _current_step = 0;
626 unsigned _current_launching = 0;
627 bool _is_number_valid =
false;
629 unsigned _launching_min;
630 t_result1d _variance_min;
631 t_mean_img _mean_min;
636 t_distance_img _distance;
639 t_label_dbg _label_dbg;
640 t_color_dbg _color_dbg;
641 t_mean_dbg _mean_dbg;
644 t_mean_cnv _mean_cnv;
645 t_variance_cnv _variance_cnv;
651 mln_min(t_value_comp0),
652 mln_min(t_value_comp1)),
653 point3d(mln_max(t_value_comp2),
654 mln_max(t_value_comp0),
655 mln_max(t_value_comp1))));
657 for (
unsigned i = 0; i < _k_center; ++i)
659 t_distance_val img(
box3d(
point3d(mln_min(t_value_comp2),
660 mln_min(t_value_comp0),
661 mln_min(t_value_comp1)),
662 point3d(mln_max(t_value_comp2),
663 mln_max(t_value_comp0),
664 mln_max(t_value_comp1))));
666 _distance.append(img);
676 for (
unsigned i = 0; i < _n_times; ++i)
682 _variance_cnv.append(img);
685 for (
unsigned i = 0; i < _k_center; ++i)
689 for (
unsigned j = 0; j < _n_times; ++j)
695 mean_set.append(img);
698 _mean_cnv.append(mean_set);
705 _variance_min = mln_max(t_result1d);
706 _current_launching = 0;
708 while (_current_launching < _n_times)
711 trace::entering(
"Launch one time");
713 t_result1d old_variance = mln_max(t_result1d);
714 _within_variance = mln_max(t_result1d);
718 trace::entering(
"init mean");
720 t_value_comp0 min_comp0 = mln_min(t_value_comp0);
721 t_value_comp0 max_comp0 = mln_max(t_value_comp0);
722 t_value_comp1 min_comp1 = mln_min(t_value_comp1);
723 t_value_comp1 max_comp1 = mln_max(t_value_comp1);
724 t_value_comp2 min_comp2 = mln_min(t_value_comp2);
725 t_value_comp2 max_comp2 = mln_max(t_value_comp2);
726 mln_eiter(t_mean_img) l(_mean);
730 _mean[l.index_()][0]=(rand()%(max_comp0-min_comp0))+min_comp0;
731 _mean[l.index_()][1]=(rand()%(max_comp1-min_comp1))+min_comp1;
732 _mean[l.index_()][2]=(rand()%(max_comp2-min_comp2))+min_comp2;
735 trace::exiting(
"init mean");
740 trace::entering(
"update distance");
742 for (
unsigned i = 0; i < _k_center; ++i)
749 mln_piter(t_distance_val) d(_distance[i].domain());
753 t_result1d diff2_row = math::sqr(d.row() - _mean[i][0]);
754 t_result1d diff2_col = math::sqr(d.col() - _mean[i][1]);
755 t_result1d diff2_sli = math::sqr(d.sli() - _mean[i][2]);
756 _distance[i](d) = _histo(d)*
757 (diff2_row + diff2_col + diff2_sli);
761 trace::exiting(
"update distance");
766 old_variance = _within_variance;
769 trace::entering(
"update group");
771 mln_piter(t_group_img) rgb(_group.domain());
775 mln_eiter(t_distance_img) l(_distance);
776 t_result1d min = mln_max(t_result1d);
777 t_label label = mln_max(t_label);
781 if (min > _distance[l.index_()](rgb))
783 min = _distance[l.index_()](rgb);
792 trace::exiting(
"update group");
796 trace::entering(
"update mean");
798 mln_eiter(t_number_img) en(_number);
799 mln_eiter(t_mean_img) em(_mean);
807 mln_piter(t_group_img) rgb(_group.domain());
811 _mean[_group(rgb)][0] += rgb.row() * _histo(rgb);
812 _mean[_group(rgb)][1] += rgb.col() * _histo(rgb);
813 _mean[_group(rgb)][2] += rgb.sli() * _histo(rgb);
814 _number(_group(rgb)) += _histo(rgb);
817 mln_eiter(t_mean_img) l(_mean);
821 _is_number_valid = (0 != _number[l.index_()]);
823 if (!_is_number_valid)
826 _mean[l.index_()] /= _number[l.index_()];
829 trace::exiting(
"update mean");
834 if (!_is_number_valid)
838 trace::entering(
"update distance");
840 for (
unsigned i = 0; i < _k_center; ++i)
842 mln_piter(t_distance_val) d(_distance[i].domain());
847 t_result1d diff2_row = math::sqr(d.row() - _mean[i][0]);
848 t_result1d diff2_col = math::sqr(d.col() - _mean[i][1]);
849 t_result1d diff2_sli = math::sqr(d.sli() - _mean[i][2]);
850 _distance[i](d) = _histo(d)*
851 (diff2_row + diff2_col + diff2_sli);
854 trace::exiting(
"update distance");
858 trace::entering(
"update variance");
861 mln_eiter(t_variance_img) l(_variance);
867 mln_piter(t_group_img) rgb(_group.domain());
871 if (l.index_() == _group(rgb))
872 _variance[l.index_()] += _distance[l.index_()](rgb);
875 _within_variance += _variance[l.index_()];
879 trace::exiting(
"update variance");
886 while (_current_step < _watch_dog &&
887 _within_variance < old_variance);
892 trace::exiting(
"Launch one time");
895 if ((_is_number_valid && (_current_step < _watch_dog))||
898 if (_within_variance < _variance_min)
900 _variance_min = _within_variance;
902 _launching_min = _current_launching;
914 ++_current_launching;
943 trace::exiting(
"mln::clustering::impl::kmean_image2d_rgb");
962 template <
typename T,
unsigned n,
typename I>
965 kmean_rgb_dispatch(const Image<I>& img,
966 const
unsigned k_center,
967 const
unsigned watch_dog,
968 const
unsigned n_times,
969 const value::rgb<n>&,
972 return impl::kmean_image2d_rgb<T,n>(img, k_center, watch_dog, n_times);
975 template <
typename T,
unsigned n,
typename I,
typename V,
typename P>
978 kmean_rgb_dispatch(const Image<I>& img,
979 const
unsigned k_center,
980 const
unsigned watch_dog,
981 const
unsigned n_times,
986 mlc_abort(I)::check();
993 template <typename T,
unsigned n, typename I>
995 mln_ch_value(I,value::label_8)
996 kmean_rgb_dispatch(const Image<I>& img,
997 const
unsigned k_center,
998 const
unsigned watch_dog,
999 const
unsigned n_times)
1001 typedef mln_value(I) V;
1002 typedef mln_site(I) P;
1003 return kmean_rgb_dispatch<T,n>(img, k_center, watch_dog,
1015 template <typename T,
unsigned n, typename I>
1017 mln_ch_value(I,value::label_8)
1018 kmean_rgb(const Image<I>& point,
1019 const
unsigned k_center,
1020 const
unsigned watch_dog,
1021 const
unsigned n_times)
1023 trace::entering(
"mln::clustering::kmean_rgb");
1026 output = internal::kmean_rgb_dispatch<T,n>(point, k_center,
1027 watch_dog, n_times);
1028 trace::exiting("mln::clustering::kmean_rgb");
1034 # endif // ! MLN_INCLUDE_ONLY
1040 #endif // ! MLN_CLUSTERING_KMEAN_RGB_HH