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_IS_SIMPLE_2D_HH
00028 # define MLN_TOPO_IS_SIMPLE_2D_HH
00029 
00034 
00038 
00039 
00040 #include <mln/core/concept/image.hh>
00041 #include <mln/core/concept/neighborhood.hh>
00042 
00043 #include <mln/core/alias/point2d.hh>
00044 #include <mln/core/alias/neighb2d.hh>
00045 
00046 
00047 namespace mln
00048 {
00049 
00050   namespace topo
00051   {
00052 
00065     template <typename N>
00066     struct is_simple_2d_t
00067     {
00068 
00069       is_simple_2d_t(const Neighborhood<N>& nbh);
00070 
00071       template <typename I>
00072       bool check(const I& ima, const mln_psite(I)& p) const;
00073 
00074       template <typename I>
00075       bool check__(const I& ima, unsigned p) const;
00076 
00077       template <typename I, typename N2>
00078       unsigned nb_connectivity2d(const I&, const N2& nbh,
00079                                  const mln_psite(I)& p, bool object) const;
00080       template <typename I, typename N2>
00081       unsigned nb_connectivity2d__(const I&, const N2& nbh,
00082                                    unsigned p, bool object) const;
00083 
00084     protected:
00085       const N& nbh_;
00086     };
00087 
00088 
00089 
00090 # ifndef MLN_INCLUDE_ONLY
00091 
00092     namespace internal
00093     {
00094 
00095       static const unsigned char connectivity_number_c8[256] =
00096       {
00097         0,  1,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   2,  2,  1,  1,
00098         1,  2,  1,  1,   1,  2,  1,  1,   2,  2,  1,  1,   2,  2,  1,  1,
00099         1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00100         2,  3,  2,  2,   2,  3,  2,  2,   2,  2,  1,  1,   2,  2,  1,  1,
00101 
00102         1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00103         1,  2,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
00104         1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00105         1,  2,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
00106 
00107         1,  2,  2,  2,   2,  3,  2,  2,   2,  2,  2,  2,   3,  3,  2,  2,
00108         1,  2,  1,  1,   1,  2,  1,  1,   2,  2,  1,  1,   2,  2,  1,  1,
00109         2,  3,  3,  3,   3,  4,  3,  3,   2,  2,  2,  2,   3,  3,  2,  2,
00110         2,  3,  2,  2,   2,  3,  2,  2,   2,  2,  1,  1,   2,  2,  1,  1,
00111 
00112         1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00113         1,  2,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
00114         1,  2,  2,  2,   2,  3,  2,  2,   1,  1,  1,  1,   2,  2,  1,  1,
00115         1,  2,  1,  1,   1,  2,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1
00116       };
00117 
00118 
00119       static const unsigned char connectivity_number_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_2d_t<N>::is_simple_2d_t(const Neighborhood<N>& nbh)
00146       : nbh_(exact(nbh))
00147     {
00148       mln_precondition(nbh_.is_valid());
00149     }
00150 
00151 
00152 
00153     template <typename N>
00154     template <typename I, typename N2>
00155     unsigned
00156     is_simple_2d_t<N>::nb_connectivity2d(const I& ima, const N2& nbh,
00157                                          const mln_psite(I)& p, bool b) const
00158     {
00159       mln_precondition(ima.is_valid());
00160       mln_precondition(nbh.is_valid());
00161 
00162       unsigned res = 0;
00163 
00164       
00165       mln_fwd_niter(N2) n(c8(), p);
00166       for_all(n)
00167       {
00168         res = (res << 1);
00169         if (ima.has(n) && ima(n) == b)
00170           res = res | 1;
00171       }
00172 
00173       switch (nbh.size())
00174       {
00175         case 4: 
00176           return internal::connectivity_number_c4[res];
00177         case 8: 
00178           return internal::connectivity_number_c8[res];
00179         default:
00180           mln_assertion(0);
00181 
00182       }
00183 
00184       return 0;
00185     }
00186 
00187 
00188     template <typename N>
00189     template <typename I, typename N2>
00190     unsigned
00191     is_simple_2d_t<N>::nb_connectivity2d__(const I& ima, const N2& nbh,
00192                                            unsigned p, bool b) const
00193     {
00194       mln_precondition(ima.is_valid());
00195       mln_precondition(nbh.is_valid());
00196 
00197       unsigned res = 0;
00198 
00199       static util::array<int>
00200         noffset = mln::offsets_wrt(ima, c8());
00201 
00202       for (unsigned i = 0; i < noffset.nelements(); ++i)
00203       {
00204         res = (res << 1);
00205         if (ima.element(p + noffset[i]) == b)
00206           res = res | 1;
00207       }
00208 
00209       switch (nbh.size())
00210       {
00211         case 4: 
00212           return internal::connectivity_number_c4[res];
00213         case 8: 
00214           return internal::connectivity_number_c8[res];
00215         default:
00216           mln_assertion(0);
00217 
00218       }
00219 
00220       return 0;
00221     }
00222 
00223 
00224     template <typename N>
00225     template <typename I>
00226     inline
00227     bool
00228     is_simple_2d_t<N>::check(const I& ima, const mln_psite(I)& p) const
00229     {
00230       mln_precondition(ima.is_valid());
00231       return (nb_connectivity2d(ima, nbh_.foreground(), p, true) == 1)  
00232         && (nb_connectivity2d(ima, nbh_.background(), p, false) == 1); 
00233     }
00234 
00235 
00236 
00237 
00238     template <typename N>
00239     template <typename I>
00240     inline
00241     bool
00242     is_simple_2d_t<N>::check__(const I& ima, unsigned p) const
00243     {
00244       mln_precondition(ima.is_valid());
00245       return (nb_connectivity2d__(ima, nbh_.foreground(), p, true) == 1)  
00246         && (nb_connectivity2d__(ima, nbh_.background(), p, false) == 1); 
00247     }
00248 
00249 
00250 
00251 # endif // MLN_INCLUDE_ONLY
00252 
00253   } 
00254 
00255 } 
00256 
00257 #endif // ! MLN_TOPO_IS_SIMPLE_2D_HH