Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2010 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_LABELING_COMPUTE_HH 00028 # define MLN_LABELING_COMPUTE_HH 00029 00047 00048 # include <mln/core/concept/image.hh> 00049 # include <mln/core/concept/accumulator.hh> 00050 # include <mln/core/concept/meta_accumulator.hh> 00051 # include <mln/util/array.hh> 00052 # include <mln/convert/from_to.hh> 00053 # include <mln/geom/ncols.hh> 00054 # include <mln/value/next.hh> 00055 00056 00057 namespace mln 00058 { 00059 00060 namespace labeling 00061 { 00062 00071 // 00072 template <typename A, typename I, typename L> 00073 util::array<mln_result(A)> 00074 compute(const Accumulator<A>& a, 00075 const Image<I>& input, 00076 const Image<L>& label, 00077 const mln_value(L)& nlabels); 00078 00079 00088 // 00089 template <typename A, typename I, typename L> 00090 util::array<mln_meta_accu_result(A, mln_value(I))> 00091 compute(const Meta_Accumulator<A>& a, 00092 const Image<I>& input, 00093 const Image<L>& label, 00094 const mln_value(L)& nlabels); 00095 00096 00104 // 00105 template <typename A, typename L> 00106 util::array<mln_result(A)> 00107 compute(const Accumulator<A>& a, 00108 const Image<L>& label, 00109 const mln_value(L)& nlabels); 00110 00111 00119 // 00120 template <typename A, typename L> 00121 util::array<mln_meta_accu_result(A, mln_psite(L))> 00122 compute(const Meta_Accumulator<A>& a, 00123 const Image<L>& label, 00124 const mln_value(L)& nlabels); 00125 00126 00135 // 00136 template <typename A, typename I, typename L> 00137 util::array<mln_result(A)> 00138 compute(util::array<A>& a, 00139 const Image<I>& input, 00140 const Image<L>& label, 00141 const mln_value(L)& nlabels); 00142 00143 00144 00145 # ifndef MLN_INCLUDE_ONLY 00146 00147 namespace internal 00148 { 00149 00150 template <typename A, typename L> 00151 inline 00152 void 00153 compute_tests(const Accumulator<A>& a, 00154 const Image<L>& label, 00155 const mln_value(L)& nlabels) 00156 { 00157 mln_precondition(exact(label).is_valid()); 00158 // mlc_is_a(mln_value(L), mln::value::Symbolic)::check(); 00159 (void) a; 00160 (void) label; 00161 (void) nlabels; 00162 } 00163 00164 00165 template <typename A, typename I, typename L> 00166 inline 00167 void 00168 compute_tests(const Accumulator<A>& a, 00169 const Image<I>& input, 00170 const Image<L>& label, 00171 const mln_value(L)& nlabels) 00172 { 00173 mln_precondition(exact(input).is_valid()); 00174 mln_precondition(exact(label).is_valid()); 00175 // mlc_is_a(mln_value(L), mln::value::Symbolic)::check(); 00176 (void) a; 00177 (void) input; 00178 (void) label; 00179 (void) nlabels; 00180 } 00181 00182 } // end of namespace mln::labeling::internal 00183 00184 00185 00186 namespace impl 00187 { 00188 00189 namespace generic 00190 { 00191 00192 00200 // 00201 template <typename A, typename L> 00202 inline 00203 util::array<mln_result(A)> 00204 compute(const Accumulator<A>& a_, 00205 const Image<L>& label_, 00206 const mln_value(L)& nlabels) 00207 { 00208 trace::entering("labeling::impl::generic::compute"); 00209 internal::compute_tests(a_, label_, nlabels); 00210 00211 const A& a = exact(a_); 00212 const L& label = exact(label_); 00213 00214 util::array<A> accus(value::next(nlabels), a); 00215 00216 mln_piter(L) p(label.domain()); 00217 for_all(p) 00218 accus[label(p)].take(p); 00219 00220 util::array<mln_result(A)> res; 00221 convert::from_to(accus, res); 00222 00223 trace::exiting("labeling::impl::generic::compute"); 00224 return res; 00225 } 00226 00237 // 00238 template <typename A, typename L> 00239 inline 00240 util::array<mln_result(A)> 00241 compute(util::array<A>& accus, 00242 const Image<L>& label_, 00243 const mln_value(L)& nlabels) 00244 { 00245 trace::entering("labeling::impl::generic::compute"); 00246 internal::compute_tests(A(), label_, nlabels); 00247 00248 if (value::next(nlabels) != accus.size()) 00249 { 00250 accus.resize(0); // Make sure all the accumulators are 00251 // re-initialized when resizing on next 00252 // line. 00253 accus.resize(value::next(nlabels)); 00254 } 00255 00256 const L& label = exact(label_); 00257 00258 mln_piter(L) p(label.domain()); 00259 for_all(p) 00260 accus[label(p)].take(p); 00261 00262 util::array<mln_result(A)> res; 00263 convert::from_to(accus, res); 00264 00265 trace::exiting("labeling::impl::generic::compute"); 00266 return res; 00267 } 00268 00269 00270 00279 // 00280 template <typename A, typename I, typename L> 00281 inline 00282 util::array<mln_result(A)> 00283 compute(const Accumulator<A>& a_, 00284 const Image<I>& input_, 00285 const Image<L>& label_, 00286 const mln_value(L)& nlabels) 00287 { 00288 trace::entering("labeling::impl::generic::compute"); 00289 internal::compute_tests(a_, input_, label_, nlabels); 00290 00291 const A& a = exact(a_); 00292 const I& input = exact(input_); 00293 const L& label = exact(label_); 00294 00295 util::array<A> accus(value::next(nlabels), a); 00296 00297 mln_piter(I) p(input.domain()); 00298 for_all(p) 00299 accus[label(p)].take(input(p)); 00300 00301 util::array<mln_result(A)> res; 00302 convert::from_to(accus, res); 00303 00304 trace::exiting("labeling::impl::generic::compute"); 00305 return res; 00306 } 00307 00308 00317 // 00318 template <typename A, typename I, typename L> 00319 inline 00320 util::array<mln_result(A)> 00321 compute(util::array<A>& accus, 00322 const Image<I>& input_, 00323 const Image<L>& label_, 00324 const mln_value(L)& nlabels) 00325 { 00326 trace::entering("labeling::impl::generic::compute"); 00327 //internal::compute_tests(a_, input_, label_, nlabels); 00328 00329 //const A& a = exact(a_); 00330 const I& input = exact(input_); 00331 const L& label = exact(label_); 00332 (void) nlabels; 00333 00334 if (value::next(nlabels) != accus.size()) 00335 { 00336 accus.resize(0); // Make sure all the accumulators are 00337 // re-initialized when resizing on next 00338 // line. 00339 accus.resize(value::next(nlabels)); 00340 } 00341 00342 mln_piter(I) p(input.domain()); 00343 for_all(p) 00344 accus[label(p)].take(input(p)); 00345 00346 util::array<mln_result(A)> res; 00347 convert::from_to(accus, res); 00348 00349 trace::exiting("labeling::impl::generic::compute"); 00350 return res; 00351 } 00352 00353 } // end of namespace mln::labeling::impl::generic 00354 00355 00356 00357 // FIXME: is there any optimization if border::get(input) == 00358 // border::get(label)) ? 00359 // 00360 00369 // 00370 template <typename A, typename I, typename L> 00371 inline 00372 util::array<mln_result(A)> 00373 compute_fastest(const Accumulator<A>& a_, 00374 const Image<I>& input_, 00375 const Image<L>& label_, 00376 const mln_value(L)& nlabels) 00377 { 00378 trace::entering("labeling::impl::compute_fastest"); 00379 internal::compute_tests(a_, input_, label_, nlabels); 00380 00381 const A& a = exact(a_); 00382 const I& input = exact(input_); 00383 const L& label = exact(label_); 00384 00385 // FIXME: check image properties + add doc. 00386 00387 util::array<A> accus(value::next(nlabels), a); 00388 00389 unsigned ncols = geom::ncols(label); 00390 00391 typedef mln_site(I) P; 00392 typedef const mln_value(I) * iptr_t; 00393 typedef const mln_value(L) * lptr_t; 00394 box_runstart_piter<P> p(label.domain()); 00395 for_all(p) 00396 { 00397 iptr_t iptr = & input(p); 00398 lptr_t lptr = & label(p); 00399 00400 for (unsigned i = 0; i < ncols; ++i) 00401 accus[*lptr++].take(*iptr++); 00402 } 00403 00404 util::array<mln_result(A)> res; 00405 convert::from_to(accus, res); 00406 00407 trace::exiting("labeling::impl::generic::compute_fastest"); 00408 return res; 00409 } 00410 00411 // FIXME: is there any optimization if border::get(input) == 00412 // border::get(label)) ? 00413 // 00414 00423 // 00424 template <typename A, typename I, typename L> 00425 inline 00426 util::array<mln_result(A)> 00427 compute_fastest(util::array<A>& accus, 00428 const Image<I>& input_, 00429 const Image<L>& label_, 00430 const mln_value(L)& nlabels) 00431 { 00432 trace::entering("labeling::impl::generic::compute_fastest"); 00433 //internal::compute_tests(a_, input_, label_, nlabels); 00434 00435 // FIXME: check image properties + add doc. 00436 00437 //const A& a = exact(a_); 00438 const I& input = exact(input_); 00439 const L& label = exact(label_); 00440 (void) nlabels; 00441 00442 if (value::next(nlabels) != accus.size()) 00443 { 00444 accus.resize(0); // Make sure all the accumulators are 00445 // re-initialized when resizing on next 00446 // line. 00447 accus.resize(value::next(nlabels)); 00448 } 00449 00450 unsigned ncols = geom::ncols(label); 00451 00452 typedef mln_site(I) P; 00453 typedef const mln_value(I) * iptr_t; 00454 typedef const mln_value(L) * lptr_t; 00455 box_runstart_piter<P> p(label.domain()); 00456 for_all(p) 00457 { 00458 iptr_t iptr = & input(p); 00459 lptr_t lptr = & label(p); 00460 00461 for (unsigned i = 0; i < ncols; ++i) 00462 accus[*lptr++].take(*iptr++); 00463 } 00464 00465 util::array<mln_result(A)> res; 00466 convert::from_to(accus, res); 00467 00468 trace::exiting("labeling::impl::generic::compute_fastest"); 00469 return res; 00470 } 00471 00472 00473 00474 } // end of namespace mln::labeling::impl 00475 00476 00477 00478 namespace internal 00479 { 00480 00481 00482 template <typename A, typename L> 00483 inline 00484 util::array<mln_result(A)> 00485 compute_dispatch(const Accumulator<A>& a, 00486 const Image<L>& label, 00487 const mln_value(L)& nlabels) 00488 { 00489 return impl::generic::compute(a, label, nlabels); 00490 } 00491 00492 00493 00494 00495 00496 template <typename A, typename I, typename L> 00497 inline 00498 util::array<mln_result(A)> 00499 compute_dispatch( 00500 mln::trait::image::value_access::any, 00501 mln::trait::image::value_access::any, 00502 mln::trait::image::ext_domain::any, 00503 mln::trait::image::ext_domain::any, 00504 const Accumulator<A>& a, 00505 const Image<I>& input, 00506 const Image<L>& label, 00507 const mln_value(L)& nlabels) 00508 { 00509 return impl::generic::compute(a, input, label, nlabels); 00510 } 00511 00512 00513 template <typename A, typename I, typename L> 00514 inline 00515 util::array<mln_result(A)> 00516 compute_dispatch( 00517 mln::trait::image::value_access::direct, 00518 mln::trait::image::value_access::direct, 00519 mln::trait::image::ext_domain::some, 00520 mln::trait::image::ext_domain::some, 00521 const Accumulator<A>& a, 00522 const Image<I>& input, 00523 const Image<L>& label, 00524 const mln_value(L)& nlabels) 00525 { 00526 return impl::compute_fastest(a, input, label, nlabels); 00527 } 00528 00529 00530 template <typename A, typename I, typename L> 00531 inline 00532 util::array<mln_result(A)> 00533 compute_dispatch(mln::trait::image::value_storage::any, 00534 mln::trait::image::value_storage::any, 00535 const Accumulator<A>& a, 00536 const Image<I>& input, 00537 const Image<L>& label, 00538 const mln_value(L)& nlabels) 00539 { 00540 return impl::generic::compute(a, input, label, nlabels); 00541 } 00542 00543 00544 template <typename A, typename I, typename L> 00545 inline 00546 util::array<mln_result(A)> 00547 compute_dispatch(mln::trait::image::value_storage::one_block, 00548 mln::trait::image::value_storage::one_block, 00549 const Accumulator<A>& a, 00550 const Image<I>& input_, 00551 const Image<L>& label_, 00552 const mln_value(L)& nlabels) 00553 { 00554 const I& input = exact(input_); 00555 const L& label = exact(label_); 00556 00558 if (mlc_is(mln_trait_image_value_alignment(I), 00559 trait::image::value_alignment::with_grid)::value && 00560 mlc_is(mln_trait_image_value_alignment(L), 00561 trait::image::value_alignment::with_grid)::value) 00562 { 00563 return compute_dispatch( 00564 mln_trait_image_value_access(I)(), 00565 mln_trait_image_value_access(L)(), 00566 mln_trait_image_ext_domain(I)(), 00567 mln_trait_image_ext_domain(L)(), 00568 a, input, label, nlabels); 00569 } 00570 else 00571 return impl::generic::compute(a, input, label, nlabels); 00572 } 00573 00574 00575 template <typename A, typename I, typename L> 00576 inline 00577 util::array<mln_result(A)> 00578 compute_dispatch(const Accumulator<A>& a, 00579 const Image<I>& input, 00580 const Image<L>& label, 00581 const mln_value(L)& nlabels) 00582 { 00583 return compute_dispatch(mln_trait_image_value_storage(I)(), 00584 mln_trait_image_value_storage(L)(), 00585 a, input, label, nlabels); 00586 } 00587 00588 00589 00590 00591 00592 00593 00594 00595 template <typename A, typename I, typename L> 00596 inline 00597 util::array<mln_result(A)> 00598 compute_dispatch( 00599 mln::trait::image::value_access::any, 00600 mln::trait::image::value_access::any, 00601 mln::trait::image::ext_domain::any, 00602 mln::trait::image::ext_domain::any, 00603 util::array<A>& a, 00604 const Image<I>& input, 00605 const Image<L>& label, 00606 const mln_value(L)& nlabels) 00607 { 00608 return impl::generic::compute(a, input, label, nlabels); 00609 } 00610 00611 00612 template <typename A, typename I, typename L> 00613 inline 00614 util::array<mln_result(A)> 00615 compute_dispatch( 00616 mln::trait::image::value_access::direct, 00617 mln::trait::image::value_access::direct, 00618 mln::trait::image::ext_domain::some, 00619 mln::trait::image::ext_domain::some, 00620 util::array<A>& a, 00621 const Image<I>& input, 00622 const Image<L>& label, 00623 const mln_value(L)& nlabels) 00624 { 00625 return impl::compute_fastest(a, input, label, nlabels); 00626 } 00627 00628 00629 template <typename A, typename I, typename L> 00630 inline 00631 util::array<mln_result(A)> 00632 compute_dispatch(mln::trait::image::value_storage::one_block, 00633 mln::trait::image::value_storage::one_block, 00634 util::array<A>& a, 00635 const Image<I>& input_, 00636 const Image<L>& label_, 00637 const mln_value(L)& nlabels) 00638 { 00639 const I& input = exact(input_); 00640 const L& label = exact(label_); 00641 00643 if (mlc_is(mln_trait_image_value_alignment(I), 00644 trait::image::value_alignment::with_grid)::value && 00645 mlc_is(mln_trait_image_value_alignment(L), 00646 trait::image::value_alignment::with_grid)::value) 00647 { 00648 return compute_dispatch( 00649 mln_trait_image_value_access(I)(), 00650 mln_trait_image_value_access(L)(), 00651 mln_trait_image_ext_domain(I)(), 00652 mln_trait_image_ext_domain(L)(), 00653 a, input, label, nlabels); 00654 } 00655 else 00656 return impl::generic::compute(a, input, label, nlabels); 00657 } 00658 00659 00660 template <typename A, typename I, typename L> 00661 inline 00662 util::array<mln_result(A)> 00663 compute_dispatch(util::array<A>& a, 00664 const Image<I>& input, 00665 const Image<L>& label, 00666 const mln_value(L)& nlabels) 00667 { 00668 return compute_dispatch(mln_trait_image_value_storage(I)(), 00669 mln_trait_image_value_storage(L)(), 00670 a, input, label, nlabels); 00671 } 00672 00673 00674 00675 00676 00677 template <typename A, typename L> 00678 inline 00679 util::array<mln_result(A)> 00680 compute_dispatch(util::array<A>& accus, 00681 const Image<L>& label, 00682 const mln_value(L)& nlabels) 00683 { 00684 return impl::generic::compute(accus, label, nlabels); 00685 } 00686 00687 } // end of namespace mln::labeling::internal 00688 00689 00690 00691 // Facades. 00692 00693 template <typename A, typename I, typename L> 00694 inline 00695 util::array<mln_result(A)> 00696 compute(util::array<A>& a, 00697 const Image<I>& input, 00698 const Image<L>& label, 00699 const mln_value(L)& nlabels) 00700 { 00701 trace::entering("labeling::compute"); 00702 00703 //internal::compute_tests(a, input, label, nlabels); 00704 00705 typedef util::array<mln_result(A)> R; 00706 R res = internal::compute_dispatch(a, input, label, nlabels); 00707 00708 trace::exiting("labeling::compute"); 00709 return res; 00710 } 00711 00712 template <typename A, typename I, typename L> 00713 inline 00714 util::array<mln_result(A)> 00715 compute(const Accumulator<A>& a, 00716 const Image<I>& input, 00717 const Image<L>& label, 00718 const mln_value(L)& nlabels) 00719 { 00720 trace::entering("labeling::compute"); 00721 00722 internal::compute_tests(a, input, label, nlabels); 00723 00724 typedef util::array<mln_result(A)> R; 00725 R res = internal::compute_dispatch(a, input, label, nlabels); 00726 00727 trace::exiting("labeling::compute"); 00728 return res; 00729 } 00730 00731 template <typename A, typename I, typename L> 00732 inline 00733 util::array<mln_meta_accu_result(A, mln_value(I))> 00734 compute(const Meta_Accumulator<A>& a, 00735 const Image<I>& input, 00736 const Image<L>& label, 00737 const mln_value(L)& nlabels) 00738 { 00739 typedef mln_accu_with(A, mln_value(I)) A_; 00740 A_ a_ = accu::unmeta(exact(a), mln_value(I)()); 00741 00742 return compute(a_, input, label, nlabels); 00743 } 00744 00745 00746 template <typename A, typename L> 00747 inline 00748 util::array<mln_result(A)> 00749 compute(util::array<A>& accus, 00750 const Image<L>& label, 00751 const mln_value(L)& nlabels) 00752 { 00753 trace::entering("labeling::compute"); 00754 00755 internal::compute_tests(A(), label, nlabels); 00756 00757 typedef util::array<mln_result(A)> R; 00758 R res = internal::compute_dispatch(accus, label, nlabels); 00759 00760 mln_postcondition(res.nelements() == value::next(nlabels)); 00761 00762 trace::exiting("labeling::compute"); 00763 return res; 00764 } 00765 00766 00767 00768 template <typename A, typename L> 00769 inline 00770 util::array<mln_result(A)> 00771 compute(const Accumulator<A>& a, 00772 const Image<L>& label, 00773 const mln_value(L)& nlabels) 00774 { 00775 trace::entering("labeling::compute"); 00776 00777 internal::compute_tests(a, label, nlabels); 00778 00779 typedef util::array<mln_result(A)> R; 00780 R res = internal::compute_dispatch(a, label, nlabels); 00781 00782 mln_postcondition(res.nelements() == value::next(nlabels)); 00783 00784 trace::exiting("labeling::compute"); 00785 return res; 00786 } 00787 00788 00789 template <typename A, typename L> 00790 inline 00791 util::array<mln_meta_accu_result(A, mln_psite(L))> 00792 compute(const Meta_Accumulator<A>& a, 00793 const Image<L>& label, 00794 const mln_value(L)& nlabels) 00795 { 00796 typedef mln_accu_with(A, mln_psite(L)) A_; 00797 A_ a_ = accu::unmeta(exact(a), mln_psite(L)()); 00798 00799 return compute(a_, label, nlabels); 00800 } 00801 00802 00803 # endif // ! MLN_INCLUDE_ONLY 00804 00805 } // end of namespace mln::labeling 00806 00807 } // end of namespace mln 00808 00809 00810 #endif // ! MLN_LABELING_COMPUTE_HH