36#ifndef VIGRA_RESAMPLING_CONVOLUTION_HXX
37#define VIGRA_RESAMPLING_CONVOLUTION_HXX
40#include "stdimage.hxx"
41#include "array_vector.hxx"
42#include "rational.hxx"
43#include "functortraits.hxx"
44#include "functorexpression.hxx"
45#include "transformimage.hxx"
46#include "imagecontainer.hxx"
47#include "multi_shape.hxx"
51namespace resampling_detail
54struct MapTargetToSourceCoordinate
56 MapTargetToSourceCoordinate(Rational<int>
const & samplingRatio,
57 Rational<int>
const & offset)
58 : a(samplingRatio.denominator()*offset.denominator()),
59 b(samplingRatio.numerator()*offset.numerator()),
60 c(samplingRatio.numerator()*offset.denominator())
67 int operator()(
int i)
const
69 return (i * a + b) / c;
72 double toDouble(
int i)
const
74 return double(i * a + b) / c;
77 Rational<int> toRational(
int i)
const
79 return Rational<int>(i * a + b, c);
82 bool isExpand2()
const
84 return a == 1 && b == 0 && c == 2;
87 bool isReduce2()
const
89 return a == 2 && b == 0 && c == 1;
98class FunctorTraits<resampling_detail::MapTargetToSourceCoordinate>
99:
public FunctorTraitsBase<resampling_detail::MapTargetToSourceCoordinate>
102 typedef VigraTrueType isUnaryFunctor;
105template <
class SrcIter,
class SrcAcc,
106 class DestIter,
class DestAcc,
109resamplingExpandLine2(SrcIter s, SrcIter send, SrcAcc src,
110 DestIter d, DestIter dend, DestAcc dest,
111 KernelArray
const & kernels)
113 typedef typename KernelArray::value_type Kernel;
114 typedef typename KernelArray::const_reference KernelRef;
115 typedef typename Kernel::const_iterator KernelIter;
118 PromoteTraits<typename SrcAcc::value_type, typename Kernel::value_type>::Promote
125 int ileft = std::max(kernels[0].right(), kernels[1].right());
126 int iright = wo + std::min(kernels[0].left(), kernels[1].left()) - 1;
127 for(
int i = 0; i < wn; ++i, ++d)
130 KernelRef kernel = kernels[i & 1];
131 KernelIter k = kernel.center() + kernel.right();
132 TmpType
sum = NumericTraits<TmpType>::zero();
135 for(
int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
140 sum += *k * src(s, mm);
145 for(
int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
150 sum += *k * src(s, mm);
155 SrcIter ss = s + is - kernel.right();
156 for(
int m = 0; m < kernel.size(); ++m, --k, ++ss)
165template <
class SrcIter,
class SrcAcc,
166 class DestIter,
class DestAcc,
169resamplingReduceLine2(SrcIter s, SrcIter send, SrcAcc src,
170 DestIter d, DestIter dend, DestAcc dest,
171 KernelArray
const & kernels)
173 typedef typename KernelArray::value_type Kernel;
174 typedef typename KernelArray::const_reference KernelRef;
175 typedef typename Kernel::const_iterator KernelIter;
177 KernelRef kernel = kernels[0];
178 KernelIter kbegin = kernel.center() + kernel.right();
181 PromoteTraits<typename SrcAcc::value_type, typename Kernel::value_type>::Promote
188 int ileft = kernel.right();
189 int iright = wo + kernel.left() - 1;
190 for(
int i = 0; i < wn; ++i, ++d)
193 KernelIter k = kbegin;
194 TmpType
sum = NumericTraits<TmpType>::zero();
197 for(
int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
202 sum += *k * src(s, mm);
207 for(
int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
212 sum += *k * src(s, mm);
217 SrcIter ss = s + is - kernel.right();
218 for(
int m = 0; m < kernel.size(); ++m, --k, ++ss)
293 NumericTraits<typename SrcAcc::value_type>::RealPromote
295 typedef typename KernelArray::value_type
Kernel;
296 typedef typename Kernel::const_iterator
KernelIter;
322 "resamplingConvolveLine(): kernel or offset larger than image.");
348template <
class Kernel,
class MapCoordinate,
class KernelArray>
350createResamplingKernels(Kernel
const & kernel,
351 MapCoordinate
const & mapCoordinate, KernelArray & kernels)
353 for(
unsigned int idest = 0; idest < kernels.size(); ++idest)
355 int isrc = mapCoordinate(idest);
356 double idsrc = mapCoordinate.toDouble(idest);
357 double offset = idsrc - isrc;
358 double radius = kernel.radius();
359 int left = std::min(0,
int(ceil(-radius - offset)));
360 int right = std::max(0,
int(floor(radius - offset)));
361 kernels[idest].initExplicitly(left, right);
363 double x = left + offset;
364 for(
int i = left; i <= right; ++i, ++x)
365 kernels[idest][i] = kernel(x);
366 kernels[idest].normalize(1.0, kernel.derivativeOrder(), offset);
498 "resamplingConvolveX(): sampling ratio must be > 0 and < infinity");
499 vigra_precondition(!
offset.is_inf(),
500 "resamplingConvolveX(): offset must be < infinity");
511 typename SrcIter::row_iterator
sr =
sul.rowIterator();
512 typename DestIter::row_iterator
dr =
dul.rowIterator();
518template <
class SrcIter,
class SrcAcc,
519 class DestIter,
class DestAcc,
523 triple<DestIter, DestIter, DestAcc> dest,
524 Kernel
const & kernel,
525 Rational<int>
const & samplingRatio, Rational<int>
const & offset)
528 dest.first, dest.second, dest.third,
529 kernel, samplingRatio, offset);
532template <
class T1,
class S1,
537 MultiArrayView<2, T2, S2> dest,
538 Kernel
const & kernel,
539 Rational<int>
const & samplingRatio, Rational<int>
const & offset)
542 destImageRange(dest),
543 kernel, samplingRatio, offset);
680 "resamplingConvolveY(): sampling ratio must be > 0 and < infinity");
681 vigra_precondition(!
offset.is_inf(),
682 "resamplingConvolveY(): offset must be < infinity");
694 typename SrcIter::column_iterator
sc =
sul.columnIterator();
695 typename DestIter::column_iterator
dc =
dul.columnIterator();
701template <
class SrcIter,
class SrcAccessor,
702 class DestIter,
class DestAccessor,
706 triple<DestIter, DestIter, DestAccessor> dest,
707 Kernel
const & kernel,
708 Rational<int>
const & samplingRatio, Rational<int>
const & offset)
711 dest.first, dest.second, dest.third,
712 kernel, samplingRatio, offset);
715template <
class T1,
class S1,
720 MultiArrayView<2, T2, S2> dest,
721 Kernel
const & kernel,
722 Rational<int>
const & samplingRatio, Rational<int>
const & offset)
725 destImageRange(dest),
726 kernel, samplingRatio, offset);
826 NumericTraits<typename SrcAccessor::value_type>::RealPromote
839template <
class SrcIterator,
class SrcAccessor,
840 class DestIterator,
class DestAccessor,
841 class KernelX,
class KernelY>
844 triple<DestIterator, DestIterator, DestAccessor> dest,
846 Rational<int>
const & samplingRatioX, Rational<int>
const & offsetX,
848 Rational<int>
const & samplingRatioY, Rational<int>
const & offsetY)
851 dest.first, dest.second, dest.third,
852 kx, samplingRatioX, offsetX,
853 ky, samplingRatioY, offsetY);
856template <
class T1,
class S1,
858 class KernelX,
class KernelY>
861 MultiArrayView<2, T2, S2> dest,
863 Rational<int>
const & samplingRatioX, Rational<int>
const & offsetX,
865 Rational<int>
const & samplingRatioY, Rational<int>
const & offsetY)
868 destImageRange(dest),
869 kx, samplingRatioX, offsetX,
870 ky, samplingRatioY, offsetY);
952 "pyramidReduceBurtFilter(): centerValue must be between 0.25 and 0.5.");
960 "pyramidReduceBurtFilter(): destSize = ceil(srcSize / 2) required.");
969 NumericTraits<typename SrcAccessor::value_type>::RealPromote
980 typename SrcIterator::row_iterator
sr =
sul.rowIterator();
981 typename TmpIterator::row_iterator
tr =
tul.rowIterator();
991 typename DestIterator::column_iterator
dc =
dul.columnIterator();
992 typename TmpIterator::column_iterator
tc =
tul.columnIterator();
998template <
class SrcIterator,
class SrcAccessor,
999 class DestIterator,
class DestAccessor>
1002 triple<DestIterator, DestIterator, DestAccessor> dest,
1003 double centerValue = 0.4)
1006 dest.first, dest.second, dest.third, centerValue);
1009template <
class Image,
class Alloc>
1012 int fromLevel,
int toLevel,
1013 double centerValue = 0.4)
1015 vigra_precondition(fromLevel < toLevel,
1016 "pyramidReduceBurtFilter(): fromLevel must be smaller than toLevel.");
1017 vigra_precondition(pyramid.lowestLevel() <= fromLevel && toLevel <= pyramid.highestLevel(),
1018 "pyramidReduceBurtFilter(): fromLevel and toLevel must be between the lowest and highest pyramid levels (inclusive).");
1020 for(
int i=fromLevel+1; i <= toLevel; ++i)
1106 "pyramidExpandBurtFilter(): centerValue must be between 0.25 and 0.5.");
1114 "pyramidExpandBurtFilter(): oldSize = ceil(newSize / 2) required.");
1121 kernels[1].initExplicitly(-1, 0) = 0.5, 0.5;
1124 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1135 typename SrcIterator::row_iterator
sr =
sul.rowIterator();
1136 typename TmpIterator::row_iterator
tr =
tul.rowIterator();
1146 typename DestIterator::column_iterator
dc =
dul.columnIterator();
1147 typename TmpIterator::column_iterator
tc =
tul.columnIterator();
1153template <
class SrcIterator,
class SrcAccessor,
1154 class DestIterator,
class DestAccessor>
1157 triple<DestIterator, DestIterator, DestAccessor> dest,
1158 double centerValue = 0.4)
1161 dest.first, dest.second, dest.third, centerValue);
1165template <
class Image,
class Alloc>
1168 double centerValue = 0.4)
1170 vigra_precondition(fromLevel > toLevel,
1171 "pyramidExpandBurtFilter(): fromLevel must be larger than toLevel.");
1172 vigra_precondition(pyramid.lowestLevel() <= toLevel && fromLevel <= pyramid.highestLevel(),
1173 "pyramidExpandBurtFilter(): fromLevel and toLevel must be between the lowest and highest pyramid levels (inclusive).");
1175 for(
int i=fromLevel-1; i >= toLevel; --i)
1195template <
class Image,
class Alloc>
1201 using namespace functor;
1228template <
class Image,
class Alloc>
1234 using namespace functor;
1237 "pyramidExpandBurtLaplacian(): fromLevel must be larger than toLevel.");
1239 "pyramidExpandBurtLaplacian(): fromLevel and toLevel must be between the lowest and highest pyramid levels (inclusive).");
Class for a single RGB value.
Definition rgbvalue.hxx:128
iterator end()
Definition tinyvector.hxx:864
iterator begin()
Definition tinyvector.hxx:861
void resamplingConvolveLine(...)
Performs a 1-dimensional resampling convolution of the source signal using the given set of kernels.
void pyramidExpandBurtFilter(...)
Two-fold up-sampling for image pyramid reconstruction.
void pyramidReduceBurtLaplacian(ImagePyramid< Image, Alloc > &pyramid, int fromLevel, int toLevel, double centerValue=0.4)
Create a Laplacian pyramid.
Definition resampling_convolution.hxx:1197
void resamplingConvolveImage(...)
Apply two separable resampling filters successively, the first in x-direction, the second in y-direct...
IntType lcm(IntType n, IntType m)
Definition rational.hxx:122
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition tinyvector.hxx:2073
void combineTwoImages(...)
Combine two source images into destination image.
void resamplingConvolveY(...)
Apply a resampling filter in the y-direction.
void pyramidReduceBurtFilter(...)
Two-fold down-sampling for image pyramid construction.
void pyramidExpandBurtLaplacian(ImagePyramid< Image, Alloc > &pyramid, int fromLevel, int toLevel, double centerValue=0.4)
Reconstruct a Laplacian pyramid.
Definition resampling_convolution.hxx:1230
void resamplingConvolveX(...)
Apply a resampling filter in the x-direction.