attribute_closing_opening_map.hxx

00001 // Copyright (C) 2004  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, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, 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 namespace oln
00030 {
00031   namespace morpho
00032   {
00033     namespace slow
00034     {
00035       template <class I, class D, class Env>
00036       template <class N>
00037       f_tarjan_map<I, D, Env>::f_tarjan_map(bool is_closing,
00038                                             const typename f_tarjan_map<I, D, Env>::input_type& input,
00039                                             const abstract::neighborhood<N>& ng,
00040                                             const typename f_tarjan_map<I, D, Env>::lambda_type& lambda,
00041                                             const Env & env) :
00042         is_closing(is_closing),
00043         input(input),
00044         lambda(lambda),
00045         parent(input.size()),
00046         is_proc(input.size()),
00047         output(input.size()),
00048         env(env)
00049       {
00050         // init S and parent
00051         typedef typename std::vector<point_type> vector_type;
00052         vector_type S(input.npoints());
00053         if (is_closing)
00054           utils::distrib_sort(input, S);
00055         else
00056           utils::distrib_sort_inv(input, S);
00057 
00058         level::fill(parent, inactive());
00059         level::fill(is_proc, false);
00060 
00061         // array S contains sorted pixel list
00062         make_set(S[0]);
00063         is_proc[S[0]] = true;
00064 
00065         for (int ip = 1; ip < int(S.size()); ++ip)
00066           {
00067             point_type p = S[ip];
00068 
00069             // p_ is the pixel just processed before p
00070             point_type p_ = S[ip - 1];
00071             if (input[p] != input[p_])
00072               {
00073                 // for all the previous layer
00074                 for (int iq = ip - 1; iq >= 0; --iq)
00075                   {
00076                     point_type q = S[iq];
00077                     if (input[q] != input[p_])
00078                       break;
00079                     // if the attribute is 'reached', we do not need
00080                     // it anymore
00081                     if (parent[q] == active() && !(auxdata[q] < lambda))
00082                       {
00083                         parent[q] = inactive();
00084                         auxdata.erase(q);
00085                       }
00086                   }
00087               }
00088             make_set(p);
00089 
00090             oln_neighb_type(N) n(ng, p);
00091             for_all(n)
00092               if (input.hold(n) && is_proc[n])
00093                 do_union(n, p);
00094 
00095             is_proc[p] = true;
00096           }
00097 
00098         // resolving phase in reverse sort order
00099 
00100         for (int ip = int(S.size()) - 1; ip >= 0; --ip)
00101           {
00102             point_type p = S[ip];
00103             if (parent[p] == active() || parent[p] == inactive())
00104               output[p] = input[p];
00105             else
00106               output[p] = output[parent[p]];
00107           }
00108       }
00109 
00110       template <class I, class D, class Env>
00111       const typename f_tarjan_map<I, D, Env>::point_type
00112       f_tarjan_map<I, D, Env>::inactive()
00113       {
00114         static const point_type it = utils::internal::mk_point_looking_like<point_type>(-2);
00115         return it;
00116       }
00117 
00118       template <class I, class D, class Env>
00119       const typename f_tarjan_map<I, D, Env>::point_type
00120       f_tarjan_map<I, D, Env>::active()
00121       {
00122         static const point_type it = utils::internal::mk_point_looking_like<point_type>(-1);
00123         return it;
00124       }
00125 
00126       template <class I, class D, class Env>
00127       void
00128       f_tarjan_map<I, D, Env>::make_set(const typename f_tarjan_map<I, D, Env>::point_type& x)
00129       {
00130         precondition(parent[x] == inactive());
00131         parent[x] = active();
00132         auxdata[x] = D(input, x, env);
00133       }
00134 
00135       template <class I, class D, class Env>
00136       void
00137       f_tarjan_map<I, D, Env>::link(const typename f_tarjan_map<I, D, Env>::point_type& x,
00138                                     const typename f_tarjan_map<I, D, Env>::point_type& y)
00139       {
00140         if (parent[x] == active() && parent[y] == active())
00141           {
00142             auxdata[y] += auxdata[x];
00143             auxdata.erase(x);
00144           }
00145         else
00146           if (parent[x] == active())
00147             auxdata.erase(x);
00148           else
00149             {
00150               parent[y] = inactive();
00151               auxdata.erase(y);
00152             }
00153         parent[x] = y;
00154       }
00155 
00156       template <class I, class D, class Env>
00157       typename f_tarjan_map<I, D, Env>::point_type
00158       f_tarjan_map<I, D, Env>::find_root(const typename f_tarjan_map<I, D, Env>::point_type& x)
00159       {
00160         if (parent[x] != active() && parent[x] != inactive())
00161           {
00162             parent[x] = find_root(parent[x]);
00163             return parent[x];
00164           }
00165         return x;
00166       }
00167 
00168       template <class I, class D, class Env>
00169       bool
00170       f_tarjan_map<I, D, Env>::equiv(const typename f_tarjan_map<I, D, Env>::point_type& x,
00171                                      const typename f_tarjan_map<I, D, Env>::point_type& y) const
00172       {
00173         return input[x] == input[y] || parent[x] == active();
00174       }
00175 
00176       template <class I, class D, class Env>
00177       void
00178       f_tarjan_map<I, D, Env>::do_union(const typename f_tarjan_map<I, D, Env>::point_type& n,
00179                                         const typename f_tarjan_map<I, D, Env>::point_type& p)
00180       {
00181         point_type r = find_root(n);
00182         if (r != p)
00183           {
00184             if (equiv(r, p))
00185               link(r, p);
00186             else
00187               if (parent[p] == active())
00188                 {
00189                   parent[p] = inactive();
00190                   auxdata.erase(p);
00191                 }
00192           }
00193       }
00194     } // end of namespace slow
00195   } // end of namespace morpho
00196 } // end of namespace oln
00197 

Generated on Thu Apr 15 20:13:05 2004 for Olena by doxygen 1.3.6-20040222