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

vigra/multi_resize.hxx
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)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.7.0 (Thu Aug 25 2011)