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

details vigra/interpolating_accessor.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 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.2.0, Aug 07 2003 )                                    */
00008 /*    You may use, modify, and distribute this software according       */
00009 /*    to the terms stated in the LICENSE file included in               */
00010 /*    the VIGRA distribution.                                           */
00011 /*                                                                      */
00012 /*    The VIGRA Website is                                              */
00013 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00014 /*    Please direct questions, bug reports, and contributions to        */
00015 /*        koethe@informatik.uni-hamburg.de                              */
00016 /*                                                                      */
00017 /*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
00018 /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
00019 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
00020 /*                                                                      */
00021 /************************************************************************/
00022  
00023 #ifndef VIGRA_INTERPOLATING_ACCESSOR_HXX
00024 #define VIGRA_INTERPOLATING_ACCESSOR_HXX
00025 
00026 
00027 #include "vigra/accessor.hxx"
00028 #include "vigra/diff2d.hxx"
00029 
00030 namespace vigra {
00031 
00032 /** \addtogroup DataAccessors 
00033 */
00034 //@{
00035 
00036 /********************************************************/
00037 /*                                                      */
00038 /*                  InterpolatingAccessor               */
00039 /*                                                      */
00040 /********************************************************/
00041 
00042 /** \brief Bilinear interpolation at non-integer positions.
00043 
00044     This accessor allows an image be accessed at arbitrary non-integer
00045     coordinates and performs an bi-linear interpolation to
00046     obtain a pixel value.
00047     It uses the given ACCESSOR (which is usually the
00048     accessor originally associated with the iterator)
00049     to access data.
00050     
00051     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"
00052     Namespace: vigra
00053     
00054     <b> Required Interface:</b>
00055     
00056     \code
00057     ITERATOR iter;
00058     ACCESSOR a;
00059     VALUETYPE destvalue;
00060     float s;
00061     int x, y;
00062     
00063     destvalue = s * a(iter, x, y) + s * a(iter, x, y);
00064     
00065     \endcode
00066 */
00067 template <class ACCESSOR, class VALUETYPE>
00068 class BilinearInterpolatingAccessor
00069 {
00070   public:
00071     /** the iterators' pixel type
00072     */
00073     typedef VALUETYPE value_type;
00074     
00075     /** init from given accessor
00076     */
00077     BilinearInterpolatingAccessor(ACCESSOR a)
00078     : a_(a)
00079     {}
00080     
00081     /** Interpolate the data item at a non-integer position.
00082         Ensure that no outside pixels are accessed if 
00083         (x, y) is near the image border (as long as
00084         0 <= x <= width-1, 0 <= y <= height-1).
00085     */
00086     template <class ITERATOR>
00087     value_type operator()(ITERATOR const & i, float x, float y) const 
00088     { 
00089         int ix = int(x);
00090         int iy = int(y);
00091         float dx = x - ix;
00092         float dy = y - iy;
00093         
00094         value_type ret;
00095         
00096         // avoid dereferencing the iterator outside its range
00097         if(dx == 0.0)
00098         {
00099             if(dy == 0.0)
00100             {
00101                 ret = a_(i, Diff2D(ix, iy));
00102             }
00103             else
00104             {
00105                 ret = detail::RequiresExplicitCast<value_type>::cast(
00106                   (1.0 - dy) * a_(i, Diff2D(ix, iy)) +
00107                   dy * a_(i, Diff2D(ix, iy + 1)));
00108             }
00109         }
00110         else
00111         {
00112             if(dy == 0.0)
00113             {
00114                 ret = detail::RequiresExplicitCast<value_type>::cast(
00115                   (1.0 - dx) * a_(i, Diff2D(ix, iy)) + 
00116                   dx * a_(i, Diff2D(ix + 1, iy)));
00117             }
00118             else
00119             {
00120                 ret = detail::RequiresExplicitCast<value_type>::cast(
00121                   (1.0 - dx) * (1.0 - dy) * a_(i, Diff2D(ix, iy)) +
00122                   dx * (1.0 - dy) * a_(i, Diff2D(ix + 1, iy)) +
00123                   (1.0 - dx) * dy * a_(i, Diff2D(ix, iy + 1)) +
00124                   dx * dy * a_(i, Diff2D(ix + 1, iy + 1)));
00125             }
00126         }
00127             
00128         return ret;
00129     }
00130 
00131     /** Interpolate the data item at a non-integer position.
00132         This function works as long as 0 <= x < width-1, 
00133         0 <= y < height-1. It is slightly faster than <TT>operator()</TT>.
00134     */
00135     template <class ITERATOR>
00136     value_type unchecked(ITERATOR const & i, float x, float y) const 
00137     { 
00138         int ix = int(x);
00139         int iy = int(y);
00140         float dx = x - ix;
00141         float dy = y - iy;
00142         return detail::RequiresExplicitCast<value_type>::cast(
00143                (1.0 - dx) * (1.0 - dy) * a_(i, Diff2D(ix, iy)) +
00144                dx * (1.0 - dy) * a_(i, Diff2D(ix + 1, iy)) +
00145                (1.0 - dx) * dy * a_(i, Diff2D(ix, iy + 1)) +
00146                dx * dy * a_(i, Diff2D(ix + 1, iy + 1)));
00147     }
00148     
00149   private:
00150     ACCESSOR a_;
00151 };
00152 
00153 //@}
00154 
00155 } // namespace vigra
00156 
00157 #endif /* VIGRA_INTERPOLATING_ACCESSOR_HXX */

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.2.0 (7 Aug 2003)