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