[ 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     // temporary 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 function
    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> <vigra/multi_resize.hxx><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.9.0 (Tue Nov 6 2012)