00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
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       } 
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         
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: 
00174             return internal::nb_connexity_c4[res];
00175           case 8: 
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: 
00207             return internal::nb_connexity_c4[res];
00208           case 8: 
00209             return internal::nb_connexity_c8[res];
00210           default:
00211             mln_assertion(0);
00212 
00213         }
00214         return 0;
00215       }
00216 
00217 
00218       template <typename N>
00219       template <typename I>
00220       inline
00221       bool
00222       is_simple_point<N>::check(const I& ima,
00223                                 const mln_psite(I)& p) const
00224       {
00225         mln_precondition(ima.is_valid());
00226         return (nb_connexity2d(ima, nbh_.foreground(), p, true) == 1)  
00227           && (nb_connexity2d(ima, nbh_.background(), p, false) == 1); 
00228       }
00229 
00230 
00231 
00232 
00233       template <typename N>
00234       template <typename I>
00235       inline
00236       bool
00237       is_simple_point<N>::check__(const I& ima,
00238                                   unsigned p) const
00239       {
00240         mln_precondition(ima.is_valid());
00241         return (nb_connexity2d__(ima, nbh_.foreground(), p, true) == 1)  
00242           && (nb_connexity2d__(ima, nbh_.background(), p, false) == 1); 
00243       }
00244 
00245 
00246 # endif // MLN_TOPO_SKELETON_INCLUDE_ONLY
00247 
00248     } 
00249 
00250   } 
00251 
00252 } 
00253 
00254 #endif // ! MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH