Milena (Olena)  User documentation 2.0a Id
is_simple_point.hh
00001 // Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
00002 // (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_TOPO_SKELETON_IS_SIMPLE_POINT_HH
00028 # define MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH
00029 
00037 
00038 # include <mln/core/concept/image.hh>
00039 # include <mln/core/alias/point2d.hh>
00040 # include <mln/core/alias/neighb2d.hh>
00041 
00042 namespace mln
00043 {
00044 
00045   namespace topo
00046   {
00047 
00048     namespace skeleton
00049     {
00050 
00067       template <typename N>
00068       struct is_simple_point
00069       {
00070 
00071         is_simple_point(const Neighborhood<N>& nbh);
00072 
00073         template <typename I>
00074         bool check(const I& ima, const mln_psite(I)& p) const;
00075         template <typename I>
00076         bool check__(const I& ima, unsigned p) const;
00077 
00078       protected:
00079         const N& nbh_;
00080         bool is_c8_;
00081 
00082         template <typename I, typename N2>
00083         unsigned nb_connexity2d(const I&, const N2 nbh,
00084                                 const mln_psite(I)& p, bool object) const;
00085         template <typename I, typename N2>
00086         unsigned nb_connexity2d__(const I&, const N2 nbh,
00087                                   unsigned p, bool object) const;
00088 
00089       };
00090 
00091 # ifndef MLN_INCLUDE_ONLY
00092 
00093 
00094       namespace internal
00095       {
00096         static const unsigned char nb_connexity_c8[256] =
00097         {
00098           0,  1,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   2,  2,  1,  1,
00099           1,  2,  1,  1,   1,  2,  1,  1,   2,  2,  1,  1,   2,  2,  1,  1,
00100           1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00101           2,  3,  2,  2,   2,  3,  2,  2,   2,  2,  1,  1,   2,  2,  1,  1,
00102 
00103           1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00104           1,  2,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
00105           1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00106           1,  2,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
00107 
00108           1,  2,  2,  2,   2,  3,  2,  2,   2,  2,  2,  2,   3,  3,  2,  2,
00109           1,  2,  1,  1,   1,  2,  1,  1,   2,  2,  1,  1,   2,  2,  1,  1,
00110           2,  3,  3,  3,   3,  4,  3,  3,   2,  2,  2,  2,   3,  3,  2,  2,
00111           2,  3,  2,  2,   2,  3,  2,  2,   2,  2,  1,  1,   2,  2,  1,  1,
00112 
00113           1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00114           1,  2,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
00115           1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00116           1,  2,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1
00117         };
00118 
00119         static const unsigned char nb_connexity_c4[256] =
00120         {
00121           0,  0,  1,  1,   0,  0,  1,  1,   1,  1,  2,  1,   1,  1,  2,  1,
00122           1,  1,  2,  2,   1,  1,  1,  1,   2,  2,  3,  2,   2,  2,  2,  1,
00123           0,  0,  1,  1,   0,  0,  1,  1,   1,  1,  2,  1,   1,  1,  2,  1,
00124           1,  1,  2,  2,   1,  1,  1,  1,   2,  2,  3,  2,   2,  2,  2,  1,
00125 
00126           1,  1,  2,  2,   1,  1,  2,  2,   2,  2,  3,  2,   2,  2,  3,  2,
00127           2,  2,  3,  3,   2,  2,  2,  2,   3,  3,  4,  3,   3,  3,  3,  2,
00128           1,  1,  2,  2,   1,  1,  2,  2,   1,  1,  2,  1,   1,  1,  2,  1,
00129           2,  2,  3,  3,   2,  2,  2,  2,   2,  2,  3,  2,   2,  2,  2,  1,
00130 
00131           0,  0,  1,  1,   0,  0,  1,  1,   1,  1,  2,  1,   1,  1,  2,  1,
00132           1,  1,  2,  2,   1,  1,  1,  1,   2,  2,  3,  2,   2,  2,  2,  1,
00133           0,  0,  1,  1,   0,  0,  1,  1,   1,  1,  2,  1,   1,  1,  2,  1,
00134           1,  1,  2,  2,   1,  1,  1,  1,   2,  2,  3,  2,   2,  2,  2,  1,
00135 
00136           1,  1,  2,  2,   1,  1,  2,  2,   2,  2,  3,  2,   2,  2,  3,  2,
00137           1,  1,  2,  2,   1,  1,  1,  1,   2,  2,  3,  2,   2,  2,  2,  1,
00138           1,  1,  2,  2,   1,  1,  2,  2,   1,  1,  2,  1,   1,  1,  2,  1,
00139           1,  1,  2,  2,   1,  1,  1,  1,   1,  1,  2,  1,   1,  1,  1,  1
00140         };
00141 
00142       } // end of namespace internal
00143 
00144       template <typename N>
00145       is_simple_point<N>::is_simple_point(const Neighborhood<N>& nbh)
00146         : nbh_(exact(nbh))
00147       {
00148         mln_precondition(nbh_.is_valid());
00149       }
00150 
00151 
00152       template <typename N>
00153       template <typename I, typename N2>
00154       unsigned
00155       is_simple_point<N>::nb_connexity2d(const I& ima,
00156                                          const N2 nbh,
00157                                          const mln_psite(I)& p,
00158                                          bool object) const
00159       {
00160         unsigned res = 0;
00161 
00162         // Note: bkd here but fwd in is_simple_2d.hh...
00163         mln_bkd_niter(N2) n(c8(), p);
00164         for_all(n)
00165         {
00166           res = (res << 1);
00167           if (ima.domain().has(n) && ima(n) == object)
00168             res = res | 1;
00169         }
00170 
00171         switch (nbh.size())
00172         {
00173           case 4: // C4
00174             return internal::nb_connexity_c4[res];
00175           case 8: // C8
00176             return internal::nb_connexity_c8[res];
00177           default:
00178             mln_assertion(0);
00179 
00180         }
00181       }
00182 
00183 
00184       template <typename N>
00185       template <typename I, typename N2>
00186       unsigned
00187       is_simple_point<N>::nb_connexity2d__(const I& ima,
00188                                            const N2 nbh,
00189                                            unsigned p,
00190                                            bool object) const
00191       {
00192         unsigned res = 0;
00193 
00194         static util::array<int>
00195           noffset = mln::offsets_wrt(ima, c8());
00196 
00197         for (int i = noffset.nelements() - 1; i >= 0; --i)
00198         {
00199           res = (res << 1);
00200           if (ima.element(p + noffset[i]) == object)
00201             res = res | 1;
00202         }
00203 
00204         switch (nbh.size())
00205         {
00206           case 4: // C4
00207             return internal::nb_connexity_c4[res];
00208           case 8: // C8
00209             return internal::nb_connexity_c8[res];
00210           default:
00211             mln_assertion(0);
00212         }
00213         return 0;
00214       }
00215 
00216 
00217       template <typename N>
00218       template <typename I>
00219       inline
00220       bool
00221       is_simple_point<N>::check(const I& ima,
00222                                 const mln_psite(I)& p) const
00223       {
00224         mln_precondition(ima.is_valid());
00225         return (nb_connexity2d(ima, nbh_.foreground(), p, true) == 1)  // Consider neighbor.
00226           && (nb_connexity2d(ima, nbh_.background(), p, false) == 1); // Consider complement neighbor.
00227       }
00228 
00229 
00230 
00231 
00232       template <typename N>
00233       template <typename I>
00234       inline
00235       bool
00236       is_simple_point<N>::check__(const I& ima,
00237                                   unsigned p) const
00238       {
00239         mln_precondition(ima.is_valid());
00240         return (nb_connexity2d__(ima, nbh_.foreground(), p, true) == 1)  // Consider neighbor
00241           && (nb_connexity2d__(ima, nbh_.background(), p, false) == 1); // Consider complement neighbor.
00242       }
00243 
00244 
00245 # endif // MLN_TOPO_SKELETON_INCLUDE_ONLY
00246 
00247     } // end of namespace mln::topo::skeleton
00248 
00249   } // end of namespace mln::topo
00250 
00251 } // end of namespace mln
00252 
00253 #endif // ! MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH
 All Classes Namespaces Functions Variables Typedefs Enumerator