Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
colorize.hh
1 // Copyright (C) 2008, 2009, 2010, 2011 EPITA Research and Development
2 // 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 
62 
72  template <typename V, typename L>
73  mln_ch_value(L, V)
74  colorize(const V& value,
75  const Image<L>& labeled_image,
76  const mln_value(L)& nlabels);
77 
78 
80  //
81  template <typename V, typename L>
82  mln_ch_value(L, V)
83  colorize(const V& value,
84  const Image<L>& labeled_image);
85 
86 
88  //
89  template <typename L>
90  mln_ch_value(L, mln::value::rgb8)
91  colorize(const Image<L>& input,
92  const mln_value(L)& nlabels);
93 
94 
95 # ifndef MLN_INCLUDE_ONLY
96 
97 # ifndef MLN_WO_GLOBAL_VARS
98 
99  namespace colorize_
100  {
101  unsigned min_value = 20;
102  unsigned max_value = 220;
103  }
104 
105 # endif // ! MLN_WO_GLOBAL_VARS
106 
107  namespace internal
108  {
109 
110  inline
111  unsigned random_number()
112  {
113  unsigned last = colorize_::min_value + (colorize_::max_value - colorize_::min_value + 1) * rand();
114 
115  return math::min(colorize_::min_value + last % colorize_::max_value, colorize_::max_value);
116  }
117 
118 
119  // No random color generator is available for the value type V.
120  template <typename V>
121  V random_color(const V&);
122 
123 
124  template <typename RGB>
125  RGB
126  random_color_rgb(const RGB&)
127  {
128  static unsigned
129  nelements = colorize_::max_value - colorize_::min_value + 1;
130  static util::array<util::set<unsigned> >
131  red_(nelements),
132  green_(nelements);
133 
134  unsigned red, green, blue;
135 
136  unsigned ntries = 0;
137  do
138  {
139  red = random_number();
140  ++ntries;
141  }
142  while (red_[red - colorize_::min_value].nelements() == nelements
143  && ntries < nelements);
144 
145  if (ntries == nelements)
146  {
147  trace::warning("labeling::colorize - Can't find a new unique color. Returning black.");
148  return literal::black;
149  }
150 
151 
152  do
153  green = random_number();
154  while (red_[red - colorize_::min_value].has(green)
155  || green_[green - colorize_::min_value].nelements() == nelements);
156  red_[red - colorize_::min_value].insert(green);
157 
158  do
159  blue = random_number();
160  while (green_[green - colorize_::min_value].has(blue));
161  green_[green - colorize_::min_value].insert(blue);
162 
163  return RGB(red, green, blue);
164  }
165 
166  template <unsigned n>
168  random_color(const mln::value::rgb<n>& v)
169  {
170  return random_color_rgb(v);
171  }
172 
173 
174 # ifdef MLN_VALUE_QT_RGB32_HH
175 
176  inline
178  random_color(const mln::value::qt::rgb32& v)
179  {
180  return random_color_rgb(v);
181  }
182 
183 # endif // ! MLN_VALUE_QT_RGB32_HH
184 
185  }
186 
187  template <typename V, typename L>
188  inline
189  mln_ch_value(L, V)
190  colorize(const V& value,
191  const Image<L>& input,
192  const mln_value(L)& nlabels)
193  {
194  trace::entering("labeling::colorize");
195  mln_precondition(exact(input).is_valid());
196  // FIXME: check that V is a color type.
197  // FIXME: we want to be sure that this is a label.
198  // mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
199  (void) value;
200 
201  unsigned label_count = value::next(nlabels);
202  static fun::i2v::array<V> f(0);
203  int diff_size = f.size() - label_count;
204  if (diff_size < 0)
205  {
206  srand(1);
207  f.resize(label_count);
208  unsigned i = f.size() + diff_size;
209  // We want to treat comp 0 differently since it is the background.
210  if (i == 0)
211  {
212  i = 1;
213  f(0) = literal::black;
214  }
215  for (; i < f.size(); ++i)
216  f(i) = internal::random_color(value);
217  }
218  mln_assertion(f.size() >= (label_count));
219  mln_ch_value(L, V) output = data::transform(input, f);
220 
221  trace::exiting("labeling::colorize");
222  return output;
223  }
224 
225  template <typename V, typename L>
226  inline
227  mln_ch_value(L, V)
228  colorize(const V& value,
229  const Image<L>& input)
230  {
231  trace::entering("labeling::colorize");
232  mln_precondition(exact(input).is_valid());
233 
235  mln_value(L) nlabels = data::compute(accu, input);
236 
237  mln_ch_value(L,V) output = colorize(value, input, nlabels);
238 
239  trace::exiting("labeling::colorize");
240  return output;
241  }
242 
243 
244  template <typename L>
245  inline
246  mln_ch_value(L, mln::value::rgb8)
247  colorize(const Image<L>& input,
248  const mln_value(L)& nlabels)
249  {
250  return colorize(mln::value::rgb8(), input, nlabels);
251  }
252 
253 
254 # endif // ! MLN_INCLUDE_ONLY
255 
256  } // end of namespace mln::labeling
257 
258 } // end of namespace mln
259 
260 
261 #endif // ! MLN_LABELING_COLORIZE_HH