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_MORPHO_APPROX_EROSION_HH
00027 # define MLN_MORPHO_APPROX_EROSION_HH
00028 
00032 
00033 # include <mln/morpho/approx/dilation.hh>
00034 # include <mln/logical/not.hh>
00035 
00036 
00037 
00038 namespace mln
00039 {
00040 
00041   namespace morpho
00042   {
00043 
00044     namespace approx
00045     {
00046 
00047 
00048       template <typename I, typename W>
00049       mln_concrete(I)
00050       erosion(const Image<I>& input, const Window<W>& win);
00051 
00052 
00053 
00054 # ifndef MLN_INCLUDE_ONLY
00055 
00056 
00057       
00058 
00059       namespace impl
00060       {
00061         
00062         
00063         
00064         
00065         template <typename I>
00066         mln_concrete(I)
00067         erosion_by_distance_thresholding_2d(const Image<I>& input_,
00068                                              const Window< win::disk2d >& win_)
00069         {
00070           trace::entering("morpho::approx::impl::erosion_by_distance_thresholding_2d");
00071 
00072           const I& input         = exact(input_);
00073           const win::disk2d& win = exact(win_);
00074 
00075           mln_precondition(input.is_valid());
00076           mln_precondition(win.is_valid());
00077 
00078           int ws[] = { 00, 11,  0, 11,  0,
00079                        11,  7,  5,  7, 11,
00080                        00,  5,  0,  5,  0,
00081                        11,  7,  5,  7, 11,
00082                        00, 11,  0, 11,  0 };
00083           const unsigned coef = 5;
00084 
00085           unsigned
00086             radius = coef * win.diameter() / 2,
00087             dmax   = radius + 1;
00088           
00089 
00090           mln_concrete(I) background = logical::not_(input);
00091           mln_ch_value(I, unsigned) dmap = transform::distance_front(background,
00092                                                                      c4(), make::w_window2d_int(ws),
00093                                                                      dmax);
00094           mln_concrete(I) output;
00095           output = duplicate((pw::value(dmap) > pw::cst(radius)) | input.domain());
00096 
00097           trace::exiting("morpho::approx::impl::erosion_by_distance_thresholding_2d");
00098           return output;
00099         }
00100 
00101 
00102         
00103         template <typename I>
00104         mln_concrete(I)
00105         erosion_by_distance_thresholding_3d(const Image<I>& input_,
00106                                              const Window< win::sphere3d >& win_)
00107         {
00108           trace::entering("morpho::approx::impl::erosion_by_distance_thresholding_3d");
00109 
00110           const I& input           = exact(input_);
00111           const win::sphere3d& win = exact(win_);
00112 
00113           mln_precondition(input.is_valid());
00114           mln_precondition(win.is_valid());
00115 
00116           int ws[] = { 00, 21, 00,
00117                        21, 17, 21,
00118                        00, 21, 00,
00119 
00120                        17, 12, 17,
00121                        12, 00, 12,
00122                        17, 12, 17,
00123 
00124                        00, 21, 00,
00125                        21, 17, 21,
00126                        00, 21, 00 };
00127           const unsigned coef = 12;
00128 
00129           unsigned
00130             radius = coef * win.diameter() / 2,
00131             dmax   = radius + 1;
00132 
00133           mln_concrete(I) background = logical::not_(input);
00134           mln_ch_value(I, unsigned) dmap = transform::distance_front(background,
00135                                                                      c6(), make::w_window3d_int(ws),
00136                                                                      dmax);
00137           mln_concrete(I) output;
00138           output = duplicate((pw::value(dmap) > pw::cst(radius)) | input.domain());
00139 
00140           trace::exiting("morpho::approx::impl::erosion_by_distance_thresholding_3d");
00141           return output;
00142         }
00143 
00144 
00145       } 
00146 
00147 
00148 
00149       
00150 
00151       namespace internal
00152       {
00153 
00154         template <typename I>
00155         mln_concrete(I)
00156         erosion_dispatch(trait::image::kind::logic,
00157                           const I& input,
00158                           const win::disk2d& win)
00159         {
00160           return impl::erosion_by_distance_thresholding_2d(input, win);
00161         }
00162 
00163         template <typename I>
00164         mln_concrete(I)
00165         erosion_dispatch(trait::image::kind::logic,
00166                           const I& input,
00167                           const win::sphere3d& win)
00168         {
00169           return impl::erosion_by_distance_thresholding_3d(input, win);
00170         }
00171 
00172         
00173 
00174         template <typename I, typename W>
00175         mln_concrete(I)
00176         erosion_dispatch(const I& input, const W& win)
00177         {
00178           return erosion_dispatch(mln_trait_image_kind(I)(),
00179                                    input, win);
00180         }
00181 
00182       } 
00183 
00184 
00185       
00186 
00187       template <typename I, typename W>
00188       inline
00189       mln_concrete(I)
00190       erosion(const Image<I>& input, const Window<W>& win)
00191       {
00192         trace::entering("morpho::approx::erosion");
00193 
00194         mln_precondition(exact(input).is_valid());
00195         mln_precondition(exact(win).is_valid());
00196 
00197         mln_concrete(I) output;
00198         output = internal::erosion_dispatch(exact(input), exact(win));
00199 
00200         if (exact(win).is_centered())
00201           mln_postcondition(output <= input);
00202         
00203         trace::exiting("morpho::approx::erosion");
00204         return output;
00205       }
00206 
00207 
00208 # endif // ! MLN_INCLUDE_ONLY
00209 
00210     } 
00211 
00212   } 
00213 
00214 } 
00215 
00216 
00217 #endif // ! MLN_MORPHO_APPROX_EROSION_HH