naive_generic_salembier.hh

00001 // Copyright (C) 2006  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016 // Boston, MA 02110-1301, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library 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
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 
00029 // FIXME: This version of Salembier et al. algorithm has been
00030 // superseded by oln::lrde::ufmt::generic_simplified_salembier, and
00031 // should not be useful anymore.
00032 
00033 
00034 #ifndef OLENA_LRDE_UFMT_NAIVE_GENERIC_SALEMBIER_HH
00035 # define OLENA_LRDE_UFMT_NAIVE_GENERIC_SALEMBIER_HH
00036 
00037 # include <iostream>
00038 
00039 # include <values.h> // for MAXINT...
00040 # include <queue>
00041 # include <map>
00042 
00043 # include <set>
00044 
00045 # include <oln/level/fill.hh>
00046 # include <oln/lrde/ufmt/utils.hh>
00047 
00048 
00049 
00050 // Forward declaration.
00051 namespace ntg
00052 {
00053   template <unsigned nbits, class behavior>
00054   class int_u;
00055 }
00056 
00057 namespace oln
00058 {
00059 
00060   namespace lrde
00061   {
00062 
00063     namespace ufmt
00064     {
00065 
00066       /*------------------------------------------------------------.
00067       | A generic version of Salembier's algorithm (in particular,  |
00068       | working on float values), but naive w.r.t. equal levels (it |
00069       | assumes that each level is unique in the input image).      |
00070       `------------------------------------------------------------*/
00071 
00072       /* FIXME: This version of generic_hqueue is naive, since it
00073          expects that each value in an image is unique.  Provide
00074          another version where a value can appear more than once.  */
00075 
00077       template <class V, class P>
00078       struct naive_generic_hqueue_t
00079       {
00080         void add(V h, const P& p)
00081         {
00082           if (q.find (h) != q.end())
00083             std::cerr
00084               << "oln::lrde::ufmt::naive_generic_hqueue_t: Warning: "
00085               << "two points at level " << h << " inserted in hqueue"
00086               << std::endl;
00087           q.insert(std::make_pair(h, p));
00088         }
00089 
00090         bool empty(V h) const
00091         {
00092           return q.count(h) == 0;
00093         }
00094 
00095         P first(V h)
00096         {
00097           P tmp = q[h];
00098           q.erase (h);
00099           return tmp;
00100         }
00101 
00102         unsigned size() const
00103         {
00104           return q.size;
00105         }
00106 
00107         std::map<V, P> q;
00108       };
00109 
00110 
00116       template <class I>
00117       struct naive_generic_salembier
00118       {
00119         typedef oln_point_type(I) point;
00120         typedef oln_value_type(I) value;
00121         typedef oln_neighborhood_type(I) Nbh;
00122         typedef oln_iter_type(Nbh) niter;
00123 
00124         enum {
00125           not_analyzed = MAXINT - 2,
00126           in_the_queue = MAXINT - 1
00127         };
00128 
00129         const I& f;
00130         const Nbh& nbh;
00131 
00132         typename mute<I, int>::ret status;
00133 
00134         size_t nvalues;
00135         std::map<value, unsigned> number_nodes;
00136         std::set<value> node_at_level;
00137         naive_generic_hqueue_t<value, point> hqueue;
00138         value h_min;
00139 
00140         typedef std::set< value, std::greater<value> > levels_t;
00141         typedef typename levels_t::const_iterator level_iterator;
00142         // Set of all values present in the input image, sorting in
00143         // descending order.
00144         levels_t levels;
00145 
00146         typedef std::pair<unsigned, value> pair_t;
00147         std::map<pair_t, pair_t> father;
00148 
00149 
00150         naive_generic_salembier(const abstract::image<I>& f,
00151                                 const oln_neighborhood_type(I)& nbh) :
00152           f(f.exact()),
00153           nbh(nbh),
00154           // FIXME: status should NOT be initialized here! (but in "init()")
00155           status(f.size())
00156         {
00157         }
00158 
00159 
00160         void go()
00161         {
00162           init();
00163           flood(h_min);
00164         }
00165 
00166 
00167         void init()
00168         {
00169           level::fill(status, not_analyzed);
00170 
00171           oln_iter_type(I) p(f);
00172           p = mlc::begin;
00173           point p_min = p;
00174           h_min = f[p];
00175           for_all(p)
00176             {
00177               // Init levels.
00178               levels.insert(f[p]);
00179               // Find the global minimum.
00180               if (f[p] < h_min)
00181                 {
00182                   h_min = f[p];
00183                   p_min = p;
00184                 }
00185           }
00186           hqueue.add(h_min, p_min);
00187         }
00188 
00189         level_iterator flood(value h)
00190         {
00191           level_iterator m;
00192           while (not hqueue.empty(h))
00193             {
00194               point p = hqueue.first(h);
00195               status[p] = get(number_nodes, h, 0u);
00196 
00197               oln_neighb_type(Nbh) q(nbh, p);
00198               for_all(q)
00199                 if (f.hold(q))
00200                   {
00201                     if (status[q] == not_analyzed)
00202                       {
00203                         hqueue.add(f[q], q);
00204                         status[q] = in_the_queue;
00205                         node_at_level.insert(f[q]); // err. 1
00206                         if (f[q] > f[p])
00207                           {
00208                             m = levels.find(f[q]);
00209                             if (m == levels.end())
00210                               abort();
00211                             while (m != levels.end() and *m > h) // err. 2
00212                               m = flood(*m);
00213                           }
00214                       }
00215                   }
00216             }
00217           number_nodes[h] = get(number_nodes, h, 0u) + 1;
00218 
00219           // Let *m be the greatest level lower than h.
00220           m = levels.find(h);
00221           if (m == levels.end())
00222             abort();
00223           ++m;
00224           while (m != levels.end() and
00225                  node_at_level.find(*m) == node_at_level.end())
00226             ++m;
00227           int i = get(number_nodes, h, 0u) - 1;
00228           if (m != levels.end())
00229             {
00230               int j = get(number_nodes, *m, 0u);
00231               father[pair_t(i, h)] = pair_t(j, *m);
00232             }
00233           else
00234             father[pair_t(i, h)] = pair_t(i, h);
00235           node_at_level.erase(h);
00236           return m;
00237         }
00238 
00239         unsigned n_level_roots() const
00240         {
00241           return father.size();
00242         }
00243 
00246         template <typename Key, typename Data,
00247                   typename Compare, typename Alloc>
00248         Data get(const std::map<Key, Data, Compare, Alloc>& map,
00249                  const Key& key, const Data& default_val) const
00250         {
00251           typename std::map<Key, Data, Compare, Alloc>::const_iterator n =
00252             map.find(key);
00253           if (n != map.end())
00254             return n->second;
00255           else
00256             return default_val;
00257         }
00258 
00259       }; // end of struct naive_generic_salembier
00260 
00261 
00262 
00263     } // end of namespace oln::lrde::ufmt
00264 
00265   } // end of namespace oln::lrde
00266 
00267 } // end of namespace oln
00268 
00269 
00270 #endif // ! OLENA_LRDE_UFMT_NAIVE_GENERIC_SALEMBIER_HH

Generated on Tue Feb 20 20:20:12 2007 for Olena by  doxygen 1.5.1