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