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 #ifndef MLN_MAKE_REGION_ADJACENCY_GRAPH_HH
00027 # define MLN_MAKE_REGION_ADJACENCY_GRAPH_HH
00028
00036
00037 # include <mln/core/concept/image.hh>
00038 # include <mln/core/concept/neighborhood.hh>
00039 # include <mln/core/image/image2d.hh>
00040 # include <mln/core/alias/box2d.hh>
00041 # include <mln/extension/adjust_fill.hh>
00042 # include <mln/util/graph.hh>
00043 # include <mln/util/adjacency_matrix.hh>
00044
00045
00046 namespace mln
00047 {
00048
00049 namespace make
00050 {
00051
00059 template <typename I, typename N>
00060 util::graph
00061 region_adjacency_graph(const Image<I>& wshd_,
00062 const Neighborhood<N>& nbh,
00063 const mln_value(I)& nbasins);
00064
00065
00066
00067 # ifndef MLN_INCLUDE_ONLY
00068
00069
00070 namespace internal
00071 {
00072
00073 template <typename I, typename N>
00074 void
00075 region_adjacency_graph_tests(const Image<I>& wshd,
00076 const Neighborhood<N>& nbh,
00077 const mln_value(I)&)
00078 {
00079 mln_precondition(exact(wshd).is_valid());
00080 mln_precondition(exact(nbh).is_valid());
00081 (void) wshd;
00082 (void) nbh;
00083 }
00084
00085 }
00086
00087
00088 namespace impl
00089 {
00090
00091 namespace generic
00092 {
00093
00094 template <typename I, typename N>
00095 util::graph
00096 region_adjacency_graph(const Image<I>& wshd_,
00097 const Neighborhood<N>& nbh_,
00098 const mln_value(I)& nbasins)
00099 {
00100 trace::entering("make::impl::generic::region_adjacency_graph");
00101
00102 internal::region_adjacency_graph_tests(wshd_, nbh_, nbasins);
00103 const I& wshd = exact(wshd_);
00104 const N& nbh = exact(nbh_);
00105
00106 util::adjacency_matrix<> adj(nbasins.next());
00107 extension::adjust_fill(wshd, nbh, 0u);
00108
00109 typedef mln_value(I) L;
00110 L l1, l2;
00111 mln_piter(I) p(wshd.domain());
00112 mln_niter(N) n(nbh, p);
00113 for_all(p)
00114 {
00115 if (wshd(p) != 0u)
00116 continue;
00117
00118 l1 = l2 = 0;
00119 for_all(n)
00120 if (wshd.has(n) && wshd(n) != 0u)
00121 {
00122 if (l1 == 0u)
00123 l1 = wshd(n);
00124 else
00125 if (wshd(n) != l1)
00126 {
00127 mln_invariant(l2 == 0u);
00128 l2 = wshd(n);
00129 break;
00130 }
00131 }
00132 if (l2 == 0u || l1 == 0u)
00133 continue;
00134
00135
00136 adj.add(l2, l1);
00137 }
00138
00139
00140 util::graph g;
00141 g.add_vertices(nbasins.next());
00142 for (unsigned i = 1; i < nbasins.next(); ++i)
00143 for (unsigned j = 1; j < i; ++j)
00144 if (adj.are_adjacent(i, j))
00145 g.add_edge(i, j);
00146
00147
00148 trace::exiting("make::impl::generic::region_adjacency_graph");
00149 return g;
00150 }
00151
00152 }
00153
00154 }
00155
00156
00157
00158 namespace internal
00159 {
00160
00161 template <typename I, typename N>
00162 util::graph
00163 region_adjacency_graph_dispatch(const Image<I>& wshd,
00164 const Neighborhood<N>& nbh,
00165 const mln_value(I)& nbasins)
00166 {
00167 return make::impl::generic::region_adjacency_graph(wshd, nbh, nbasins);
00168 }
00169
00170 }
00171
00172
00173
00174
00175
00176 template <typename I, typename N>
00177 inline
00178 util::graph
00179 region_adjacency_graph(const Image<I>& wshd,
00180 const Neighborhood<N>& nbh,
00181 const mln_value(I)& nbasins)
00182 {
00183 trace::entering("make::region_adjacency_graph");
00184
00185 internal::region_adjacency_graph_tests(wshd, nbh, nbasins);
00186
00187 util::graph g = internal::region_adjacency_graph_dispatch(wshd, nbh, nbasins);
00188
00189 trace::exiting("make::region_adjacency_graph");
00190 return g;
00191 }
00192
00193
00194 # endif // ! MLN_INCLUDE_ONLY
00195
00196
00197 }
00198
00199 }
00200
00201
00202 #endif // ! MLN_MAKE_REGION_ADJACENCY_GRAPH_HH