Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2010, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 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 // Forward declaration. 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 // No random color generator is available for the value type V. 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 // FIXME: check that V is a color type. 00197 // FIXME: we want to be sure that this is a label. 00198 // mlc_is_a(mln_value(L), mln::value::Symbolic)::check(); 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 // We want to treat comp 0 differently since it is the background. 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 } // end of namespace mln::labeling 00257 00258 } // end of namespace mln 00259 00260 00261 #endif // ! MLN_LABELING_COLORIZE_HH