27 #ifndef MLN_LINEAR_GAUSSIAN_IMPL_HH
28 # define MLN_LINEAR_GAUSSIAN_IMPL_HH
40 # include <mln/core/concept/image.hh>
41 # include <mln/core/alias/point2d.hh>
42 # include <mln/core/alias/dpoint1d.hh>
43 # include <mln/core/alias/dpoint3d.hh>
44 # include <mln/extension/adjust_fill.hh>
45 # include <mln/geom/ncols.hh>
46 # include <mln/geom/nrows.hh>
47 # include <mln/geom/ninds.hh>
48 # include <mln/geom/nslis.hh>
49 # include <mln/data/paste.hh>
50 # include <mln/data/stretch.hh>
51 # include <mln/algebra/vec.hh>
53 # include <mln/linear/gaussian/internal/coefficients.hh>
69 # ifndef MLN_INCLUDE_ONLY
71 template <
class WorkType,
class I>
74 recursivefilter_(I& ima,
75 const internal::coefficients& c,
76 const mln_psite(I)& start,
77 const mln_psite(I)& finish,
79 const mln_deduce(I, psite, delta)& d)
81 std::vector<WorkType> tmp1(len);
82 std::vector<WorkType> tmp2(len);
95 c.n[0] * ima(start + d)
100 c.n[0] * ima(start + d + d)
101 + c.n[1] * ima(start + d)
102 + c.n[2] * ima(start)
107 c.n[0] * ima(start + d + d + d)
108 + c.n[1] * ima(start + d + d)
109 + c.n[2] * ima(start + d)
110 + c.n[3] * ima(start)
111 - c.d[1] * tmp1[2] - c.d[2] * tmp1[1]
114 mln_psite(I) current(start + d + d + d + d);
115 for (mln_deduce(I, site, coord) i = 4; i < len; ++i)
118 c.n[0] * ima(current)
119 + c.n[1] * ima(current - d)
120 + c.n[2] * ima(current - d - d)
121 + c.n[3] * ima(current - d - d - d)
122 - c.d[1] * tmp1[i - 1] - c.d[2] * tmp1[i - 2]
123 - c.d[3] * tmp1[i - 3] - c.d[4] * tmp1[i - 4];
124 current = current + d;
129 tmp2[len - 1] = WorkType();
132 c.nm[1] * ima(finish);
135 c.nm[1] * ima(finish - d)
136 + c.nm[2] * ima(finish)
137 - c.dm[1] * tmp2[len - 2];
140 c.nm[1] * ima(finish - d - d)
141 + c.nm[2] * ima(finish - d)
142 + c.nm[3] * ima(finish)
143 - c.dm[1] * tmp2[len - 3]
144 - c.dm[2] * tmp2[len - 2];
146 current = finish - d - d - d ;
148 for (
int i = len - 5; i >= 0; --i)
151 c.nm[1] * ima(current)
152 + c.nm[2] * ima(current + d)
153 + c.nm[3] * ima(current + d + d)
154 + c.nm[4] * ima(current + d + d + d)
155 - c.dm[1] * tmp2[i + 1] - c.dm[2] * tmp2[i + 2]
156 - c.dm[3] * tmp2[i + 3] - c.dm[4] * tmp2[i + 4];
157 current = current - d;
162 for (
int i = 0; i < len; ++i)
164 ima(current) = tmp1[i] + tmp2[i];
165 current = current + d;
170 template <
class I,
class F>
173 generic_filter_(trait::image::dimension::one_d,
174 Image<I>& img_,
const F& coef,
int dir)
176 I& img = exact(img_);
177 typedef mln_site(I) S;
179 mln_precondition(dir < S::dim);
181 recursivefilter_<mln_value(I)>(img, coef,
182 point1d(static_cast<def::coord>(-img.border())),
183 point1d(static_cast<def::coord>(geom::ninds(img) - 1 +
185 geom::ninds(img) + 2 * img.border(),
189 template <class I, class F>
192 generic_filter_(trait::image::dimension::two_d,
193 Image<I>& img_, const F& coef,
int dir)
195 I& img = exact(img_);
196 typedef mln_site(I) S;
198 mln_precondition(dir < S::dim);
204 recursivefilter_<mln_value(I)>(img, coef,
205 point2d(static_cast<def::coord>(-img.border()),
206 static_cast<def::coord>(j)),
209 static_cast<def::coord>(j)),
218 recursivefilter_<mln_value(I)>(img, coef,
219 point2d(static_cast<def::coord>(i),
220 static_cast<def::coord>(-img.border())),
221 point2d(static_cast<def::coord>(i),
229 template <
class I,
class F>
232 generic_filter_(trait::image::dimension::three_d,
233 Image<I>& img_,
const F& coef,
int dir)
235 I& img = exact(img_);
236 typedef mln_site(I) S;
238 mln_precondition(dir < S::dim);
245 recursivefilter_<mln_value(I)>(img, coef,
246 point3d(static_cast<def::coord>(-img.border()),
247 static_cast<def::coord>(j),
251 static_cast<def::coord>(j),
264 recursivefilter_<mln_value(I)>(img, coef,
265 point3d(static_cast<def::coord>(i),
266 static_cast<def::coord>(-img.border()),
267 static_cast<def::coord>(k)),
268 point3d(static_cast<def::coord>(i),
271 static_cast<def::coord>(k)),
282 recursivefilter_<mln_value(I)>(img, coef,
283 point3d(static_cast<def::coord>(i),
284 static_cast<def::coord>(j),
285 static_cast<def::coord>(-img.border())),
286 point3d(static_cast<def::coord>(i),
287 static_cast<def::coord>(j),
298 template <
class I,
class F,
class O>
301 generic_filter_common_(trait::value::nature::floating,
307 typedef mln_site(I) S;
309 mln_ch_value(O,
double) work_img(exact(in).domain());
310 data::paste(in, work_img);
311 extension::adjust_fill(work_img, 4, 0);
316 for (
int i = 0; i < S::dim; ++i)
317 generic_filter_(mln_trait_image_dimension(I)(),
321 data::paste(work_img, out);
324 template <class I, class F, class O>
327 generic_filter_common_(trait::value::nature::floating,
334 mln_ch_value(O,
double) work_img(exact(in).domain());
335 data::paste(in, work_img);
336 extension::adjust_fill(work_img, 4, 0);
341 generic_filter_(mln_trait_image_dimension(I)(),
342 work_img, coef, dir);
345 data::paste(work_img, out);
349 template <class I, class F, class O>
352 generic_filter_common_(trait::value::nature::scalar,
358 typedef mln_site(I) S;
360 mln_ch_value(O,
double) work_img(exact(in).domain());
361 data::paste(in, work_img);
362 extension::adjust_fill(work_img, 4, 0);
367 for (
int i = 0; i < S::dim; ++i)
368 generic_filter_(mln_trait_image_dimension(I)(),
372 data::paste(
data::stretch(mln_value(I)(), work_img), out);
375 template <class I, class F, class O>
378 generic_filter_common_(trait::value::nature::scalar,
385 mln_ch_value(O,
double) work_img(exact(in).domain());
386 data::paste(in, work_img);
387 extension::adjust_fill(work_img, 4, 0);
392 generic_filter_(mln_trait_image_dimension(I)(),
393 work_img, coef, dir);
396 data::paste(
data::stretch(mln_value(I)(), work_img), out);
401 template <class I, class F, class O>
404 generic_filter_common_(trait::value::nature::vectorial,
410 typedef mln_site(I) S;
415 data::paste(in, out);
420 for (
int i = 0; i < S::dim; ++i)
421 generic_filter_(mln_trait_image_dimension(I)(),
425 template <class I, class F, class O>
428 generic_filter_common_(trait::value::nature::vectorial,
443 generic_filter_(mln_trait_image_dimension(I)(),
448 # endif // ! MLN_INCLUDE_ONLY
460 #endif // ! MLN_LINEAR_GAUSSIAN_IMPL_HH