[ 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)