Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 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> // FIXME: We may have some dep trouble with this include. 00046 # include <mln/literal/zero.hh> 00047 # include <mln/convert/to.hh> 00048 00049 00050 namespace mln 00051 { 00052 00053 // Forward declarations. 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 } // end of namespace mln::convert::over_load 00077 00078 } // end of namespace mln::convert 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 // Same traits as its corresponding window. 00088 }; 00089 00090 } // end of namespace mln::trait 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 // with_w_<It,W> 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 // w_window<D,W> 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)) // FIXME: Implicit restriction "W scalar"... 00260 // no-op 00261 return *this; 00262 00263 // memorization: d_i -> w_i 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 // insertion of d and w: 00269 win_.insert(d); 00270 memo_wei_[d] = w; 00271 00272 // re-mapping: w_i <- d_i 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 // convert::from_to_ 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 // data::fill(ima, literal::zero) is: 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 // FIXME: Sample code (below) to generalize the code above: 00365 00366 // template <typename W> 00367 // inline 00368 // mln_image_from(W, mln_weight(W)) to_image(const Weighted_Window<W>& w_win_) 00369 // { 00370 // const W& w_win = exact(w_win_); 00371 // mln_precondition(! w_win.is_empty()); 00372 00373 // typedef mln_psite(W) P; 00374 // box<P> b = geom::bbox(w_win); 00375 // mln_image_from(W, mln_weight(W)) ima(b); 00376 // // Fill the image with zeros, as (weighted) windows are not 00377 // // necessarily box-shaped (there might be holes corresponding to 00378 // // null weights). 00379 // data::fill(ima, literal::zero); 00380 // P O = P::origin; 00381 // mln_qiter(W) q(w_win, O); 00382 // for_all(q) 00383 // ima(q) = q.w(); 00384 // return ima; 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 } // end of namespace mln::convert::over_load 00412 00413 } // end of namespace mln::convert 00414 00415 00416 // operators 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 } // end of namespace mln 00448 00449 00450 # include <mln/make/w_window.hh> 00451 00452 00453 #endif // ! MLN_CORE_W_WINDOW_HH