00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_LABELING_COLORIZE_HH
00028 # define MLN_LABELING_COLORIZE_HH
00029
00033
00034 # include <mln/core/concept/image.hh>
00035 # include <mln/fun/i2v/array.hh>
00036 # include <mln/value/rgb8.hh>
00037 # include <mln/literal/black.hh>
00038 # include <mln/data/transform.hh>
00039 # include <mln/data/compute.hh>
00040 # include <mln/accu/stat/max.hh>
00041 # include <mln/util/array.hh>
00042 # include <mln/util/set.hh>
00043 # include <mln/value/next.hh>
00044
00045
00046 namespace mln
00047 {
00048
00049 namespace labeling
00050 {
00051
00052
00053 namespace colorize_
00054 {
00055 extern unsigned min_value;
00056 extern unsigned max_value;
00057 }
00058
00059
00062
00072 template <typename V, typename L>
00073 mln_ch_value(L, V)
00074 colorize(const V& value,
00075 const Image<L>& labeled_image,
00076 const mln_value(L)& nlabels);
00077
00078
00080
00081 template <typename V, typename L>
00082 mln_ch_value(L, V)
00083 colorize(const V& value,
00084 const Image<L>& labeled_image);
00085
00086
00088
00089 template <typename L>
00090 mln_ch_value(L, mln::value::rgb8)
00091 colorize(const Image<L>& input,
00092 const mln_value(L)& nlabels);
00093
00094
00095 # ifndef MLN_INCLUDE_ONLY
00096
00097 namespace colorize_
00098 {
00099 unsigned min_value = 20;
00100 unsigned max_value = 220;
00101 }
00102
00103
00104 namespace internal
00105 {
00106
00107 unsigned random_number()
00108 {
00109 unsigned last = colorize_::min_value + (colorize_::max_value - colorize_::min_value + 1) * rand();
00110
00111 return math::min(colorize_::min_value + last % colorize_::max_value, colorize_::max_value);
00112 }
00113
00114
00115
00116 template <typename V>
00117 V random_color(const V&);
00118
00119
00120 template <typename RGB>
00121 RGB
00122 random_color_rgb(const RGB&)
00123 {
00124 static unsigned
00125 nelements = colorize_::max_value - colorize_::min_value + 1;
00126 static util::array<util::set<unsigned> >
00127 red_(nelements),
00128 green_(nelements);
00129
00130 unsigned red, green, blue;
00131
00132 unsigned ntries = 0;
00133 do
00134 {
00135 red = random_number();
00136 ++ntries;
00137 }
00138 while (red_[red - colorize_::min_value].nelements() == nelements
00139 && ntries < nelements);
00140
00141 if (ntries == nelements)
00142 {
00143 trace::warning("labeling::colorize - Can't find a new unique color. Returning black.");
00144 return literal::black;
00145 }
00146
00147
00148 do
00149 green = random_number();
00150 while (red_[red - colorize_::min_value].has(green)
00151 || green_[green - colorize_::min_value].nelements() == nelements);
00152 red_[red - colorize_::min_value].insert(green);
00153
00154 do
00155 blue = random_number();
00156 while (green_[green - colorize_::min_value].has(blue));
00157 green_[green - colorize_::min_value].insert(blue);
00158
00159 return RGB(red, green, blue);
00160 }
00161
00162 template <unsigned n>
00163 mln::value::rgb<n>
00164 random_color(const mln::value::rgb<n>& v)
00165 {
00166 return random_color_rgb(v);
00167 }
00168
00169
00170 # ifdef MLN_VALUE_QT_RGB32_HH
00171
00172 mln::value::qt::rgb32
00173 random_color(const mln::value::qt::rgb32& v)
00174 {
00175 return random_color_rgb(v);
00176 }
00177
00178 # endif // ! MLN_VALUE_QT_RGB32_HH
00179
00180 }
00181
00182 template <typename V, typename L>
00183 inline
00184 mln_ch_value(L, V)
00185 colorize(const V& value,
00186 const Image<L>& input,
00187 const mln_value(L)& nlabels)
00188 {
00189 trace::entering("labeling::colorize");
00190 mln_precondition(exact(input).is_valid());
00191
00192
00193
00194 (void) value;
00195
00196 unsigned label_count = value::next(nlabels);
00197 static fun::i2v::array<V> f(0);
00198 int diff_size = f.size() - label_count;
00199 if (diff_size < 0)
00200 {
00201 srand(1);
00202 f.resize(label_count);
00203 unsigned i = f.size() + diff_size;
00204
00205 if (i == 0)
00206 {
00207 i = 1;
00208 f(0) = literal::black;
00209 }
00210 for (; i < f.size(); ++i)
00211 f(i) = internal::random_color(value);
00212 }
00213 mln_assertion(f.size() >= (label_count));
00214 mln_ch_value(L, V) output = data::transform(input, f);
00215
00216 trace::exiting("labeling::colorize");
00217 return output;
00218 }
00219
00220 template <typename V, typename L>
00221 inline
00222 mln_ch_value(L, V)
00223 colorize(const V& value,
00224 const Image<L>& input)
00225 {
00226 trace::entering("labeling::colorize");
00227 mln_precondition(exact(input).is_valid());
00228
00229 accu::stat::max<mln_value(L)> accu;
00230 mln_value(L) nlabels = data::compute(accu, input);
00231
00232 mln_ch_value(L,V) output = colorize(value, input, nlabels);
00233
00234 trace::exiting("labeling::colorize");
00235 return output;
00236 }
00237
00238
00239 template <typename L>
00240 inline
00241 mln_ch_value(L, mln::value::rgb8)
00242 colorize(const Image<L>& input,
00243 const mln_value(L)& nlabels)
00244 {
00245 return colorize(mln::value::rgb8(), input, nlabels);
00246 }
00247
00248
00249 # endif // ! MLN_INCLUDE_ONLY
00250
00251 }
00252
00253 }
00254
00255
00256 #endif // ! MLN_LABELING_COLORIZE_HH