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 # ifndef MLN_WO_GLOBAL_VARS
00098
00099 namespace colorize_
00100 {
00101 unsigned min_value = 20;
00102 unsigned max_value = 220;
00103 }
00104
00105 # endif // ! MLN_WO_GLOBAL_VARS
00106
00107 namespace internal
00108 {
00109
00110 inline
00111 unsigned random_number()
00112 {
00113 unsigned last = colorize_::min_value + (colorize_::max_value - colorize_::min_value + 1) * rand();
00114
00115 return math::min(colorize_::min_value + last % colorize_::max_value, colorize_::max_value);
00116 }
00117
00118
00119
00120 template <typename V>
00121 V random_color(const V&);
00122
00123
00124 template <typename RGB>
00125 RGB
00126 random_color_rgb(const RGB&)
00127 {
00128 static unsigned
00129 nelements = colorize_::max_value - colorize_::min_value + 1;
00130 static util::array<util::set<unsigned> >
00131 red_(nelements),
00132 green_(nelements);
00133
00134 unsigned red, green, blue;
00135
00136 unsigned ntries = 0;
00137 do
00138 {
00139 red = random_number();
00140 ++ntries;
00141 }
00142 while (red_[red - colorize_::min_value].nelements() == nelements
00143 && ntries < nelements);
00144
00145 if (ntries == nelements)
00146 {
00147 trace::warning("labeling::colorize - Can't find a new unique color. Returning black.");
00148 return literal::black;
00149 }
00150
00151
00152 do
00153 green = random_number();
00154 while (red_[red - colorize_::min_value].has(green)
00155 || green_[green - colorize_::min_value].nelements() == nelements);
00156 red_[red - colorize_::min_value].insert(green);
00157
00158 do
00159 blue = random_number();
00160 while (green_[green - colorize_::min_value].has(blue));
00161 green_[green - colorize_::min_value].insert(blue);
00162
00163 return RGB(red, green, blue);
00164 }
00165
00166 template <unsigned n>
00167 mln::value::rgb<n>
00168 random_color(const mln::value::rgb<n>& v)
00169 {
00170 return random_color_rgb(v);
00171 }
00172
00173
00174 # ifdef MLN_VALUE_QT_RGB32_HH
00175
00176 inline
00177 mln::value::qt::rgb32
00178 random_color(const mln::value::qt::rgb32& v)
00179 {
00180 return random_color_rgb(v);
00181 }
00182
00183 # endif // ! MLN_VALUE_QT_RGB32_HH
00184
00185 }
00186
00187 template <typename V, typename L>
00188 inline
00189 mln_ch_value(L, V)
00190 colorize(const V& value,
00191 const Image<L>& input,
00192 const mln_value(L)& nlabels)
00193 {
00194 trace::entering("labeling::colorize");
00195 mln_precondition(exact(input).is_valid());
00196
00197
00198
00199 (void) value;
00200
00201 unsigned label_count = value::next(nlabels);
00202 static fun::i2v::array<V> f(0);
00203 int diff_size = f.size() - label_count;
00204 if (diff_size < 0)
00205 {
00206 srand(1);
00207 f.resize(label_count);
00208 unsigned i = f.size() + diff_size;
00209
00210 if (i == 0)
00211 {
00212 i = 1;
00213 f(0) = literal::black;
00214 }
00215 for (; i < f.size(); ++i)
00216 f(i) = internal::random_color(value);
00217 }
00218 mln_assertion(f.size() >= (label_count));
00219 mln_ch_value(L, V) output = data::transform(input, f);
00220
00221 trace::exiting("labeling::colorize");
00222 return output;
00223 }
00224
00225 template <typename V, typename L>
00226 inline
00227 mln_ch_value(L, V)
00228 colorize(const V& value,
00229 const Image<L>& input)
00230 {
00231 trace::entering("labeling::colorize");
00232 mln_precondition(exact(input).is_valid());
00233
00234 accu::stat::max<mln_value(L)> accu;
00235 mln_value(L) nlabels = data::compute(accu, input);
00236
00237 mln_ch_value(L,V) output = colorize(value, input, nlabels);
00238
00239 trace::exiting("labeling::colorize");
00240 return output;
00241 }
00242
00243
00244 template <typename L>
00245 inline
00246 mln_ch_value(L, mln::value::rgb8)
00247 colorize(const Image<L>& input,
00248 const mln_value(L)& nlabels)
00249 {
00250 return colorize(mln::value::rgb8(), input, nlabels);
00251 }
00252
00253
00254 # endif // ! MLN_INCLUDE_ONLY
00255
00256 }
00257
00258 }
00259
00260
00261 #endif // ! MLN_LABELING_COLORIZE_HH