• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

colorize.hh

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

Generated on Tue Oct 4 2011 15:23:35 for Milena (Olena) by  doxygen 1.7.1