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_CORE_W_WINDOW_HH
00027 # define MLN_CORE_W_WINDOW_HH
00028
00034
00035 # include <map>
00036
00037 # include <mln/core/internal/weighted_window_base.hh>
00038 # include <mln/core/concept/image.hh>
00039 # include <mln/core/site_set/box.hh>
00040 # include <mln/core/window.hh>
00041 # include <mln/core/dpsites_piter.hh>
00042
00043 # include <mln/value/ops.hh>
00044 # include <mln/util/ord.hh>
00045 # include <mln/geom/bbox.hh>
00046 # include <mln/literal/zero.hh>
00047 # include <mln/convert/to.hh>
00048
00049
00050 namespace mln
00051 {
00052
00053
00054 template <typename D, typename W> struct w_window;
00055 template <typename It, typename W> struct with_w_;
00056
00057
00058 namespace convert
00059 {
00060
00061 namespace over_load
00062 {
00063
00064 template <typename I, typename D, typename W>
00065 void
00066 from_to_(const Image<I>& from, w_window<D,W>& to);
00067
00068 template <typename D, typename W, typename I>
00069 void
00070 from_to_(const w_window<D,W>& from, Image<I>& to);
00071
00072 template <typename V, unsigned S, typename D, typename W>
00073 void
00074 from_to_(const V (&weight)[S], w_window<D,W>& to);
00075
00076 }
00077
00078 }
00079
00080
00081 namespace trait
00082 {
00083
00084 template <typename D, typename W>
00085 struct window_< mln::w_window<D,W> > : window_< mln::window<D> >
00086 {
00087
00088 };
00089
00090 }
00091
00092
00099 template <typename D, typename W>
00100 struct w_window : public internal::weighted_window_base< mln::window<D>,
00101 w_window<D,W> >
00102 {
00104 typedef D dpsite;
00105
00107 typedef W weight;
00108
00109
00111 typedef with_w_< dpsites_fwd_piter< w_window<D, W> >, W > fwd_qiter;
00112
00114 typedef with_w_< dpsites_bkd_piter< w_window<D, W> >, W > bkd_qiter;
00115
00116
00118 w_window();
00119
00120
00122 w_window<D,W>& insert(const W& w, const D& d);
00123
00124
00126 W w(unsigned i) const;
00127
00129 const std::vector<W>& weights() const;
00130
00131
00133 const std::vector<D>& std_vector() const;
00134
00136 const mln::window<D>& win() const;
00137
00138
00140 bool is_symmetric() const;
00141
00143 void sym();
00144
00146 void clear();
00147
00148 protected:
00149
00150 mln::window<D> win_;
00151 std::vector<W> wei_;
00152 };
00153
00154
00157 template <typename D, typename W>
00158 std::ostream& operator<<(std::ostream& ostr, const w_window<D,W>& w_win);
00159
00160
00163 template <typename D, typename Wl, typename Wr>
00164 bool operator==(const w_window<D,Wl>& lhs, const w_window<D,Wr>& rhs);
00165
00166
00167
00169 template <typename It, typename W>
00170 struct with_w_ : public It
00171 {
00172
00173 template <typename Ds, typename P>
00174 with_w_(const Ds& ds, const P& p);
00175
00176 W w() const;
00177
00178 protected:
00179 const std::vector<W> wei_;
00180 };
00181
00182
00183
00184 # ifndef MLN_INCLUDE_ONLY
00185
00186
00187
00188
00189 template <typename It, typename W>
00190 template <typename Ds, typename P>
00191 inline
00192 with_w_<It,W>::with_w_(const Ds& ds,
00193 const P& p)
00194 : It(ds, p),
00195 wei_(ds.weights())
00196 {
00197 }
00198
00199 template <typename It, typename W>
00200 inline
00201 W
00202 with_w_<It,W>::w() const
00203 {
00204 mln_precondition(this->i_ < wei_.size());
00205 return wei_[this->i_];
00206 }
00207
00208
00209
00210
00211 template <typename D, typename W>
00212 inline
00213 w_window<D,W>::w_window()
00214 {
00215 }
00216
00217 template <typename D, typename W>
00218 inline
00219 const mln::window<D>&
00220 w_window<D,W>::win() const
00221 {
00222 return win_;
00223 }
00224
00225 template <typename D, typename W>
00226 inline
00227 const std::vector<D>&
00228 w_window<D,W>::std_vector() const
00229 {
00230 return win_.std_vector();
00231 }
00232
00233 template <typename D, typename W>
00234 inline
00235 const std::vector<W>&
00236 w_window<D,W>::weights() const
00237 {
00238 return wei_;
00239 }
00240
00241 template <typename D, typename W>
00242 inline
00243 W
00244 w_window<D,W>::w(unsigned i) const
00245 {
00246 mln_precondition(i < wei_.size());
00247 mln_invariant(wei_.size() == win_.size());
00248 return wei_[i];
00249 }
00250
00251 template <typename D, typename W>
00252 inline
00253 w_window<D,W>&
00254 w_window<D,W>::insert(const W& w, const D& d)
00255 {
00256 mln_invariant(wei_.size() == win_.size());
00257 mln_precondition(! win_.has(d));
00258
00259 if (w == W(0))
00260
00261 return *this;
00262
00263
00264 std::map<D, W, util::ord<D> > memo_wei_;
00265 for (unsigned i = 0; i < win_.size(); ++i)
00266 memo_wei_[win_.dp(i)] = wei_[i];
00267
00268
00269 win_.insert(d);
00270 memo_wei_[d] = w;
00271
00272
00273 wei_.resize(win_.size());
00274 for (unsigned i = 0; i < win_.size(); ++i)
00275 wei_[i] = memo_wei_[win_.dp(i)];
00276
00277 mln_invariant(wei_.size() == win_.size());
00278 return *this;
00279 }
00280
00281 template <typename D, typename W>
00282 inline
00283 bool
00284 w_window<D,W>::is_symmetric() const
00285 {
00286 if (! win_.is_symmetric())
00287 return false;
00288 w_window<D,W> tmp;
00289 tmp.sym();
00290 return *this == tmp;
00291 }
00292
00293 template <typename D, typename W>
00294 inline
00295 void
00296 w_window<D,W>::sym()
00297 {
00298 w_window<D,W> tmp;
00299 unsigned n = this->size();
00300 for (unsigned i = 0; i < n; ++i)
00301 tmp.insert(this->w(i), - this->dp(i));
00302 *this = tmp;
00303 }
00304
00305 template <typename D, typename W>
00306 inline
00307 void
00308 w_window<D,W>::clear()
00309 {
00310 win_.clear();
00311 wei_.clear();
00312 }
00313
00314
00315
00316
00317 namespace convert
00318 {
00319
00320 namespace over_load
00321 {
00322
00323 template <typename I, typename D, typename W>
00324 void
00325 from_to_(const Image<I>& from_, w_window<D,W>& to)
00326 {
00327 mlc_converts_to(mln_deduce(I, psite, delta), D)::check();
00328 mlc_converts_to(mln_value(I), W)::check();
00329 const I& ima = exact(from_);
00330 to.clear();
00331 mln_value(I) zero = literal::zero;
00332 mln_piter(I) p(ima.domain());
00333 for_all(p)
00334 if (ima(p) != zero)
00335 to.insert(ima(p), convert::to<D>(p));
00336 }
00337
00338 template <typename D, typename W, typename I>
00339 void
00340 from_to_(const w_window<D,W>& w_win, Image<I>& ima_)
00341 {
00342 typedef mln_site(I) P;
00343 mlc_converts_to(D, mln_delta(P))::check();
00344 mlc_converts_to(W, mln_value(I))::check();
00345
00346 I& ima = exact(ima_);
00347 mln_precondition(! ima.is_valid());
00348 mln_precondition(w_win.is_valid());
00349
00350 ima.init_(geom::bbox(w_win));
00351 {
00352
00353 mln_value(I) zero = literal::zero;
00354 mln_piter(I) p(ima.domain());
00355 for_all(p)
00356 ima(p) = zero;
00357 }
00358
00359 unsigned n = w_win.size();
00360 for (unsigned i = 0; i < n; ++i)
00361 ima(convert::to<P>(w_win.dp(i))) = w_win.w(i);
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 template <typename V, unsigned S, typename D, typename W>
00388 void
00389 from_to_(const V (&weight)[S], w_window<D,W>& to)
00390 {
00391 mlc_bool(S != 0)::check();
00392 mlc_converts_to(V, W)::check();
00393 enum { d = D::dim,
00394 s = mlc_root(d,S)::value / 2 };
00395 metal::bool_<(mlc_pow_int(2 * s + 1, d) == S)>::check();
00396 to.clear();
00397 typedef mln_site(D) P;
00398 box<P> b(all_to(-s), all_to(+s));
00399 mln_fwd_piter(box<P>) p(b);
00400 unsigned i = 0;
00401 V zero = literal::zero;
00402 for_all(p)
00403 {
00404 if (weight[i] != zero)
00405 to.insert(weight[i], convert::to<D>(p));
00406 ++i;
00407 }
00408
00409 }
00410
00411 }
00412
00413 }
00414
00415
00416
00417
00418 template <typename D, typename W>
00419 inline
00420 std::ostream& operator<<(std::ostream& ostr, const w_window<D,W>& w_win)
00421 {
00422 ostr << '[';
00423 for (unsigned i = 0; i < w_win.win().size(); ++i)
00424 ostr << w_win.dp(i) << ':' << w_win.w(i) << ' ';
00425 return ostr << ']';
00426 }
00427
00428 template <typename D, typename Wl, typename Wr>
00429 inline
00430 bool operator==(const w_window<D,Wl>& lhs, const w_window<D,Wr>& rhs)
00431 {
00432 if (lhs.size() != rhs.size())
00433 return false;
00434 if (lhs.win() != rhs.win())
00435 return false;
00436 const std::vector<Wl>& wl = lhs.weights();
00437 const std::vector<Wr>& wr = rhs.weights();
00438 mln_assertion(wl.size() == wr.size());
00439 for (unsigned i = 0; i < wl.size(); ++i)
00440 if (wr[i] != wl[i])
00441 return false;
00442 return true;
00443 }
00444
00445 # endif // ! MLN_INCLUDE_ONLY
00446
00447 }
00448
00449
00450 # include <mln/make/w_window.hh>
00451
00452
00453 #endif // ! MLN_CORE_W_WINDOW_HH