reconstruction.hh

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_MORPHO_RECONSTRUCTION_HH
00029 # define OLENA_MORPHO_RECONSTRUCTION_HH
00030 
00031 # include <oln/basics.hh>
00032 # include <oln/convert/conversion_ng_se.hh>
00033 # include <oln/level/compare.hh>
00034 # include <oln/morpho/geodesic_dilation.hh>
00035 # include <oln/morpho/geodesic_erosion.hh>
00036 # include <oln/morpho/splitse.hh>
00037 # include <oln/morpho/stat.hh>
00038 
00039 # include <ntg/basics.hh>
00040 
00041 # include <queue>
00042 
00043 namespace oln {
00044   namespace morpho {
00045     namespace sure {
00094       template<class I1, class I2, class N>
00095       oln_concrete_type(I1)
00096         geodesic_reconstruction_dilation(const abstract::non_vectorial_image<I1> & marker,
00097                                          const abstract::non_vectorial_image<I2> & mask,
00098                                          const abstract::neighborhood<N>& Ng)
00099       {
00100         mlc::eq<I1::dim, I2::dim>::ensure();
00101         mlc::eq<I1::dim, N::dim>::ensure();
00102         precondition(marker.size() == mask.size());
00103         precondition(level::is_greater_or_equal(mask, marker));
00104         oln_concrete_type(I1) output = marker.clone();
00105         bool non_stability = true;
00106         while (non_stability)
00107           {
00108             oln_concrete_type(I1) work = geodesic_dilation(output, mask, Ng);
00109             non_stability = !(level::is_equal(work, output));
00110             output = work;
00111           }
00112         return output;
00113       }
00114     }// sure
00115 
00116 
00117     namespace sequential {
00166       template<class I1, class I2, class N>
00167       oln_concrete_type(I1)
00168         geodesic_reconstruction_dilation(const abstract::non_vectorial_image<I1> & marker,
00169                                          const abstract::non_vectorial_image<I2> & mask,
00170                                          const abstract::neighborhood<N>& Ng)
00171       {
00172         mlc::eq<I1::dim, I2::dim>::ensure();
00173         mlc::eq<I1::dim, N::dim>::ensure();
00174         precondition(marker.size() == mask.size());
00175         precondition(level::is_greater_or_equal(mask, marker));
00176 
00177         // Conversion of neighborhood into a SE.
00178         typedef typename abstract::neighborhood<N>::win_type E;
00179         E se_plus = get_plus_se_p(convert::ng_to_cse(Ng));
00180         E se_minus = get_minus_se_p(convert::ng_to_cse(Ng));
00181 
00182         oln_concrete_type(I1) output = marker.clone();
00183         bool non_stability = true;
00184         typename I1::fwd_iter_type fwd_p(output);
00185         typename I1::bkd_iter_type bkd_p(output);
00186         while (non_stability)
00187           {
00188             oln_concrete_type(I1) work = output.clone();
00189             work.border_adapt_copy(Ng.delta());
00190             for_all (fwd_p)
00191               work[fwd_p] = ntg::min(morpho::max(work, fwd_p, se_plus), mask[fwd_p]);
00192             for_all (bkd_p)
00193               work[bkd_p] = ntg::min(morpho::max(work, bkd_p, se_minus), mask[bkd_p]);
00194             non_stability = !(level::is_equal(work, output));
00195             output = work;
00196           }
00197         return output;
00198       }
00199     }// sequential
00200 
00201 
00202     namespace hybrid {
00203 
00204       namespace internal {
00205 
00214         template<class P, class I1, class I2, class E> inline
00215         static bool
00216         exist_init_dilation(const abstract::point<P>& p,
00217                             const abstract::non_vectorial_image<I1>& marker,
00218                             const abstract::non_vectorial_image<I2>& mask,
00219                             const abstract::struct_elt<E>& se)
00220         {
00221           mlc::eq<I1::dim, I2::dim>::ensure();
00222           mlc::eq<I1::dim, E::dim>::ensure();
00223           mlc::eq<I1::dim, P::dim>::ensure();
00224 
00225           oln_neighb_type(E) q(se, p);
00226           for_all (q)
00227             if (marker.hold(q) && (marker[q] < marker[p]) && (marker[q] < mask[q]))
00228               return true;
00229           return false;
00230         }
00231 
00232       } //internal
00233 
00282       template<class I1, class I2, class N>
00283       oln_concrete_type(I1)
00284         geodesic_reconstruction_dilation(const abstract::non_vectorial_image<I1> & marker,
00285                                          const abstract::non_vectorial_image<I2> & mask,
00286                                          const abstract::neighborhood<N>& Ng)
00287       {
00288         mlc::eq<I1::dim, I2::dim>::ensure();
00289         mlc::eq<I1::dim, N::dim>::ensure();
00290 
00291         precondition(marker.size() == mask.size());
00292         precondition(level::is_greater_or_equal(mask, marker));
00293 
00294         oln_concrete_type(I1) output = marker.clone();
00295         output.border_adapt_copy(Ng.delta());
00296         {
00297           typedef typename abstract::neighborhood<N>::win_type E;
00298           E Ng_plus = get_plus_se_p(convert::ng_to_cse(Ng));
00299           E Ng_minus = get_minus_se_p(convert::ng_to_cse(Ng));
00300           typename I1::fwd_iter_type fwd_p(output);
00301           typename I1::bkd_iter_type bkd_p(output);
00302           for_all (fwd_p)
00303             output[fwd_p] = ntg::min(morpho::max(output, fwd_p, Ng_plus),
00304                                      mask[fwd_p]);
00305 
00306           std::queue<oln_point_type(I1) > fifo;
00307           for_all (bkd_p)
00308             {
00309               output[bkd_p] = ntg::min(morpho::max(output, bkd_p, Ng_minus),
00310                                        mask[bkd_p]);
00311               if (internal::exist_init_dilation(bkd_p.cur(), output, mask, Ng_minus))
00312                 fifo.push(bkd_p);
00313             }
00314           // Propagation Step
00315           while (!fifo.empty())
00316             {
00317               oln_point_type(I1) p = fifo.front();
00318               fifo.pop();
00319               oln_neighb_type(N) q(Ng, p);
00320               for_all (q) if (output.hold(q))
00321                 {
00322                   if ((output[q] < output[p]) && (mask[q] != output[q]))
00323                     {
00324                       output[q] = ntg::min(output[p], mask[q]);
00325                       fifo.push(q);
00326                     }
00327                 }
00328             }
00329         }
00330         return output;
00331       }
00332     }// hybrid
00333 
00334 
00335     //GEODESIC RECONSTRUCTION EROSION
00336 
00337     namespace sure {
00338 
00387       template<class I1, class I2, class N>
00388       oln_concrete_type(I1)
00389         geodesic_reconstruction_erosion(const abstract::non_vectorial_image<I1> & marker,
00390                                         const abstract::non_vectorial_image<I2> & mask,
00391                                         const abstract::neighborhood<N>& Ng)
00392       {
00393         mlc::eq<I1::dim, I2::dim>::ensure();
00394         mlc::eq<I1::dim, N::dim>::ensure();
00395         precondition(marker.size() == mask.size());
00396         precondition(level::is_greater_or_equal(marker, mask));
00397         oln_concrete_type(I1) output = marker.clone();
00398         bool non_stability = true;
00399         while (non_stability)
00400           {
00401             oln_concrete_type(I1) work = geodesic_erosion(output, mask, Ng);
00402             non_stability = !(level::is_equal(work, output));
00403             output = work;
00404           }
00405         return output;
00406       }
00407     } // sure
00408 
00409 
00410     namespace sequential {
00411 
00460       template<class I1, class I2, class N>
00461       oln_concrete_type(I1)
00462         geodesic_reconstruction_erosion(const abstract::non_vectorial_image<I1>& marker,
00463                                         const abstract::non_vectorial_image<I2>& mask,
00464                                         const abstract::neighborhood<N>& Ng)
00465       {
00466         mlc::eq<I1::dim, I2::dim>::ensure();
00467         mlc::eq<I1::dim, N::dim>::ensure();
00468         precondition(marker.size() == mask.size());
00469         precondition(level::is_greater_or_equal(marker, mask));
00470 
00471         typedef typename abstract::neighborhood<N>::win_type E;
00472         E se_plus = get_plus_se_p(convert::ng_to_cse(Ng));
00473         E se_minus = get_minus_se_p(convert::ng_to_cse(Ng));
00474         oln_concrete_type(I1) output = marker.clone();
00475 
00476         bool non_stability = true;
00477         typename I1::fwd_iter_type fwd_p(output);
00478         typename I1::bkd_iter_type bkd_p(output);
00479         while (non_stability)
00480           {
00481             oln_concrete_type(I1) work = output.clone();
00482             work.border_adapt_copy(Ng.delta());
00483             for_all (fwd_p)
00484               work[fwd_p] = ntg::max(morpho::min(work, fwd_p, se_plus), mask[fwd_p]);
00485             for_all (bkd_p)
00486               work[bkd_p] = ntg::max(morpho::min(work, bkd_p, se_minus), mask[bkd_p]);
00487             non_stability = !(level::is_equal(work, output));
00488             output = work;
00489           }
00490         return output;
00491       }
00492     } // sequential
00493 
00494 
00495     namespace hybrid {
00496       namespace internal {
00505         template<class P, class I1, class I2, class E> inline
00506         static bool
00507         exist_init_erosion(const abstract::point<P>& p,
00508                            const abstract::non_vectorial_image<I1>& marker,
00509                            const abstract::non_vectorial_image<I2>& mask,
00510                            const abstract::struct_elt<E>& se)
00511         {
00512           mlc::eq<I1::dim, I2::dim>::ensure();
00513           mlc::eq<I1::dim, E::dim>::ensure();
00514           mlc::eq<I1::dim, P::dim>::ensure();
00515 
00516           oln_neighb_type(E) q(se, p);
00517           for_all (q)
00518             if (marker.hold(q) && (marker[q] > marker[p]) && (marker[q] > mask[q]))
00519               return true;
00520           return false;
00521         }
00522       } // internal
00523 
00572       template<class I1, class I2, class N>
00573       oln_concrete_type(I1)
00574         geodesic_reconstruction_erosion(const abstract::non_vectorial_image<I1> & marker,
00575                                         const abstract::non_vectorial_image<I2> & mask,
00576                                         const abstract::neighborhood<N>& Ng)
00577       {
00578         mlc::eq<I1::dim, I2::dim>::ensure();
00579         mlc::eq<I1::dim, N::dim>::ensure();
00580 
00581         precondition(marker.size() == mask.size());
00582         precondition(level::is_greater_or_equal(marker, mask));
00583 
00584         oln_concrete_type(I1) output = marker.clone();
00585         output.border_adapt_copy(Ng.delta());
00586         {
00587           typedef typename abstract::neighborhood<N>::win_type E;
00588           E Ng_plus = get_plus_se_p(convert::ng_to_cse(Ng));
00589           E Ng_minus = get_minus_se_p(convert::ng_to_cse(Ng));
00590           typename I1::fwd_iter_type fwd_p(output);
00591           typename I1::bkd_iter_type bkd_p(output);
00592           for_all (fwd_p)
00593             output[fwd_p] = ntg::max(morpho::min(output, fwd_p, Ng_plus),
00594                                      mask[fwd_p]);
00595 
00596           std::queue<oln_point_type(I1) > fifo;
00597           for_all (bkd_p)
00598             {
00599               output[bkd_p] = ntg::max(morpho::min(output, bkd_p, Ng_minus),
00600                                        mask[bkd_p]);
00601               if (internal::exist_init_erosion(bkd_p.cur(), output, mask, Ng_minus))
00602                 fifo.push(bkd_p);
00603             }
00604           //     Propagation Step
00605           while (!fifo.empty())
00606             {
00607               oln_point_type(I1) p = fifo.front();
00608               fifo.pop();
00609               oln_neighb_type(N) q(Ng, p);
00610               for_all (q) if (output.hold(q))
00611                 {
00612                   if ((output[q] > output[p]) && (mask[q] != output[q]))
00613                     {
00614                       output[q] = ntg::max(output[p], mask[q]);
00615                       fifo.push(q);
00616                     }
00617                 }
00618             }
00619         }
00620         return output;
00621       }
00622 
00623 
00624     } // hybrid
00625   } // morpho
00626 } // oln
00627 
00628 #endif // OLENA_MORPHO_RECONSTRUCTION_HH

Generated on Thu Apr 15 20:13:14 2004 for Olena by doxygen 1.3.6-20040222