[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

multi_resize.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2004 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36
37 #ifndef VIGRA_MULTI_RESIZE_HXX
38 #define VIGRA_MULTI_RESIZE_HXX
39
40 #include <vector>
41 #include "resizeimage.hxx"
42 #include "navigator.hxx"
43 #include "multi_shape.hxx"
44
45 namespace vigra {
46
47 namespace detail {
48
49 template <class SrcIterator, class Shape, class SrcAccessor,
50 class DestIterator, class DestAccessor, class Kernel>
51 void
52 internalResizeMultiArrayOneDimension(
53 SrcIterator si, Shape const & sshape, SrcAccessor src,
54 DestIterator di, Shape const & dshape, DestAccessor dest,
55 Kernel const & spline, unsigned int d)
56 {
57 enum { N = 1 + SrcIterator::level };
58
59 typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
60
61 typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
62 typedef MultiArrayNavigator<DestIterator, N> DNavigator;
63
64 SNavigator snav( si, sshape, d );
65 DNavigator dnav( di, dshape, d );
66
67 int ssize = sshape[d];
68 int dsize = dshape[d];
69
70 vigra_precondition(ssize > 1,
71 "resizeMultiArraySplineInterpolation(): "
72 "Source array too small.\n");
73
74 Rational<int> ratio(dsize - 1, ssize - 1);
75 Rational<int> offset(0);
76 resampling_detail::MapTargetToSourceCoordinate mapCoordinate(ratio, offset);
77 int period = lcm(ratio.numerator(), ratio.denominator());
78
79 ArrayVector<double> const & prefilterCoeffs = spline.prefilterCoefficients();
80 ArrayVector<Kernel1D<double> > kernels(period);
81 createResamplingKernels(spline, mapCoordinate, kernels);
82
83 // temporary array to hold the current line to enable in-place operation
84 ArrayVector<TmpType> tmp( ssize );
85 typename ArrayVector<TmpType>::iterator t = tmp.begin(), tend = tmp.end();
86 typename AccessorTraits<TmpType>::default_accessor ta;
87
88 for( ; snav.hasMore(); snav++, dnav++ )
89 {
90 // first copy source to temp for maximum cache efficiency
91 copyLine( snav.begin(), snav.end(), src, t, ta);
92
93 for(unsigned int b = 0; b < prefilterCoeffs.size(); ++b)
94 {
95 recursiveFilterLine(t, tend, ta, t, ta,
96 prefilterCoeffs[b], BORDER_TREATMENT_REFLECT);
97 }
98 resamplingConvolveLine(t, tend, ta,
99 dnav.begin(), dnav.begin() + dsize, dest,
100 kernels, mapCoordinate);
101 }
102 }
103
104 } // namespace detail
105
106 /** \addtogroup GeometricTransformations
107 */
108 //@{
109
110
111 /***************************************************************/
112 /* */
113 /* resizeMultiArraySplineInterpolation */
114 /* */
115 /***************************************************************/
116
117 /** \brief Resize MultiArray using B-spline interpolation.
118
119 <b> Declarations:</b>
120
121 pass arbitrary-dimensional array views:
122 \code
123 namespace vigra {
124 template <unsigned int N, class T1, class S1,
125 class T2, class S2,
126 class Kernel = BSpline<3, double> >
127 void
128 resizeMultiArraySplineInterpolation(MultiArrayView<N, T1, S1> const & source,
129 MultiArrayView<N, T2, S2> dest,
130 Kernel const & spline = BSpline<3, double>());
131 }
132 \endcode
133
134 \deprecatedAPI{resizeMultiArraySplineInterpolation}
135 pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
136 \code
137 namespace vigra {
138 template <class SrcIterator, class Shape, class SrcAccessor,
139 class DestIterator, class DestAccessor,
140 class Kernel = BSpline<3, double> >
141 void
142 resizeMultiArraySplineInterpolation(
143 SrcIterator si, Shape const & sshape, SrcAccessor src,
144 DestIterator di, Shape const & dshape, DestAccessor dest,
145 Kernel const & spline = BSpline<3, double>());
146 }
147 \endcode
148 use argument objects in conjunction with \ref ArgumentObjectFactories :
149 \code
150 namespace vigra {
151 template <class SrcIterator, class Shape, class SrcAccessor,
152 class DestIterator, class DestAccessor,
153 class Kernel = BSpline<3, double> >
154 void
155 resizeMultiArraySplineInterpolation(
156 triple<SrcIterator, Shape, SrcAccessor> src,
157 triple<DestIterator, Shape, DestAccessor> dest,
158 Kernel const & spline = BSpline<3, double>());
159 }
160 \endcode
161 \deprecatedEnd
162
163 The function implements separable spline interpolation algorithm described in
164
165 M. Unser, A. Aldroubi, M. Eden, <i>"B-Spline Signal Processing"</i>
166 IEEE Transactions on Signal Processing, vol. 41, no. 2, pp. 821-833 (part I),
167 pp. 834-848 (part II), 1993.
168
169 to obtain optimal interpolation quality and speed. You may pass the function
170 a spline of arbitrary order (e.g. <TT>BSpline<ORDER, double></tt> or
171 <TT>CatmullRomSpline<double></tt>). The default is a third order spline
172 which gives a twice continuously differentiable interpolant.
173 The implementation ensures that image values are interpolated rather
174 than smoothed by first calling a recursive (sharpening) prefilter as
175 described in the above paper. Then the actual interpolation is done
176 using \ref resamplingConvolveLine().
177
178 The range of both the input and output images (resp. regions)
179 must be given. The input image must have a size of at
180 least 4x4, the destination of at least 2x2. The scaling factors are then calculated
181 accordingly. If the source image is larger than the destination, it
182 is smoothed (band limited) using a recursive
183 exponential filter. The source value_type (SrcAccessor::value_type) must
184 be a linear algebra, i.e. it must support addition, subtraction,
185 and multiplication (+, -, *), multiplication with a scalar
186 real number and \ref NumericTraits "NumericTraits".
187 The function uses accessors.
188
189 <b> Usage:</b>
190
191 <b>\#include</b> <vigra/multi_resize.hxx><br>
192 Namespace: vigra
193
194 \code
195 MultiArray<3, float> src(Shape3(5, 7, 10)),
196 dest(Shape3(9, 13, 19)); // double the size
197
198 // use default cubic spline interpolator
199 resizeMultiArraySplineInterpolation(src, dest);
200
201 // use linear interpolator
202 resizeMultiArraySplineInterpolation(src, dest, BSpline<1, double>());
203 \endcode
204
205 \deprecatedUsage{resizeMultiArraySplineInterpolation}
206 \code
207 vigra::MultiArray<3, float> src(Shape3(5, 7, 10)),
208 dest(Shape3(9, 13, 19)); // double the size
209
210 // use linear interpolator
211 vigra::resizeMultiArraySplineInterpolation(srcMultiArrayRange(src),
212 destMultiArrayRange(dest), BSpline<1, double>());
213
214 // use default cubic spline interpolator
215 vigra::resizeMultiArraySplineInterpolation(
216 srcMultiArrayRange(src),
217 destMultiArrayRange(dest));
218
219 \endcode
220 <b> Required Interface:</b>
221 The source and destination iterators must be compatible with \ref vigra::MultiIterator. The array value
222 types must be models of \ref LinearSpace.
223 \deprecatedEnd
224 */
225 doxygen_overloaded_function(template <...> void resizeMultiArraySplineInterpolation)
226
227 template <class SrcIterator, class Shape, class SrcAccessor,
228 class DestIterator, class DestAccessor,
229 class Kernel>
230 void
231 resizeMultiArraySplineInterpolation(
232 SrcIterator si, Shape const & sshape, SrcAccessor src,
233 DestIterator di, Shape const & dshape, DestAccessor dest,
234 Kernel const & spline)
235 {
236 enum { N = 1 + SrcIterator::level };
237 typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
238 typedef typename AccessorTraits<TmpType>::default_accessor TmpAccessor;
239
240 if(N==1)
241 {
242 detail::internalResizeMultiArrayOneDimension(si, sshape, src,
243 di, dshape, dest, spline, 0);
244 }
245 else
246 {
247 unsigned int d = 0;
248 Shape tmpShape(sshape);
249 tmpShape[d] = dshape[d];
250 MultiArray<N, TmpType> tmp(tmpShape);
251 TmpAccessor ta;
252
253 detail::internalResizeMultiArrayOneDimension(si, sshape, src,
254 tmp.traverser_begin(), tmpShape, ta, spline, d);
255 d = 1;
256 for(; d<N-1; ++d)
257 {
258 tmpShape[d] = dshape[d];
259 MultiArray<N, TmpType> dtmp(tmpShape);
260
261 detail::internalResizeMultiArrayOneDimension(tmp.traverser_begin(), tmp.shape(), ta,
262 dtmp.traverser_begin(), tmpShape, ta, spline, d);
263 dtmp.swap(tmp);
264 }
265 detail::internalResizeMultiArrayOneDimension(tmp.traverser_begin(), tmp.shape(), ta,
266 di, dshape, dest, spline, d);
267 }
268 }
269
270 template <class SrcIterator, class Shape, class SrcAccessor,
271 class DestIterator, class DestAccessor>
272 inline void
273 resizeMultiArraySplineInterpolation(
274 SrcIterator si, Shape const & sshape, SrcAccessor src,
275 DestIterator di, Shape const & dshape, DestAccessor dest)
276 {
277 resizeMultiArraySplineInterpolation(si, sshape, src, di, dshape, dest, BSpline<3, double>());
278 }
279
280 template <class SrcIterator, class Shape, class SrcAccessor,
281 class DestIterator, class DestAccessor,
282 class Kernel>
283 inline void
284 resizeMultiArraySplineInterpolation(triple<SrcIterator, Shape, SrcAccessor> src,
285 triple<DestIterator, Shape, DestAccessor> dest,
286 Kernel const & spline)
287 {
288 resizeMultiArraySplineInterpolation(src.first, src.second, src.third,
289 dest.first, dest.second, dest.third, spline);
290 }
291
292 template <class SrcIterator, class Shape, class SrcAccessor,
293 class DestIterator, class DestAccessor>
294 inline void
295 resizeMultiArraySplineInterpolation(triple<SrcIterator, Shape, SrcAccessor> src,
296 triple<DestIterator, Shape, DestAccessor> dest)
297 {
298 resizeMultiArraySplineInterpolation(src.first, src.second, src.third,
299 dest.first, dest.second, dest.third);
300 }
301
302 template <unsigned int N, class T1, class S1,
303 class T2, class S2,
304 class Kernel>
305 inline void
306 resizeMultiArraySplineInterpolation(MultiArrayView<N, T1, S1> const & source,
307 MultiArrayView<N, T2, S2> dest,
308 Kernel const & spline)
309 {
310 resizeMultiArraySplineInterpolation(srcMultiArrayRange(source),
311 destMultiArrayRange(dest), spline);
312 }
313
314 template <unsigned int N, class T1, class S1,
315 class T2, class S2>
316 inline void
317 resizeMultiArraySplineInterpolation(MultiArrayView<N, T1, S1> const & source,
318 MultiArrayView<N, T2, S2> dest)
319 {
320 resizeMultiArraySplineInterpolation(srcMultiArrayRange(source),
321 destMultiArrayRange(dest));
322 }
323
324 //@}
325
326 } // namespace vigra
327
328 #endif // VIGRA_MULTI_RESIZE_HXX
vigra
vigra::doxygen_overloaded_function
doxygen_overloaded_function(template<... > void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
vigra::resamplingConvolveLine
void resamplingConvolveLine(...)
Performs a 1-dimensional resampling convolution of the source signal using the given set of kernels.
vigra::recursiveFilterLine
void recursiveFilterLine(...)
Performs a 1-dimensional recursive convolution of the source signal.
vigra::resizeMultiArraySplineInterpolation
void resizeMultiArraySplineInterpolation(...)
Resize MultiArray using B-spline interpolation.
vigra::lcm
IntType lcm(IntType n, IntType m)
Definition: rational.hxx:122

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.11.1