37#ifndef VIGRA_SEPARABLECONVOLUTION_HXX
38#define VIGRA_SEPARABLECONVOLUTION_HXX
42#include "numerictraits.hxx"
43#include "imageiteratoradapter.hxx"
44#include "bordertreatment.hxx"
45#include "gaussians.hxx"
46#include "array_vector.hxx"
47#include "multi_shape.hxx"
51template <
class ARITHTYPE>
64template <
class SrcIterator,
class SrcAccessor,
65 class DestIterator,
class DestAccessor,
66 class KernelIterator,
class KernelAccessor>
67void internalConvolveLineOptimistic(SrcIterator is, SrcIterator iend, SrcAccessor sa,
68 DestIterator
id, DestAccessor da,
69 KernelIterator kernel, KernelAccessor ka,
70 int kleft,
int kright)
72 typedef typename PromoteTraits<
73 typename SrcAccessor::value_type,
74 typename KernelAccessor::value_type>::Promote SumType;
76 int w = std::distance( is, iend );
77 int kw = kright - kleft + 1;
78 for(
int x=0; x<w; ++x, ++is, ++id)
80 SrcIterator iss = is + (-kright);
81 KernelIterator ik = kernel + kright;
82 SumType
sum = NumericTraits<SumType>::zero();
84 for(
int k = 0; k < kw; ++k, --ik, ++iss)
86 sum += ka(ik) * sa(iss);
89 da.set(detail::RequiresExplicitCast<
typename
90 DestAccessor::value_type>::cast(
sum),
id);
97template <
class SrcIterator,
class SrcAccessor,
98 class DestIterator,
class DestAccessor>
100copyLineWithBorderTreatment(SrcIterator is, SrcIterator iend, SrcAccessor sa,
101 DestIterator
id, DestAccessor da,
103 int kleft,
int kright,
104 BorderTreatmentMode borderTreatment)
106 int w = std::distance( is, iend );
107 int leftBorder = start - kright;
108 int rightBorder = stop - kleft;
109 int copyEnd = std::min(w, rightBorder);
113 switch(borderTreatment)
115 case BORDER_TREATMENT_WRAP:
117 for(; leftBorder<0; ++leftBorder, ++id)
118 da.set(sa(iend, leftBorder),
id);
121 case BORDER_TREATMENT_AVOID:
126 case BORDER_TREATMENT_REFLECT:
128 for(; leftBorder<0; ++leftBorder, ++id)
129 da.set(sa(is, -leftBorder),
id);
132 case BORDER_TREATMENT_REPEAT:
134 for(; leftBorder<0; ++leftBorder, ++id)
138 case BORDER_TREATMENT_CLIP:
140 vigra_precondition(
false,
141 "copyLineWithBorderTreatment() internal error: not applicable to BORDER_TREATMENT_CLIP.");
144 case BORDER_TREATMENT_ZEROPAD:
146 for(; leftBorder<0; ++leftBorder, ++id)
147 da.set(NumericTraits<typename DestAccessor::value_type>::zero(),
id);
152 vigra_precondition(
false,
153 "copyLineWithBorderTreatment(): Unknown border treatment mode.");
158 SrcIterator iss = is + leftBorder;
159 vigra_invariant( leftBorder < copyEnd,
160 "copyLineWithBorderTreatment(): assertion failed.");
161 for(; leftBorder<copyEnd; ++leftBorder, ++id, ++iss)
164 if(copyEnd < rightBorder)
166 switch(borderTreatment)
168 case BORDER_TREATMENT_WRAP:
170 for(; copyEnd<rightBorder; ++copyEnd, ++id, ++is)
174 case BORDER_TREATMENT_AVOID:
179 case BORDER_TREATMENT_REFLECT:
182 for(; copyEnd<rightBorder; ++copyEnd, ++id, --iss)
186 case BORDER_TREATMENT_REPEAT:
189 for(; copyEnd<rightBorder; ++copyEnd, ++id)
193 case BORDER_TREATMENT_CLIP:
195 vigra_precondition(
false,
196 "copyLineWithBorderTreatment() internal error: not applicable to BORDER_TREATMENT_CLIP.");
199 case BORDER_TREATMENT_ZEROPAD:
201 for(; copyEnd<rightBorder; ++copyEnd, ++id)
202 da.set(NumericTraits<typename DestAccessor::value_type>::zero(),
id);
207 vigra_precondition(
false,
208 "copyLineWithBorderTreatment(): Unknown border treatment mode.");
222template <
class SrcIterator,
class SrcAccessor,
223 class DestIterator,
class DestAccessor,
224 class KernelIterator,
class KernelAccessor>
225void internalConvolveLineWrap(SrcIterator is, SrcIterator iend, SrcAccessor sa,
226 DestIterator
id, DestAccessor da,
227 KernelIterator kernel, KernelAccessor ka,
228 int kleft,
int kright,
229 int start = 0,
int stop = 0)
231 int w = std::distance( is, iend );
233 typedef typename PromoteTraits<
234 typename SrcAccessor::value_type,
235 typename KernelAccessor::value_type>::Promote SumType;
237 SrcIterator ibegin = is;
243 for(
int x=start; x<stop; ++x, ++is, ++id)
245 KernelIterator ik = kernel + kright;
246 SumType
sum = NumericTraits<SumType>::zero();
251 SrcIterator iss = iend + x0;
253 for(; x0; ++x0, --ik, ++iss)
255 sum += ka(ik) * sa(iss);
261 SrcIterator isend = iend;
262 for(; iss != isend ; --ik, ++iss)
264 sum += ka(ik) * sa(iss);
267 int x0 = -kleft - w + x + 1;
270 for(; x0; --x0, --ik, ++iss)
272 sum += ka(ik) * sa(iss);
277 SrcIterator isend = is + (1 - kleft);
278 for(; iss != isend ; --ik, ++iss)
280 sum += ka(ik) * sa(iss);
284 else if(w-x <= -kleft)
286 SrcIterator iss = is + (-kright);
287 SrcIterator isend = iend;
288 for(; iss != isend ; --ik, ++iss)
290 sum += ka(ik) * sa(iss);
293 int x0 = -kleft - w + x + 1;
296 for(; x0; --x0, --ik, ++iss)
298 sum += ka(ik) * sa(iss);
303 SrcIterator iss = is - kright;
304 SrcIterator isend = is + (1 - kleft);
305 for(; iss != isend ; --ik, ++iss)
307 sum += ka(ik) * sa(iss);
311 da.set(detail::RequiresExplicitCast<
typename
312 DestAccessor::value_type>::cast(
sum),
id);
322template <
class SrcIterator,
class SrcAccessor,
323 class DestIterator,
class DestAccessor,
324 class KernelIterator,
class KernelAccessor,
326void internalConvolveLineClip(SrcIterator is, SrcIterator iend, SrcAccessor sa,
327 DestIterator
id, DestAccessor da,
328 KernelIterator kernel, KernelAccessor ka,
329 int kleft,
int kright, Norm
norm,
330 int start = 0,
int stop = 0)
332 int w = std::distance( is, iend );
334 typedef typename PromoteTraits<
335 typename SrcAccessor::value_type,
336 typename KernelAccessor::value_type>::Promote SumType;
338 SrcIterator ibegin = is;
344 for(
int x=start; x<stop; ++x, ++is, ++id)
346 KernelIterator ik = kernel + kright;
347 SumType
sum = NumericTraits<SumType>::zero();
352 Norm clipped = NumericTraits<Norm>::zero();
354 for(; x0; ++x0, --ik)
359 SrcIterator iss = ibegin;
362 SrcIterator isend = iend;
363 for(; iss != isend ; --ik, ++iss)
365 sum += ka(ik) * sa(iss);
368 int x0 = -kleft - w + x + 1;
370 for(; x0; --x0, --ik)
377 SrcIterator isend = is + (1 - kleft);
378 for(; iss != isend ; --ik, ++iss)
380 sum += ka(ik) * sa(iss);
386 else if(w-x <= -kleft)
388 SrcIterator iss = is + (-kright);
389 SrcIterator isend = iend;
390 for(; iss != isend ; --ik, ++iss)
392 sum += ka(ik) * sa(iss);
395 Norm clipped = NumericTraits<Norm>::zero();
397 int x0 = -kleft - w + x + 1;
399 for(; x0; --x0, --ik)
408 SrcIterator iss = is + (-kright);
409 SrcIterator isend = is + (1 - kleft);
410 for(; iss != isend ; --ik, ++iss)
412 sum += ka(ik) * sa(iss);
416 da.set(detail::RequiresExplicitCast<
typename
417 DestAccessor::value_type>::cast(
sum),
id);
427template <
class SrcIterator,
class SrcAccessor,
428 class DestIterator,
class DestAccessor,
429 class KernelIterator,
class KernelAccessor>
430void internalConvolveLineZeropad(SrcIterator is, SrcIterator iend, SrcAccessor sa,
431 DestIterator
id, DestAccessor da,
432 KernelIterator kernel, KernelAccessor ka,
433 int kleft,
int kright,
434 int start = 0,
int stop = 0)
436 int w = std::distance( is, iend );
438 typedef typename PromoteTraits<
439 typename SrcAccessor::value_type,
440 typename KernelAccessor::value_type>::Promote SumType;
442 SrcIterator ibegin = is;
448 for(
int x=start; x<stop; ++x, ++is, ++id)
450 SumType
sum = NumericTraits<SumType>::zero();
454 KernelIterator ik = kernel + x;
455 SrcIterator iss = ibegin;
459 SrcIterator isend = iend;
460 for(; iss != isend ; --ik, ++iss)
462 sum += ka(ik) * sa(iss);
467 SrcIterator isend = is + (1 - kleft);
468 for(; iss != isend ; --ik, ++iss)
470 sum += ka(ik) * sa(iss);
474 else if(w-x <= -kleft)
476 KernelIterator ik = kernel + kright;
477 SrcIterator iss = is + (-kright);
478 SrcIterator isend = iend;
479 for(; iss != isend ; --ik, ++iss)
481 sum += ka(ik) * sa(iss);
486 KernelIterator ik = kernel + kright;
487 SrcIterator iss = is + (-kright);
488 SrcIterator isend = is + (1 - kleft);
489 for(; iss != isend ; --ik, ++iss)
491 sum += ka(ik) * sa(iss);
495 da.set(detail::RequiresExplicitCast<
typename
496 DestAccessor::value_type>::cast(
sum),
id);
506template <
class SrcIterator,
class SrcAccessor,
507 class DestIterator,
class DestAccessor,
508 class KernelIterator,
class KernelAccessor>
509void internalConvolveLineReflect(SrcIterator is, SrcIterator iend, SrcAccessor sa,
510 DestIterator
id, DestAccessor da,
511 KernelIterator kernel, KernelAccessor ka,
512 int kleft,
int kright,
513 int start = 0,
int stop = 0)
515 int w = std::distance( is, iend );
517 typedef typename PromoteTraits<
518 typename SrcAccessor::value_type,
519 typename KernelAccessor::value_type>::Promote SumType;
521 SrcIterator ibegin = is;
527 for(
int x=start; x<stop; ++x, ++is, ++id)
529 KernelIterator ik = kernel + kright;
530 SumType
sum = NumericTraits<SumType>::zero();
535 SrcIterator iss = ibegin - x0;
537 for(; x0; ++x0, --ik, --iss)
539 sum += ka(ik) * sa(iss);
544 SrcIterator isend = iend;
545 for(; iss != isend ; --ik, ++iss)
547 sum += ka(ik) * sa(iss);
550 int x0 = -kleft - w + x + 1;
553 for(; x0; --x0, --ik, --iss)
555 sum += ka(ik) * sa(iss);
560 SrcIterator isend = is + (1 - kleft);
561 for(; iss != isend ; --ik, ++iss)
563 sum += ka(ik) * sa(iss);
567 else if(w-x <= -kleft)
569 SrcIterator iss = is + (-kright);
570 SrcIterator isend = iend;
571 for(; iss != isend ; --ik, ++iss)
573 sum += ka(ik) * sa(iss);
576 int x0 = -kleft - w + x + 1;
579 for(; x0; --x0, --ik, --iss)
581 sum += ka(ik) * sa(iss);
586 SrcIterator iss = is + (-kright);
587 SrcIterator isend = is + (1 - kleft);
588 for(; iss != isend ; --ik, ++iss)
590 sum += ka(ik) * sa(iss);
594 da.set(detail::RequiresExplicitCast<
typename
595 DestAccessor::value_type>::cast(
sum),
id);
605template <
class SrcIterator,
class SrcAccessor,
606 class DestIterator,
class DestAccessor,
607 class KernelIterator,
class KernelAccessor>
608void internalConvolveLineRepeat(SrcIterator is, SrcIterator iend, SrcAccessor sa,
609 DestIterator
id, DestAccessor da,
610 KernelIterator kernel, KernelAccessor ka,
611 int kleft,
int kright,
612 int start = 0,
int stop = 0)
614 int w = std::distance( is, iend );
616 typedef typename PromoteTraits<
617 typename SrcAccessor::value_type,
618 typename KernelAccessor::value_type>::Promote SumType;
620 SrcIterator ibegin = is;
626 for(
int x=start; x<stop; ++x, ++is, ++id)
628 KernelIterator ik = kernel + kright;
629 SumType
sum = NumericTraits<SumType>::zero();
634 SrcIterator iss = ibegin;
636 for(; x0; ++x0, --ik)
638 sum += ka(ik) * sa(iss);
643 SrcIterator isend = iend;
644 for(; iss != isend ; --ik, ++iss)
646 sum += ka(ik) * sa(iss);
649 int x0 = -kleft - w + x + 1;
652 for(; x0; --x0, --ik)
654 sum += ka(ik) * sa(iss);
659 SrcIterator isend = is + (1 - kleft);
660 for(; iss != isend ; --ik, ++iss)
662 sum += ka(ik) * sa(iss);
666 else if(w-x <= -kleft)
668 SrcIterator iss = is + (-kright);
669 SrcIterator isend = iend;
670 for(; iss != isend ; --ik, ++iss)
672 sum += ka(ik) * sa(iss);
675 int x0 = -kleft - w + x + 1;
678 for(; x0; --x0, --ik)
680 sum += ka(ik) * sa(iss);
685 SrcIterator iss = is + (-kright);
686 SrcIterator isend = is + (1 - kleft);
687 for(; iss != isend ; --ik, ++iss)
689 sum += ka(ik) * sa(iss);
693 da.set(detail::RequiresExplicitCast<
typename
694 DestAccessor::value_type>::cast(
sum),
id);
704template <
class SrcIterator,
class SrcAccessor,
705 class DestIterator,
class DestAccessor,
706 class KernelIterator,
class KernelAccessor>
707void internalConvolveLineAvoid(SrcIterator is, SrcIterator iend, SrcAccessor sa,
708 DestIterator
id, DestAccessor da,
709 KernelIterator kernel, KernelAccessor ka,
710 int kleft,
int kright,
711 int start = 0,
int stop = 0)
713 int w = std::distance( is, iend );
720 id += kright - start;
731 typedef typename PromoteTraits<
732 typename SrcAccessor::value_type,
733 typename KernelAccessor::value_type>::Promote SumType;
737 for(
int x=start; x<stop; ++x, ++is, ++id)
739 KernelIterator ik = kernel + kright;
740 SumType
sum = NumericTraits<SumType>::zero();
742 SrcIterator iss = is + (-kright);
743 SrcIterator isend = is + (1 - kleft);
744 for(; iss != isend ; --ik, ++iss)
746 sum += ka(ik) * sa(iss);
749 da.set(detail::RequiresExplicitCast<
typename
750 DestAccessor::value_type>::cast(
sum),
id);
903 int start = 0,
int stop = 0)
905 vigra_precondition(
kleft <= 0,
906 "convolveLine(): kleft must be <= 0.\n");
907 vigra_precondition(
kright >= 0,
908 "convolveLine(): kright must be >= 0.\n");
911 int w = std::distance(
is,
iend );
913 vigra_precondition(w >= std::max(
kright, -
kleft) + 1,
914 "convolveLine(): kernel longer than line.\n");
917 vigra_precondition(0 <= start && start < stop && stop <= w,
918 "convolveLine(): invalid subrange (start, stop).\n");
920 typedef typename PromoteTraits<
921 typename SrcAccessor::value_type,
922 typename KernelAccessor::value_type>::Promote SumType;
926 case BORDER_TREATMENT_WRAP:
928 internalConvolveLineWrap(
is,
iend,
sa,
id,
da,
ik,
ka,
kleft,
kright, start, stop);
931 case BORDER_TREATMENT_AVOID:
933 internalConvolveLineAvoid(
is,
iend,
sa,
id,
da,
ik,
ka,
kleft,
kright, start, stop);
936 case BORDER_TREATMENT_REFLECT:
938 internalConvolveLineReflect(
is,
iend,
sa,
id,
da,
ik,
ka,
kleft,
kright, start, stop);
941 case BORDER_TREATMENT_REPEAT:
943 internalConvolveLineRepeat(
is,
iend,
sa,
id,
da,
ik,
ka,
kleft,
kright, start, stop);
946 case BORDER_TREATMENT_CLIP:
949 typedef typename KernelAccessor::value_type
KT;
950 KT norm = NumericTraits<KT>::zero();
955 vigra_precondition(
norm != NumericTraits<KT>::zero(),
956 "convolveLine(): Norm of kernel must be != 0"
957 " in mode BORDER_TREATMENT_CLIP.\n");
959 internalConvolveLineClip(
is,
iend,
sa,
id,
da,
ik,
ka,
kleft,
kright,
norm, start, stop);
962 case BORDER_TREATMENT_ZEROPAD:
964 internalConvolveLineZeropad(
is,
iend,
sa,
id,
da,
ik,
ka,
kleft,
kright, start, stop);
969 vigra_precondition(0,
970 "convolveLine(): Unknown border treatment mode.\n");
975template <
class SrcIterator,
class SrcAccessor,
976 class DestIterator,
class DestAccessor,
977 class KernelIterator,
class KernelAccessor>
979void convolveLine(triple<SrcIterator, SrcIterator, SrcAccessor> src,
980 pair<DestIterator, DestAccessor> dest,
981 tuple5<KernelIterator, KernelAccessor,
982 int,
int, BorderTreatmentMode> kernel,
983 int start = 0,
int stop = 0)
986 dest.first, dest.second,
987 kernel.first, kernel.second,
988 kernel.third, kernel.fourth, kernel.fifth, start, stop);
1094 vigra_precondition(
kleft <= 0,
1095 "separableConvolveX(): kleft must be <= 0.\n");
1096 vigra_precondition(
kright >= 0,
1097 "separableConvolveX(): kright must be >= 0.\n");
1102 vigra_precondition(w >= std::max(
kright, -
kleft) + 1,
1103 "separableConvolveX(): kernel longer than line\n");
1109 typename SrcIterator::row_iterator
rs =
supperleft.rowIterator();
1110 typename DestIterator::row_iterator rd =
dupperleft.rowIterator();
1117template <
class SrcIterator,
class SrcAccessor,
1118 class DestIterator,
class DestAccessor,
1119 class KernelIterator,
class KernelAccessor>
1122 pair<DestIterator, DestAccessor> dest,
1123 tuple5<KernelIterator, KernelAccessor,
1124 int,
int, BorderTreatmentMode> kernel)
1127 dest.first, dest.second,
1128 kernel.first, kernel.second,
1129 kernel.third, kernel.fourth, kernel.fifth);
1132template <
class T1,
class S1,
1137 MultiArrayView<2, T2, S2> dest,
1138 Kernel1D<T3>
const & kernel)
1140 vigra_precondition(src.shape() == dest.shape(),
1141 "separableConvolveX(): shape mismatch between input and output.");
1143 destImage(dest), kernel1d(kernel));
1249 vigra_precondition(
kleft <= 0,
1250 "separableConvolveY(): kleft must be <= 0.\n");
1251 vigra_precondition(
kright >= 0,
1252 "separableConvolveY(): kright must be >= 0.\n");
1258 "separableConvolveY(): kernel longer than line\n");
1264 typename SrcIterator::column_iterator
cs =
supperleft.columnIterator();
1265 typename DestIterator::column_iterator cd =
dupperleft.columnIterator();
1272template <
class SrcIterator,
class SrcAccessor,
1273 class DestIterator,
class DestAccessor,
1274 class KernelIterator,
class KernelAccessor>
1277 pair<DestIterator, DestAccessor> dest,
1278 tuple5<KernelIterator, KernelAccessor,
1279 int,
int, BorderTreatmentMode> kernel)
1282 dest.first, dest.second,
1283 kernel.first, kernel.second,
1284 kernel.third, kernel.fourth, kernel.fifth);
1287template <
class T1,
class S1,
1292 MultiArrayView<2, T2, S2> dest,
1293 Kernel1D<T3>
const & kernel)
1295 vigra_precondition(src.shape() == dest.shape(),
1296 "separableConvolveY(): shape mismatch between input and output.");
1298 destImage(dest), kernel1d(kernel));
1365template <
class ARITHTYPE =
double>
1406 : iter_(
i), base_(
i),
1407 count_(count), sum_(count),
1412#if _MSC_VER >= 1900 || __cplusplus >= 201103L
1415 throw(PreconditionViolation)
1418 vigra_precondition(count_ == 1 || count_ == sum_,
1419 "Kernel1D::initExplicitly(): "
1420 "Wrong number of init values.");
1445 static value_type one() {
return NumericTraits<value_type>::one(); }
1455 border_treatment_(BORDER_TREATMENT_REFLECT),
1458 kernel_.push_back(norm_);
1464 : kernel_(
k.kernel_),
1467 border_treatment_(
k.border_treatment_),
1490 border_treatment_ =
k.border_treatment_;
1492 kernel_ =
k.kernel_;
1515 int size = right_ - left_ + 1;
1516 for(
unsigned int i=0;
i<kernel_.
size(); ++
i) kernel_[
i] = v;
1519 return InitProxy(kernel_.
begin(),
size, norm_);
1735 this->
initExplicitly(-2, 2) = 0.03134, 0.24, 0.45732, 0.24, 0.03134;
1763 this->
initExplicitly(-2, 2) = 0.04255, 0.241, 0.4329, 0.241, 0.04255;
1791 this->
initExplicitly(-2, 2) = 0.0243, 0.23556, 0.48028, 0.23556, 0.0243;
1826 vigra_precondition(a >= 0.0 && a <= 0.125,
1827 "Kernel1D::initBurtFilter(): 0 <= a <= 0.125 required.");
2062 this->
initExplicitly(-2, 2) = 0.22075, 0.117, -0.6755, 0.117, 0.22075;
2102 vigra_precondition(
left <= 0,
2103 "Kernel1D::initExplicitly(): left border must be <= 0.");
2104 vigra_precondition(
right >= 0,
2105 "Kernel1D::initExplicitly(): right border must be >= 0.");
2161 int size()
const {
return right_ - left_ + 1; }
2166 {
return border_treatment_; }
2200 InternalVector kernel_;
2202 BorderTreatmentMode border_treatment_;
2206template <
class ARITHTYPE>
2208 unsigned int derivativeOrder,
2211 typedef typename NumericTraits<value_type>::RealPromote
TmpType;
2215 TmpType sum = NumericTraits<TmpType>::zero();
2217 if(derivativeOrder == 0)
2219 for(;
k < kernel_.
end(); ++
k)
2227 for(
unsigned int i = 2;
i <= derivativeOrder; ++
i)
2229 for(
double x = left() +
offset;
k < kernel_.
end(); ++x, ++
k)
2235 vigra_precondition(
sum != NumericTraits<value_type>::zero(),
2236 "Kernel1D<ARITHTYPE>::normalize(): "
2237 "Cannot normalize a kernel with sum = 0");
2241 for(;
k != kernel_.
end(); ++
k)
2251template <
class ARITHTYPE>
2257 vigra_precondition(
std_dev >= 0.0,
2258 "Kernel1D::initGaussian(): Standard deviation must be >= 0.");
2260 "Kernel1D::initGaussian(): windowRatio must be >= 0.");
2276 kernel_.erase(kernel_.begin(), kernel_.end());
2277 kernel_.reserve(radius*2+1);
2281 kernel_.push_back(
gauss(x));
2288 kernel_.erase(kernel_.begin(), kernel_.end());
2289 kernel_.push_back(1.0);
2300 border_treatment_ = BORDER_TREATMENT_REFLECT;
2305template <
class ARITHTYPE>
2310 vigra_precondition(
std_dev >= 0.0,
2311 "Kernel1D::initDiscreteGaussian(): Standard deviation must be >= 0.");
2323 int maxIndex = (
int)(2.0 * (radius + 5.0 * VIGRA_CSTD::sqrt((
double)radius)) + 0.5);
2326 warray[maxIndex-1] = 1.0;
2328 for(
int i = maxIndex-2;
i >= radius; --
i)
2344 for(
int i = radius-1;
i >= 0; --
i)
2352 initExplicitly(-radius, radius);
2355 for(
int i=0;
i<=radius; ++
i)
2362 kernel_.erase(kernel_.begin(), kernel_.end());
2363 kernel_.push_back(
norm);
2371 border_treatment_ = BORDER_TREATMENT_REFLECT;
2376template <
class ARITHTYPE>
2383 vigra_precondition(order >= 0,
2384 "Kernel1D::initGaussianDerivative(): Order must be >= 0.");
2392 vigra_precondition(
std_dev > 0.0,
2393 "Kernel1D::initGaussianDerivative(): "
2394 "Standard deviation must be > 0.");
2396 "Kernel1D::initGaussianDerivative(): windowRatio must be >= 0.");
2403 radius = (
int)((3.0 + 0.5 * order) *
std_dev + 0.5);
2411 kernel_.reserve(radius*2+1);
2418 kernel_.push_back(
gauss(x));
2419 dc += kernel_[kernel_.size()-1];
2427 for(
unsigned int i=0;
i < kernel_.
size(); ++
i)
2437 normalize(
norm, order);
2443 border_treatment_ = BORDER_TREATMENT_REFLECT;
2448template <
class ARITHTYPE>
2453 vigra_precondition(radius > 0,
2454 "Kernel1D::initBinomial(): Radius must be > 0.");
2462 for(
int j=radius-1;
j>=-radius; --
j)
2464 x[
j] = 0.5 * x[
j+1];
2465 for(
int i=
j+1;
i<radius; ++
i)
2467 x[
i] = 0.5 * (x[
i] + x[
i+1]);
2477 border_treatment_ = BORDER_TREATMENT_REFLECT;
2482template <
class ARITHTYPE>
2487 vigra_precondition(radius > 0,
2488 "Kernel1D::initAveraging(): Radius must be > 0.");
2491 double scale = 1.0 / (radius * 2 + 1);
2494 kernel_.erase(kernel_.begin(), kernel_.end());
2495 kernel_.reserve(radius*2+1);
2497 for(
int i=0;
i<=radius*2+1; ++
i)
2499 kernel_.push_back(scale *
norm);
2507 border_treatment_ = BORDER_TREATMENT_CLIP;
2512template <
class ARITHTYPE>
2516 kernel_.erase(kernel_.begin(), kernel_.end());
2529 border_treatment_ = BORDER_TREATMENT_REFLECT;
2540template <
class KernelIterator,
class KernelAccessor>
2542tuple5<KernelIterator, KernelAccessor, int, int, BorderTreatmentMode>
2543kernel1d(KernelIterator ik, KernelAccessor ka,
2544 int kleft,
int kright, BorderTreatmentMode border)
2547 tuple5<KernelIterator, KernelAccessor, int, int, BorderTreatmentMode>(
2548 ik, ka, kleft, kright, border);
2554 int, int, BorderTreatmentMode>
2555kernel1d(Kernel1D<T>
const & k)
2560 int, int, BorderTreatmentMode>(
2563 k.left(), k.right(),
2564 k.borderTreatment());
2570 int, int, BorderTreatmentMode>
2571kernel1d(Kernel1D<T>
const & k, BorderTreatmentMode border)
2576 int, int, BorderTreatmentMode>(
2579 k.left(), k.right(),
Generic 1 dimensional convolution kernel.
Definition separableconvolution.hxx:1367
void initBinomial(int radius)
Definition separableconvolution.hxx:1853
void initOptimalFirstDerivativeSmoothing5()
Definition separableconvolution.hxx:1761
void initSecondDifference3()
Definition separableconvolution.hxx:1999
void initOptimalSecondDerivativeSmoothing3()
Definition separableconvolution.hxx:1707
InternalVector::reference reference
Definition separableconvolution.hxx:1377
void initBurtFilter(double a=0.04785)
Definition separableconvolution.hxx:1824
void initDiscreteGaussian(double std_dev)
Definition separableconvolution.hxx:1584
void initBackwardDifference()
Definition separableconvolution.hxx:1955
void initOptimalFirstDerivative5()
Definition separableconvolution.hxx:2031
int right() const
Definition separableconvolution.hxx:2157
value_type norm() const
Definition separableconvolution.hxx:2175
reference operator[](int location)
Definition separableconvolution.hxx:2141
Kernel1D(Kernel1D< U > const &k)
Definition separableconvolution.hxx:1474
void initGaussian(double std_dev, value_type norm, double windowRatio=0.0)
Definition separableconvolution.hxx:2253
InitProxy operator=(value_type const &v)
Definition separableconvolution.hxx:1513
void initSymmetricGradient()
Definition separableconvolution.hxx:1908
BorderTreatmentMode borderTreatment() const
Definition separableconvolution.hxx:2165
void setBorderTreatment(BorderTreatmentMode new_mode)
Definition separableconvolution.hxx:2170
StandardAccessor< ARITHTYPE > Accessor
Definition separableconvolution.hxx:1397
void initOptimalSmoothing5()
Definition separableconvolution.hxx:1733
ConstAccessor accessor() const
Definition separableconvolution.hxx:2193
void initGaussianDerivative(double std_dev, int order)
Definition separableconvolution.hxx:1626
void initDiscreteGaussian(double std_dev, value_type norm)
Definition separableconvolution.hxx:2307
InternalVector::value_type value_type
Definition separableconvolution.hxx:1373
void initGaussianDerivative(double std_dev, int order, value_type norm, double windowRatio=0.0)
Definition separableconvolution.hxx:2378
InternalVector::iterator iterator
Definition separableconvolution.hxx:1389
~Kernel1D()
Definition separableconvolution.hxx:1524
void initSymmetricDifference()
Definition separableconvolution.hxx:1978
void initAveraging(int radius)
Definition separableconvolution.hxx:1879
StandardConstAccessor< ARITHTYPE > ConstAccessor
Definition separableconvolution.hxx:1401
Kernel1D(Kernel1D const &k)
Definition separableconvolution.hxx:1463
void initOptimalSecondDerivative5()
Definition separableconvolution.hxx:2060
InternalVector::const_iterator const_iterator
Definition separableconvolution.hxx:1393
InternalVector::const_reference const_reference
Definition separableconvolution.hxx:1381
void initAveraging(int radius, value_type norm)
Definition separableconvolution.hxx:2484
void initSymmetricGradient(value_type norm)
Definition separableconvolution.hxx:1898
void initGaussian(double std_dev)
Definition separableconvolution.hxx:1556
void initOptimalSecondDerivativeSmoothing5()
Definition separableconvolution.hxx:1789
int left() const
Definition separableconvolution.hxx:2153
Accessor accessor()
Definition separableconvolution.hxx:2197
Kernel1D()
Definition separableconvolution.hxx:1451
void initBinomial(int radius, value_type norm)
Definition separableconvolution.hxx:2450
void normalize()
Definition separableconvolution.hxx:2186
void initForwardDifference()
Definition separableconvolution.hxx:1931
InternalVector::iterator Iterator
Definition separableconvolution.hxx:1385
Kernel1D & initExplicitly(int left, int right)
Definition separableconvolution.hxx:2100
void initOptimalSmoothing3()
Definition separableconvolution.hxx:1651
void initOptimalFirstDerivativeSmoothing3()
Definition separableconvolution.hxx:1679
int size() const
Definition separableconvolution.hxx:2161
iterator center()
Definition separableconvolution.hxx:2123
Kernel1D & operator=(Kernel1D const &k)
Definition separableconvolution.hxx:1484
Class for a single RGB value.
Definition rgbvalue.hxx:128
RGBValue()
Definition rgbvalue.hxx:209
size_type size() const
Definition tinyvector.hxx:913
iterator end()
Definition tinyvector.hxx:864
iterator begin()
Definition tinyvector.hxx:861
void convolveLine(...)
Performs a 1-dimensional convolution of the source signal using the given kernel.
void separableConvolveX(...)
Performs a 1 dimensional convolution in x direction.
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition fftw3.hxx:1037
void separableConvolveY(...)
Performs a 1 dimensional convolution in y direction.
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition tinyvector.hxx:2073