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