$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
colorize.hh
1 // Copyright (C) 2008, 2009, 2010, 2011, 2013 EPITA Research and
2 // Development Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_LABELING_COLORIZE_HH
28 # define MLN_LABELING_COLORIZE_HH
29 
33 
34 # include <mln/core/concept/image.hh>
35 # include <mln/fun/i2v/array.hh>
36 # include <mln/value/rgb8.hh>
37 # include <mln/literal/black.hh>
38 # include <mln/data/transform.hh>
39 # include <mln/data/compute.hh>
40 # include <mln/accu/stat/max.hh>
41 # include <mln/util/array.hh>
42 # include <mln/util/set.hh>
43 # include <mln/value/next.hh>
44 
45 
46 namespace mln
47 {
48 
49  namespace labeling
50  {
51 
52  // Forward declaration.
53  namespace colorize_
54  {
55  extern unsigned min_value;
56  extern unsigned max_value;
57  }
58 
59 
74  template <typename V, typename L>
75  mln_ch_value(L, V)
76  colorize(const V& value,
77  const Image<L>& labeled_image,
78  const mln_value(L)& nlabels);
79 
80 
89  template <typename V, typename L>
90  mln_ch_value(L, V)
91  colorize(const V& value,
92  const Image<L>& labeled_image);
93 
94 
101  template <typename L>
102  mln_ch_value(L, mln::value::rgb8)
103  colorize(const Image<L>& input,
104  const mln_value(L)& nlabels);
105 
106 
107 # ifndef MLN_INCLUDE_ONLY
108 
109 # ifndef MLN_WO_GLOBAL_VARS
110 
111  namespace colorize_
112  {
113  unsigned min_value = 20;
114  unsigned max_value = 220;
115  }
116 
117 # endif // ! MLN_WO_GLOBAL_VARS
118 
119  namespace internal
120  {
121 
122  inline
123  unsigned random_number()
124  {
125  unsigned last = colorize_::min_value + (colorize_::max_value - colorize_::min_value + 1) * rand();
126 
127  return math::min(colorize_::min_value + last % colorize_::max_value, colorize_::max_value);
128  }
129 
130 
131  // No random color generator is available for the value type V.
132  template <typename V>
133  V random_color(const V&);
134 
135 
136  template <typename RGB>
137  RGB
138  random_color_rgb(const RGB&)
139  {
140  static unsigned
141  nelements = colorize_::max_value - colorize_::min_value + 1;
142  static util::array<util::set<unsigned> >
143  red_(nelements),
144  green_(nelements);
145 
146  unsigned red, green, blue;
147 
148  unsigned ntries = 0;
149  do
150  {
151  red = random_number();
152  ++ntries;
153  }
154  while (red_[red - colorize_::min_value].nelements() == nelements
155  && ntries < nelements);
156 
157  if (ntries == nelements)
158  {
159  mln_trace_warning("labeling::colorize - Can't find a new unique color. Returning black.");
160  return literal::black;
161  }
162 
163 
164  do
165  green = random_number();
166  while (red_[red - colorize_::min_value].has(green)
167  || green_[green - colorize_::min_value].nelements() == nelements);
168  red_[red - colorize_::min_value].insert(green);
169 
170  do
171  blue = random_number();
172  while (green_[green - colorize_::min_value].has(blue));
173  green_[green - colorize_::min_value].insert(blue);
174 
175  return RGB(red, green, blue);
176  }
177 
178  template <unsigned n>
180  random_color(const mln::value::rgb<n>& v)
181  {
182  return random_color_rgb(v);
183  }
184 
185 
186 # ifdef MLN_VALUE_QT_RGB32_HH
187 
188  inline
190  random_color(const mln::value::qt::rgb32& v)
191  {
192  return random_color_rgb(v);
193  }
194 
195 # endif // ! MLN_VALUE_QT_RGB32_HH
196 
197  }
198 
199  template <typename V, typename L>
200  inline
201  mln_ch_value(L, V)
202  colorize(const V& value,
203  const Image<L>& input,
204  const mln_value(L)& nlabels)
205  {
206  mln_trace("labeling::colorize");
207  mln_precondition(exact(input).is_valid());
208  // FIXME: check that V is a color type.
209  // FIXME: we want to be sure that this is a label.
210  // mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
211  (void) value;
212 
213  unsigned label_count = value::next(nlabels);
214  static fun::i2v::array<V> f(0);
215  int diff_size = f.size() - label_count;
216  if (diff_size < 0)
217  {
218  srand(1);
219  unsigned i = f.size();
220  f.resize(label_count);
221  // We want to treat comp 0 differently since it is the background.
222  if (i == 0)
223  {
224  i = 1;
225  f(0) = literal::black;
226  }
227  for (; i < f.size(); ++i)
228  f(i) = internal::random_color(value);
229  }
230  mln_assertion(f.size() >= (label_count));
231  mln_ch_value(L, V) output = data::transform(input, f);
232 
233  return output;
234  }
235 
236  template <typename V, typename L>
237  inline
238  mln_ch_value(L, V)
239  colorize(const V& value,
240  const Image<L>& input)
241  {
242  mln_trace("labeling::colorize");
243  mln_precondition(exact(input).is_valid());
244 
245  accu::stat::max<mln_value(L)> accu;
246  mln_value(L) nlabels = data::compute(accu, input);
247 
248  mln_ch_value(L,V) output = colorize(value, input, nlabels);
249 
250  return output;
251  }
252 
253 
254  template <typename L>
255  inline
256  mln_ch_value(L, mln::value::rgb8)
257  colorize(const Image<L>& input,
258  const mln_value(L)& nlabels)
259  {
260  return colorize(mln::value::rgb8(), input, nlabels);
261  }
262 
263 
264 # endif // ! MLN_INCLUDE_ONLY
265 
266  } // end of namespace mln::labeling
267 
268 } // end of namespace mln
269 
270 
271 #endif // ! MLN_LABELING_COLORIZE_HH