VIGRA - VIGRA: vigra/multi_resize.hxx Source File

[ 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 /*       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) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python VIGRA 1.6.0 (13 Aug 2008)