[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2004 by Ullrich Koethe */ 00004 /* Cognitive Systems Group, University of Hamburg, Germany */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* ( Version 1.6.0, Aug 13 2008 ) */ 00008 /* The VIGRA Website is */ 00009 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00010 /* Please direct questions, bug reports, and contributions to */ 00011 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00012 /* vigra@informatik.uni-hamburg.de */ 00013 /* */ 00014 /* Permission is hereby granted, free of charge, to any person */ 00015 /* obtaining a copy of this software and associated documentation */ 00016 /* files (the "Software"), to deal in the Software without */ 00017 /* restriction, including without limitation the rights to use, */ 00018 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00019 /* sell copies of the Software, and to permit persons to whom the */ 00020 /* Software is furnished to do so, subject to the following */ 00021 /* conditions: */ 00022 /* */ 00023 /* The above copyright notice and this permission notice shall be */ 00024 /* included in all copies or substantial portions of the */ 00025 /* Software. */ 00026 /* */ 00027 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00028 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00029 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00030 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00031 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00032 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00033 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00034 /* OTHER DEALINGS IN THE SOFTWARE. */ 00035 /* */ 00036 /************************************************************************/ 00037 00038 00039 #ifndef VIGRA_MULTI_RESIZE_HXX 00040 #define VIGRA_MULTI_RESIZE_HXX 00041 00042 #include <vector> 00043 #include "resizeimage.hxx" 00044 00045 namespace vigra { 00046 00047 namespace detail { 00048 00049 template <class SrcIterator, class Shape, class SrcAccessor, 00050 class DestIterator, class DestAccessor, class Kernel> 00051 void 00052 internalResizeMultiArrayOneDimension( 00053 SrcIterator si, Shape const & sshape, SrcAccessor src, 00054 DestIterator di, Shape const & dshape, DestAccessor dest, 00055 Kernel const & spline, unsigned int d) 00056 { 00057 enum { N = 1 + SrcIterator::level }; 00058 00059 typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType; 00060 00061 typedef MultiArrayNavigator<SrcIterator, N> SNavigator; 00062 typedef MultiArrayNavigator<DestIterator, N> DNavigator; 00063 00064 SNavigator snav( si, sshape, d ); 00065 DNavigator dnav( di, dshape, d ); 00066 00067 int ssize = sshape[d]; 00068 int dsize = dshape[d]; 00069 00070 vigra_precondition(ssize > 1, 00071 "resizeMultiArraySplineInterpolation(): " 00072 "Source array too small.\n"); 00073 00074 Rational<int> ratio(dsize - 1, ssize - 1); 00075 Rational<int> offset(0); 00076 resampling_detail::MapTargetToSourceCoordinate mapCoordinate(ratio, offset); 00077 int period = lcm(ratio.numerator(), ratio.denominator()); 00078 00079 ArrayVector<double> const & prefilterCoeffs = spline.prefilterCoefficients(); 00080 ArrayVector<Kernel1D<double> > kernels(period); 00081 createResamplingKernels(spline, mapCoordinate, kernels); 00082 00083 // temporay array to hold the current line to enable in-place operation 00084 ArrayVector<TmpType> tmp( ssize ); 00085 ArrayVector<TmpType>::iterator t = tmp.begin(), tend = tmp.end(); 00086 typename AccessorTraits<TmpType>::default_accessor ta; 00087 00088 for( ; snav.hasMore(); snav++, dnav++ ) 00089 { 00090 // first copy source to temp for maximum cache efficiency 00091 copyLine( snav.begin(), snav.end(), src, t, ta); 00092 00093 for(unsigned int b = 0; b < prefilterCoeffs.size(); ++b) 00094 { 00095 recursiveFilterLine(t, tend, ta, t, ta, 00096 prefilterCoeffs[b], BORDER_TREATMENT_REFLECT); 00097 } 00098 resamplingConvolveLine(t, tend, ta, 00099 dnav.begin(), dnav.begin() + dsize, dest, 00100 kernels, mapCoordinate); 00101 } 00102 } 00103 00104 } // namespace detail 00105 00106 /** \addtogroup GeometricTransformations Geometric Transformations 00107 */ 00108 //@{ 00109 00110 00111 /***************************************************************/ 00112 /* */ 00113 /* resizeMultiArraySplineInterpolation */ 00114 /* */ 00115 /***************************************************************/ 00116 00117 /** \brief Resize MultiArray using B-spline interpolation. 00118 00119 <b> Declarations:</b> 00120 00121 pass arguments explicitly: 00122 \code 00123 namespace vigra { 00124 template <class SrcIterator, class Shape, class SrcAccessor, 00125 class DestIterator, class DestAccessor, 00126 class Kernel = BSpline<3, double> > 00127 void 00128 resizeMultiArraySplineInterpolation( 00129 SrcIterator si, Shape const & sshape, SrcAccessor src, 00130 DestIterator di, Shape const & dshape, DestAccessor dest, 00131 Kernel const & spline = BSpline<3, double>()); 00132 } 00133 \endcode 00134 00135 00136 use argument objects in conjunction with \ref ArgumentObjectFactories : 00137 \code 00138 namespace vigra { 00139 template <class SrcIterator, class Shape, class SrcAccessor, 00140 class DestIterator, class DestAccessor, 00141 class Kernel = BSpline<3, double> > 00142 void 00143 resizeMultiArraySplineInterpolation( 00144 triple<SrcIterator, Shape, SrcAccessor> src, 00145 triple<DestIterator, Shape, DestAccessor> dest, 00146 Kernel const & spline = BSpline<3, double>()); 00147 } 00148 \endcode 00149 00150 The function implements separable spline interpolation algorithm described in 00151 00152 M. Unser, A. Aldroubi, M. Eden, <i>"B-Spline Signal Processing"</i> 00153 IEEE Transactions on Signal Processing, vol. 41, no. 2, pp. 821-833 (part I), 00154 pp. 834-848 (part II), 1993. 00155 00156 to obtain optimal interpolation quality and speed. You may pass the funcion 00157 a spline of arbitrary order (e.g. <TT>BSpline<ORDER, double></tt> or 00158 <TT>CatmullRomSpline<double></tt>). The default is a third order spline 00159 which gives a twice continuously differentiable interpolant. 00160 The implementation ensures that image values are interpolated rather 00161 than smoothed by first calling a recursive (sharpening) prefilter as 00162 described in the above paper. Then the actual interpolation is done 00163 using \ref resamplingConvolveLine(). 00164 00165 The range of both the input and output images (resp. regions) 00166 must be given. The input image must have a size of at 00167 least 4x4, the destination of at least 2x2. The scaling factors are then calculated 00168 accordingly. If the source image is larger than the destination, it 00169 is smoothed (band limited) using a recursive 00170 exponential filter. The source value_type (SrcAccessor::value_type) must 00171 be a linear algebra, i.e. it must support addition, subtraction, 00172 and multiplication (+, -, *), multiplication with a scalar 00173 real number and \ref NumericTraits "NumericTraits". 00174 The function uses accessors. 00175 00176 <b> Usage:</b> 00177 00178 <b>\#include</b> <<a href="multi__resize_8hxx-source.html">vigra/multi_resize.hxx</a>><br> 00179 Namespace: vigra 00180 00181 \code 00182 typedef vigra::MultiArray<3, float>::difference_type Shape; 00183 vigra::MultiArray<3, float> src(Shape(5, 7, 10)), 00184 dest(Shape(9, 13, 19)); // double the size 00185 00186 // use default cubic spline interpolator 00187 vigra::resizeMultiArraySplineInterpolation( 00188 srcMultiArrayRange(src), 00189 destMultiArrayRange(dest)); 00190 00191 \endcode 00192 00193 <b> Required Interface:</b> 00194 00195 The source and destination iterators must be compatible with \ref vigra::MultiIterator. The array value 00196 types must be models of \ref LinearSpace. 00197 */ 00198 doxygen_overloaded_function(template <...> void resizeMultiArraySplineInterpolation) 00199 00200 template <class SrcIterator, class Shape, class SrcAccessor, 00201 class DestIterator, class DestAccessor, 00202 class Kernel> 00203 void 00204 resizeMultiArraySplineInterpolation( 00205 SrcIterator si, Shape const & sshape, SrcAccessor src, 00206 DestIterator di, Shape const & dshape, DestAccessor dest, 00207 Kernel const & spline) 00208 { 00209 enum { N = 1 + SrcIterator::level }; 00210 typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType; 00211 typedef MultiArray<N, TmpType> TmpArray; 00212 typedef typename AccessorTraits<TmpType>::default_accessor TmpAccessor; 00213 00214 if(N==1) 00215 { 00216 detail::internalResizeMultiArrayOneDimension(si, sshape, src, 00217 di, dshape, dest, spline, 0); 00218 } 00219 else 00220 { 00221 unsigned int d = 0; 00222 Shape tmpShape(sshape); 00223 tmpShape[d] = dshape[d]; 00224 MultiArray<N, TmpType> tmp(tmpShape); 00225 TmpAccessor ta; 00226 00227 detail::internalResizeMultiArrayOneDimension(si, sshape, src, 00228 tmp.traverser_begin(), tmpShape, ta, spline, d); 00229 d = 1; 00230 for(; d<N-1; ++d) 00231 { 00232 tmpShape[d] = dshape[d]; 00233 MultiArray<N, TmpType> dtmp(tmpShape); 00234 00235 detail::internalResizeMultiArrayOneDimension(tmp.traverser_begin(), tmp.shape(), ta, 00236 dtmp.traverser_begin(), tmpShape, ta, spline, d); 00237 dtmp.swap(tmp); 00238 } 00239 detail::internalResizeMultiArrayOneDimension(tmp.traverser_begin(), tmp.shape(), ta, 00240 di, dshape, dest, spline, d); 00241 } 00242 } 00243 00244 template <class SrcIterator, class Shape, class SrcAccessor, 00245 class DestIterator, class DestAccessor, 00246 class Kernel> 00247 inline void 00248 resizeMultiArraySplineInterpolation(triple<SrcIterator, Shape, SrcAccessor> src, 00249 triple<DestIterator, Shape, DestAccessor> dest, 00250 Kernel const & spline) 00251 { 00252 resizeMultiArraySplineInterpolation(src.first, src.second, src.third, 00253 dest.first, dest.second, dest.third, spline); 00254 } 00255 00256 template <class SrcIterator, class Shape, class SrcAccessor, 00257 class DestIterator, class DestAccessor> 00258 inline void 00259 resizeMultiArraySplineInterpolation( 00260 SrcIterator si, Shape const & sshape, SrcAccessor src, 00261 DestIterator di, Shape const & dshape, DestAccessor dest) 00262 { 00263 resizeMultiArraySplineInterpolation(si, sshape, src, di, dshape, dest, BSpline<3, double>()); 00264 } 00265 00266 template <class SrcIterator, class Shape, class SrcAccessor, 00267 class DestIterator, class DestAccessor> 00268 inline void 00269 resizeMultiArraySplineInterpolation(triple<SrcIterator, Shape, SrcAccessor> src, 00270 triple<DestIterator, Shape, DestAccessor> dest) 00271 { 00272 resizeMultiArraySplineInterpolation(src.first, src.second, src.third, 00273 dest.first, dest.second, dest.third); 00274 } 00275 00276 //@} 00277 00278 } // namespace vigra 00279 00280 #endif // VIGRA_MULTI_RESIZE_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|