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

colorize.hh

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

Generated on Fri Oct 19 2012 04:15:41 for Milena (Olena) by  doxygen 1.7.1