00001 // Copyright (C) 2001, 2002, 2003, 2004 EPITA Research and Development Laboratory 00002 // 00003 // This file is part of the Olena Library. This library is free 00004 // software; you can redistribute it and/or modify it under the terms 00005 // of the GNU General Public License version 2 as published by the 00006 // Free Software Foundation. 00007 // 00008 // This library is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 // General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this library; see the file COPYING. If not, write to 00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston, 00016 // MA 02111-1307, USA. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software library 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 00022 // produce an executable, this file does not by itself cause the 00023 // resulting executable to be covered by the GNU General Public 00024 // License. This exception does not however invalidate any other 00025 // reasons why the executable file might be covered by the GNU General 00026 // Public License. 00027 00028 #ifndef OLENA_TOPO_DMAP_HH 00029 # define OLENA_TOPO_DMAP_HH 00030 00031 # include <ntg/bin.hh> 00032 # include <oln/basics2d.hh> 00033 # include <oln/core/w_window2d.hh> 00034 00035 // \todo FIXME: math.h should be included by ntg/config/system.hh 00036 // # include <math.h> 00037 # include <utility> 00038 00045 namespace oln { 00046 00048 namespace topo { 00054 template<class T> 00055 struct chamfer 00056 { 00057 chamfer(const w_window2d<T>& fwd, 00058 const w_window2d<T>& bkd, 00059 float coef); 00060 00061 coord 00062 delta() const; 00063 00064 const w_window2d<T> fwd; 00065 const w_window2d<T> bkd; 00066 const float coef; 00067 }; 00068 00087 template<int d10, int d11> inline 00088 const chamfer<int>& 00089 mk_chamfer_3x3(float coef = 1.f); 00090 00109 inline 00110 const chamfer<float>& 00111 mk_chamfer_3x3(float d10, float d11); 00112 00133 template<int d10, int d11, int d21> inline 00134 const chamfer<int>& 00135 mk_chamfer_5x5(float coef = 1.f); 00136 00141 inline 00142 const chamfer<float>& 00143 mk_chamfer_5x5(float d10, float d11, float d21); 00144 00161 inline const chamfer<int>& chamfer_1_1(); 00162 00179 inline const chamfer<int>& chamfer_1_2(); 00196 inline const chamfer<int>& chamfer_2_3(); 00213 inline const chamfer<int>& chamfer_5_7(); 00230 inline const chamfer<int>& chamfer_12_17(); 00247 inline const chamfer<int>& chessboard(); 00264 inline const chamfer<int>& cityblock(); 00285 inline const chamfer<int>& chamfer_4_6_9(); 00306 inline const chamfer<int>& chamfer_5_7_11(); 00327 inline const chamfer<int>& chamfer_9_13_20(); 00348 inline const chamfer<int>& chamfer_16_23_36(); 00365 inline const chamfer<float>& best_set_3x3(); 00386 inline const chamfer<float>& best_set_5x5(); 00387 00388 // maximum absolute error for integer local distances (Table 2) 00389 /* Maximum absolute error for integer local distances for chamfer_1_1. 00390 ** 00391 ** \verbatim 00392 ** oln::topo::mchamfer_1_1() = 00393 ** w.delta(): 1 00394 ** w.coef: 0.8536 00395 ** w.fwd: 00396 ** 1 1 1 00397 ** 1 . . 00398 ** . . . 00399 ** w.bkd: 00400 ** . . . 00401 ** . . 1 00402 ** 1 1 1 00403 ** \endverbatim 00404 */ 00405 inline const chamfer<int>& mchamfer_1_1(); 00406 /* Maximum absolute error for integer local distances for chamfer_1_2. 00407 ** 00408 ** \verbatim 00409 ** oln::topo::mchamfer_1_2() = 00410 ** w.delta(): 1 00411 ** w.coef: 1.2071 00412 ** w.fwd: 00413 ** 2 1 2 00414 ** 1 . . 00415 ** . . . 00416 ** w.bkd: 00417 ** . . . 00418 ** . . 1 00419 ** 2 1 2 00420 ** \endverbatim 00421 */ 00422 inline const chamfer<int>& mchamfer_1_2(); 00423 /* Maximum absolute error for integer local distances for chamfer_2_3. 00424 ** 00425 ** \verbatim 00426 ** oln::topo::mchamfer_2_3() = 00427 ** w.delta(): 1 00428 ** w.coef: 2.118 00429 ** w.fwd: 00430 ** 3 2 3 00431 ** 2 . . 00432 ** . . . 00433 ** w.bkd: 00434 ** . . . 00435 ** . . 2 00436 ** 3 2 3 00437 ** \endverbatim 00438 */ 00439 inline const chamfer<int>& mchamfer_2_3(); 00440 /* Maximum absolute error for integer local distances for chamfer_5_7. 00441 ** 00442 ** \verbatim 00443 ** oln::topo::mchamfer_5_7() = 00444 ** w.delta(): 1 00445 ** w.coef: 5.1675 00446 ** w.fwd: 00447 ** 7 5 7 00448 ** 5 . . 00449 ** . . . 00450 ** w.bkd: 00451 ** . . . 00452 ** . . 5 00453 ** 7 5 7 00454 ** \endverbatim 00455 */ 00456 inline const chamfer<int>& mchamfer_5_7(); 00457 /* Maximum absolute error for integer local distances for chamfer_12_17. 00458 ** 00459 ** \verbatim 00460 ** oln::topo::mchamfer_12_17() = 00461 ** w.delta(): 1 00462 ** w.coef: 12.5 00463 ** w.fwd: 00464 ** 17 12 17 00465 ** 12 . . 00466 ** . . . 00467 ** w.bkd: 00468 ** . . . 00469 ** . . 12 00470 ** 17 12 17 00471 ** \endverbatim 00472 */ 00473 inline const chamfer<int>& mchamfer_12_17(); 00474 /* Maximum absolute error for integer local distances for chessboard. 00475 ** 00476 ** \verbatim 00477 ** oln::topo::mchessboard() = 00478 ** w.delta(): 1 00479 ** w.coef: 0.8536 00480 ** w.fwd: 00481 ** 1 1 1 00482 ** 1 . . 00483 ** . . . 00484 ** w.bkd: 00485 ** . . . 00486 ** . . 1 00487 ** 1 1 1 00488 ** \endverbatim 00489 */ 00490 inline const chamfer<int>& mchessboard(); 00491 /* Maximum absolute error for integer local distances for cityblock. 00492 ** 00493 ** \verbatim 00494 ** oln::topo::mcityblock() = 00495 ** w.delta(): 1 00496 ** w.coef: 1.2071 00497 ** w.fwd: 00498 ** 2 1 2 00499 ** 1 . . 00500 ** . . . 00501 ** w.bkd: 00502 ** . . . 00503 ** . . 1 00504 ** 2 1 2 00505 ** \endverbatim 00506 */ 00507 inline const chamfer<int>& mcityblock(); 00508 /* Maximum absolute error for integer local distances for chamfer_4_6_9. 00509 ** 00510 ** \verbatim 00511 ** oln::topo::mchamfer_4_6_9() = 00512 ** w.delta(): 2 00513 ** w.coef: 4.1213 00514 ** w.fwd: 00515 ** . 9 . 9 . 00516 ** 9 6 4 6 9 00517 ** . 4 . . . 00518 ** . . . . . 00519 ** . . . . . 00520 ** w.bkd: 00521 ** . . . . . 00522 ** . . . . . 00523 ** . . . 4 . 00524 ** 9 6 4 6 9 00525 ** . 9 . 9 . 00526 ** \endverbatim 00527 */ 00528 inline const chamfer<int>& mchamfer_4_6_9(); 00529 /* Maximum absolute error for integer local distances for chamfer_5_7_11. 00530 ** 00531 ** \verbatim 00532 ** oln::topo::mchamfer_5_7_11() = 00533 ** w.delta(): 2 00534 ** w.coef: 5.0092 00535 ** w.fwd: 00536 ** . 11 . 11 . 00537 ** 11 7 5 7 11 00538 ** . 5 . . . 00539 ** . . . . . 00540 ** . . . . . 00541 ** w.bkd: 00542 ** . . . . . 00543 ** . . . . . 00544 ** . . . 5 . 00545 ** 11 7 5 7 11 00546 ** . 11 . 11 . 00547 ** \endverbatim 00548 */ 00549 inline const chamfer<int>& mchamfer_5_7_11(); 00550 /* Maximum absolute error for integer local distances for chamfer_9_13_20. 00551 ** 00552 ** \verbatim 00553 ** oln::topo::mchamfer_9_13_20() = 00554 ** w.delta(): 2 00555 ** w.coef: 9.0819 00556 ** w.fwd: 00557 ** . 20 . 20 . 00558 ** 20 13 9 13 20 00559 ** . 9 . . . 00560 ** . . . . . 00561 ** . . . . . 00562 ** w.bkd: 00563 ** . . . . . 00564 ** . . . . . 00565 ** . . . 9 . 00566 ** 20 13 9 13 20 00567 ** . 20 . 20 . 00568 ** \endverbatim 00569 */ 00570 inline const chamfer<int>& mchamfer_9_13_20(); 00571 /* Maximum absolute error for integer local distances for chamfer_17_24_38. 00572 ** 00573 ** \verbatim 00574 ** oln::topo::mchamfer_17_24_38() = 00575 ** w.delta(): 2 00576 ** w.coef: 17.2174 00577 ** w.fwd: 00578 ** . 38 . 38 . 00579 ** 38 24 17 24 38 00580 ** . 17 . . . 00581 ** . . . . . 00582 ** . . . . . 00583 ** w.bkd: 00584 ** . . . . . 00585 ** . . . . . 00586 ** . . . 17 . 00587 ** 38 24 17 24 38 00588 ** . 38 . 38 . 00589 ** \endverbatim 00590 */ 00591 inline const chamfer<int>& mchamfer_17_24_38(); 00592 /* Maximum absolute error for integer local distances for best_set_3x3. 00593 ** 00594 ** \verbatim 00595 ** oln::topo:mbest_set_3x3() = 00596 ** w.delta(): 1 00597 ** w.coef: 1 00598 ** w.fwd: 00599 ** 1.35825 0.96043 1.35825 00600 ** 0.96043 . . 00601 ** . . . 00602 ** w.bkd: 00603 ** . . . 00604 ** . . 0.96043 00605 ** 1.35825 0.96043 1.35825 00606 ** \endverbatim 00607 */ 00608 inline const chamfer<float>& mbest_set_3x3(); 00609 /* Maximum absolute error for integer local distances for best_set_5x5. 00610 ** 00611 ** \verbatim 00612 ** oln::topo:mbest_set_5x5() = 00613 ** w.delta(): 2 00614 ** w.coef: 1 00615 ** w.fwd: 00616 ** . 2.20585 . 2.20585 . 00617 ** 2.20585 1.3951 0.986485 1.3951 2.20585 00618 ** . 0.986485 . . . 00619 ** . . . . . 00620 ** . . . . . 00621 ** w.bkd: 00622 ** . . . . . 00623 ** . . . . . 00624 ** . . . 0.986485 . 00625 ** 2.20585 1.3951 0.986485 1.3951 2.20585 00626 ** . 2.20585 . 2.20585 . 00627 ** \endverbatim 00628 */ 00629 inline const chamfer<float>& mbest_set_5x5(); 00630 00659 template<class T, class T2> 00660 class dmap 00661 { 00662 public: 00663 typedef image2d<ntg::bin>::point_type point_type; 00664 00670 dmap(const image2d_size& size, const chamfer<T2>& ch); 00671 00673 template <class V> 00674 void 00675 compute(const image2d<V>& input, float infty = 0.f); 00676 00678 template <class V> 00679 void 00680 compute(const image2d<V>& input, 00681 image2d<point2d>& nearest_point_map, 00682 float infty = 0.f); 00683 00685 const image2d<T>& 00686 imap() const; 00687 00689 image2d<float> 00690 to_image() const; 00691 00693 const T& 00694 operator[](const point_type& p) const; 00695 00697 const T& 00698 operator()(coord row, coord col) const; 00699 00700 private: 00701 image2d<T> imap_; 00702 chamfer<T2> ch_; 00703 float inFty_; 00704 T infTy_; 00705 }; 00707 template <class I> 00708 image2d<float> exact_dmap(const abstract::image<I>& input); 00709 00710 } // end of namespace topo 00711 00712 } // end of namespace oln 00713 00714 # include <oln/topo/dmap.hxx> 00715 00716 #endif // OLENA_TOPO_DMAP_HH