hdx_maxtree.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_HDX_MAXTREE_HH
00029 # define OLENA_LRDE_UFMT_HDX_MAXTREE_HH
00030 
00031 # include <oln/level/fill.hh>
00032 # include <oln/lrde/ufmt/utils.hh>
00033 # include <oln/lrde/ufmt/ad_maxtree.hh>
00034 # include <oln/lrde/ufmt/attributes.hh>
00035 
00036 
00037 
00038 namespace oln
00039 {
00040 
00041   namespace lrde
00042   {
00043 
00044     namespace ufmt
00045     {
00046 
00047 
00048       // FIXME: make it more generic! and move it...
00049 
00050       template <class T>
00051       std::vector<int> to_index(const image2d<T>& input,
00052                                 const std::vector<dpoint2d>& dp_)
00053       {
00054         std::vector<int> dp(dp_.size());
00055         for (unsigned i = 0; i < dp_.size(); ++i)
00056           dp[i] = dp_[i].row() * (input.ncols() + 2 * input.border()) + dp_[i].col();
00057         return dp;
00058       }
00059 
00060 
00061 
00062 
00063       // FIXME: doc.
00064 
00065       template <class I>
00066       struct hdx_maxtree : public ad_maxtree<I>
00067       {
00068         typedef ad_maxtree<I> super;
00069         using super::f;
00070         using super::dpar;
00071         oln_lrde_ufmt_import_ad_maxtree_typedefs;
00072 
00073         const oln_neighborhood_type(I)& nbh;
00074 
00075         // aux data
00076         std::vector<int> S;
00077         std::vector<size_t> H;
00078         std::vector<oln_dpoint_type(I)> dp_pre_, dp_post_; // temp
00079         std::vector<int> dp_pre, dp_post;
00080         unsigned nb;
00081         unsigned nnodes;
00082 
00083         dparent_t c_dpar_; // proxied
00084         dpar_t c_dpar;     // proxy
00085 
00086         // ctor
00087 
00088         hdx_maxtree(const abstract::image<I>& f,
00089                        const oln_neighborhood_type(I)& nbh)
00090           :
00091           super(f),
00092           nbh(nbh),
00093           c_dpar_(f.size())
00094         {
00095           c_dpar.init(c_dpar_);
00096           c_dpar.memset_0();
00097         }
00098 
00099         void go()
00100         {
00101           init();
00102           compute_parent();  // 1st pass
00103 //        extract_maxtree(); // 2nd pass
00104         }
00105 
00106         void init()
00107         {
00108           S = histogram_reverse_sort_i(f.real(), H);
00109           nb = split<I>(nbh, dp_pre_, dp_post_);
00110           dp_pre  = to_index(f.real(), dp_pre_);
00111           dp_post = to_index(f.real(), dp_post_);
00112           nnodes = 1;
00113           dpar.memset_0();
00114         }
00115 
00116         void compute_parent()
00117         {
00118           int ip = 0;
00119           for (int h = uint_nvalues(f.real()) - 1; h >= 0; --h)
00120             {
00121               int ip_first = ip;
00122               int ip_last = ip + H[h];
00123 
00124               // union-find
00125 
00126               for (ip = ip_first; ip < ip_last; ++ip)
00127                 {
00128                   point p = S[ip];
00129                   // pre
00130                   for (unsigned i = 0; i < nb; ++i)
00131                     {
00132                       point n = p + dp_pre[i];
00133                       if (f[n] >= h)
00134                         do_adv_union(n, p);
00135                     }
00136                   // post
00137                   for (unsigned i = 0; i < nb; ++i)
00138                     {
00139                       point n = p + dp_post[i];
00140                       if (f[n] > h)
00141                         do_adv_union(n, p);
00142                     }
00143                 }
00144 
00145               // finalizing level compression
00146 
00147               for (int i = ip_last - 1; i >= ip_first; --i)
00148                 {
00149                   point p = S[i];
00150 //                if (is_root(p))
00151 //                  ++nnodes;
00152 //                else
00153                     c_dpar[p] += c_dpar[p + c_dpar[p]];
00154                 }
00155               
00156             } // end of "for all h"
00157         }
00158 
00159 
00160         point find_adv_root(point x)
00161         {
00162           if (is_root(x))
00163             return x;
00164           else
00165             {
00166               point lr = find_adv_root(x + c_dpar[x]);
00167               c_dpar[x] = lr - x;
00168               return lr;
00169             }
00170         }
00171 
00172         void do_adv_union(const point& n, const point& p)
00173         {
00174           point r = find_adv_root(n);
00175           if (r != p)
00176             {
00177               dpar[r] = p - r;
00178               c_dpar[r] = p - r;
00179               if (f[p] < f[r])
00180                 ++nnodes;
00181             }
00182         }
00183 
00184         template <class A> // A for attributes
00185         std::vector< node_<A> >
00186         extract_maxtree()
00187         {
00188           std::vector< node_<A> > node(nnodes);
00189           dpar_t& label = dpar;
00190 
00191           // bkd
00192           unsigned cur_l = nnodes - 1;
00193           for (int i = S.size() - 1; i != 0; --i)
00194             {
00195               point p = S[i];
00196               assert(is_level_root(p + dpar[p])); // level compression is total
00197               if (is_level_root(p))
00198                 {
00199                   // node initialization
00200                   point par_p = p + dpar[p]; // this value is saved
00201                   label[p] = cur_l; // because dpar[p] is modified here
00202                   node[cur_l].par = label[par_p]; // so this line is ok
00203                   if (is_root(p))
00204                     assert(node[cur_l].par == cur_l);
00205                   --cur_l;
00206                 }
00207               else
00208                 // label propagation
00209                 label[p] = label[p + dpar[p]];
00210             }
00211           return node;
00212         }
00213 
00214 
00215         template <class A> // A for attributes
00216         void compute_attributes(std::vector< node_<A> >& node)
00217           // point-wise version
00218         {
00219           dpar_t& label = dpar;
00220           for (int i = S.size() - 1; i != 0; --i)
00221             {
00222               point p = S[i];
00223               if (is_level_root(p))
00224                 node[label[p]].init(f, p);
00225               else
00226                 node[label[p]].insert(f, p);
00227             }
00228           for (int l = 0; l < nnodes; ++l)
00229             if (node[l].par != l) // not root node
00230               node[node[l].par].embrace(node[l]);
00231         }
00232 
00233 
00234 
00235       }; // end of class hdx_maxtree
00236 
00237 
00238 
00239     } // end of namespace oln::lrde::ufmt
00240 
00241   } // end of namespace oln::lrde
00242 
00243 } // end of namespace oln
00244 
00245 
00246 #endif // ! OLENA_LRDE_UFMT_HDX_MAXTREE_HH

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