basic_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 #ifndef OLENA_LRDE_UFMT_BASIC_SALEMBIER_HH
00029 # define OLENA_LRDE_UFMT_BASIC_SALEMBIER_HH
00030 
00031 # include <values.h> // for MAXINT...
00032 # include <queue>
00033 # include <map>
00034 
00035 # include <oln/level/fill.hh>
00036 # include <oln/lrde/ufmt/utils.hh>
00037 
00038 
00039 namespace oln
00040 {
00041 
00042   namespace lrde
00043   {
00044 
00045     namespace ufmt
00046     {
00047 
00048       /*-----------------------------------------------------------.
00049       | Original version of Salembier's algorithm (working only on |
00050       | image of unsigned integers).                               |
00051       `-----------------------------------------------------------*/
00052 
00055       template <class P>
00056       struct hqueue_t
00057       {
00058         unsigned nvalues;
00059         
00060         hqueue_t()
00061         {
00062           nvalues = 0;
00063         }
00064 
00065         void set_nvalues(unsigned nvalues)
00066         {
00067           assert(nvalues > 0);
00068           this->nvalues = nvalues;
00069           q = new std::queue<P>[nvalues];
00070         }
00071 
00072         void add(unsigned h, const P& p)
00073         {
00074           assert(h < nvalues);
00075           q[h].push(p);
00076         }
00077 
00078         bool empty(unsigned h) const
00079         {
00080           assert(h < nvalues);
00081           return q[h].empty();
00082         }
00083 
00084         P first(unsigned h)
00085         {
00086           assert(h < nvalues);
00087           P tmp = q[h].front();
00088           q[h].pop();
00089           return tmp;
00090         }
00091 
00092         unsigned size() const
00093         {
00094           unsigned s = 0;
00095           for (unsigned i = 0; i < nvalues; ++i)
00096             s += q[i].size();
00097           return s;
00098         }
00099 
00100         void print (std::ostream& os)
00101         {
00102           os << "hqueue = {";
00103           for (unsigned h = 0; h < nvalues; ++h)
00104             if (not empty(h))
00105               {
00106                 os << "  " << h << " -> { ";
00107                 std::queue<P> queue_copy = q[h];
00108                 while (not queue_copy.empty())
00109                   {
00110                     os << queue_copy.front () << " ";
00111                     queue_copy.pop();
00112                   }
00113                 os << "}";
00114               }
00115           os << " }" << std::endl;
00116         }
00117 
00118         std::queue<P>* q;
00119       };
00120 
00121 
00163       template <class I>
00164       struct basic_salembier
00165       {
00166         typedef oln_point_type(I) point;
00167         typedef oln_value_type(I) value;
00168         typedef oln_neighborhood_type(I) Nbh;
00169         typedef oln_iter_type(Nbh) niter;
00170 
00171         enum {
00172           not_analyzed = MAXINT - 2,
00173           in_the_queue = MAXINT - 1
00174         };
00175 
00176         const I& f;
00177         const Nbh& nbh;
00178 
00179         typename mute<I, int>::ret status;
00180 
00181         size_t nvalues;
00182         unsigned* number_nodes;
00183         bool* node_at_level;
00184         hqueue_t<point> hqueue;
00185         int h_min;
00186 
00187         typedef std::pair<unsigned,unsigned> pair_t;
00188         std::map<pair_t, pair_t> father;
00189 
00190 
00191         basic_salembier(const abstract::image<I>& f,
00192                         const oln_neighborhood_type(I)& nbh) :
00193           f(f.exact()),
00194           nbh(nbh),
00195           // FIXME: status should NOT be initialized here! (but in "init()")
00196           status(f.size())
00197         {
00198         }
00199 
00200 
00201         void go()
00202         {
00203           init();
00204           flood(h_min);
00205         }
00206 
00207 
00208         void init()
00209         {
00210           nvalues = uint_nvalues(f);
00211           number_nodes = new unsigned[nvalues];
00212           node_at_level = new bool[nvalues];
00213           for (unsigned i = 0; i < nvalues; ++i)
00214             {
00215               number_nodes[i] = 0;
00216               node_at_level[i] = false;
00217             }
00218 
00219           level::fill(status, not_analyzed);
00220 
00221           hqueue.set_nvalues(nvalues);
00222           h_min = nvalues;
00223           {
00224             point p_min;
00225             oln_iter_type(I) p(f);
00226             for_all(p)
00227               if (f[p] < h_min)
00228                 {
00229                   h_min = f[p];
00230                   p_min = p;
00231                 }
00232             hqueue.add(h_min, p_min);
00233           }
00234         }
00235 
00236 
00237         int flood(int h)
00238         {
00239           int m;
00240           while (not hqueue.empty(h))
00241             {
00242               point p = hqueue.first(h);
00243               
00244               status[p] = number_nodes[h];
00245 
00246               oln_neighb_type(Nbh) q(nbh, p);
00247               for_all(q)
00248                 if (f.hold(q))
00249                   {
00250                     if (status[q] == not_analyzed)
00251                       {
00252                         hqueue.add(f[q], q);
00253                         status[q] = in_the_queue;
00254                         node_at_level[f[q]] = true; // err. 1
00255                         if (f[q] > f[p])
00256                           {
00257                             m = f[q];
00258                             while (m > h) // err. 2
00259                               m = flood(m);
00260                           }
00261                       }
00262                   }
00263             }
00264           number_nodes[h] = number_nodes[h] + 1;
00265 
00266           m = h - 1;
00267           while (m >= 0 and node_at_level[m] == false)
00268             m = m - 1;
00269           int i = number_nodes[h] - 1;
00270           if (m >= 0)
00271             {
00272               int j = number_nodes[m];
00273               father[pair_t(i, h)] = pair_t(j, m);
00274             }
00275           else
00276             {
00277               father[pair_t(i, h)] = pair_t(i, h);
00278             }
00279           node_at_level[h] = false;
00280           return m;
00281         }
00282 
00283 
00284         unsigned n_level_roots() const
00285         {
00286           return father.size();
00287         }
00288 
00289       }; // end of struct basic_salembier
00290 
00291 
00292     } // end of namespace oln::lrde::ufmt
00293 
00294   } // end of namespace oln::lrde
00295 
00296 } // end of namespace oln
00297 
00298 
00299 #endif // ! OLENA_LRDE_UFMT_BASIC_SALEMBIER_HH

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