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_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
00027 # define MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
00028
00032
00033 # include <mln/extension/adjust.hh>
00034 # include <mln/canvas/distance_geodesic.hh>
00035 # include <mln/transform/internal/influence_zone_functor.hh>
00036
00037
00038 namespace mln
00039 {
00040
00041 namespace transform
00042 {
00043
00050
00051 template <typename I, typename N>
00052 mln_concrete(I)
00053 influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh);
00054
00055
00056
00057 # ifndef MLN_INCLUDE_ONLY
00058
00059
00060 namespace internal
00061 {
00062
00063 template <typename I, typename N>
00064 void
00065 influence_zone_geodesic_tests(const Image<I>& input,
00066 const Neighborhood<N>& nbh)
00067 {
00068 mln_precondition(exact(input).is_valid());
00069 mln_precondition(exact(nbh).is_valid());
00070
00071 (void) input;
00072 (void) nbh;
00073 }
00074
00075 }
00076
00077
00078 namespace impl
00079 {
00080
00081 namespace generic
00082 {
00083
00084 template <typename I, typename N>
00085 mln_concrete(I)
00086 influence_zone_geodesic(const Image<I>& input,
00087 const Neighborhood<N>& nbh)
00088 {
00089
00090 mlc_abort(I)::check();
00091 }
00092
00093 }
00094
00095
00096 template <typename I, typename N>
00097 mln_concrete(I)
00098 influence_zone_geodesic_fastest(const Image<I>& input_,
00099 const Neighborhood<N>& nbh_)
00100 {
00101 trace::entering("transform::impl::influence_zone_geodesic_fastest");
00102
00103 const I& input = exact(input_);
00104 const N& nbh = exact(nbh_);
00105
00106 internal::influence_zone_geodesic_tests(input, nbh);
00107 mln_precondition(input.domain().pmin() == literal::origin);
00108
00109 std::queue<mln_value(I)*> q;
00110 mln_concrete(I) output;
00111
00112 util::array<int> dp = offsets_wrt(input, nbh);
00113 const unsigned n_nbhs = dp.nelements();
00114 const unsigned
00115 ncols = input.ncols(),
00116 first_offset = input.border() * (ncols + 2 * input.border() + 1);
00117
00118
00119 {
00120 extension::adjust(input, nbh);
00121 output = duplicate(input);
00122
00123 extension::fill(input, 0);
00124 extension::fill(output, 1);
00125
00126 const unsigned nelts = input.nelements();
00127 const mln_value(I)* p_i = & input.at_(0, 0);
00128 mln_value(I)* p_o = & output.at_(0, 0);
00129 for (unsigned i = first_offset; i < nelts; ++i, ++p_i, ++p_o)
00130 {
00131 if (*p_i == 0)
00132 continue;
00133 for (unsigned j = 0; j < n_nbhs; ++j)
00134 {
00135 const mln_value(I)* n_i = p_i + dp[j];
00136 if (*n_i == 0)
00137 {
00138 q.push(p_o);
00139 break;
00140 }
00141 }
00142 }
00143
00144 }
00145
00146
00147 {
00148 mln_value(I)* ptr;
00149
00150 while (! q.empty())
00151 {
00152 ptr = q.front();
00153 q.pop();
00154 mln_invariant(*ptr != 0);
00155 for (unsigned j = 0; j < n_nbhs; ++j)
00156 {
00157 mln_value(I)* ntr = ptr + dp[j];
00158 if (*ntr == 0)
00159 {
00160 *ntr = *ptr;
00161 q.push(ntr);
00162 }
00163 }
00164 }
00165 }
00166
00167 trace::exiting("transform::impl::influence_zone_geodesic_fastest");
00168 return output;
00169 }
00170
00171
00172 }
00173
00174
00175 namespace internal
00176 {
00177
00178 template <typename I, typename N>
00179 mln_concrete(I)
00180 influence_zone_geodesic_dispatch(trait::image::value_alignment::any,
00181 trait::image::value_storage::any,
00182 trait::image::value_access::any,
00183 const I& input,
00184 const N& nbh)
00185 {
00186 return impl::generic::influence_zone_geodesic(input, nbh);
00187 }
00188
00189
00190 template <typename I, typename N>
00191 mln_concrete(I)
00192 influence_zone_geodesic_dispatch(trait::image::value_alignment::with_grid,
00193 trait::image::value_storage::one_block,
00194 trait::image::value_access::direct,
00195 const I& input,
00196 const N& nbh)
00197 {
00198 return impl::influence_zone_geodesic_fastest(input, nbh);
00199 }
00200
00201
00202 template <typename I, typename N>
00203 mln_concrete(I)
00204 influence_zone_geodesic_dispatch(const Image<I>& input,
00205 const Neighborhood<N>& nbh)
00206 {
00207 return
00208 influence_zone_geodesic_dispatch(mln_trait_image_value_alignment(I)(),
00209 mln_trait_image_value_storage(I)(),
00210 mln_trait_image_value_access(I)(),
00211 exact(input), exact(nbh));
00212 }
00213
00214 }
00215
00216
00217 template <typename I, typename N>
00218 mln_concrete(I)
00219 influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh)
00220 {
00221 trace::entering("transform::influence_zone_geodesic");
00222
00223 internal::influence_zone_geodesic_tests(input, nbh);
00224
00225 mln_concrete(I)
00226 output = internal::influence_zone_geodesic_dispatch(input, nbh);
00227
00228 trace::exiting("transform::influence_zone_geodesic");
00229 return output;
00230 }
00231
00232 # endif // ! MLN_INCLUDE_ONLY
00233
00234 }
00235
00236 }
00237
00238
00239 #endif // ! MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH