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

details vigra/gradient_energy_tensor.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 2004-2005 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.3.3, Aug 18 2005 )                                    */
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 
00024 #ifndef VIGRA_GRADIENT_ENERGY_TENSOR_HXX
00025 #define VIGRA_GRADIENT_ENERGY_TENSOR_HXX
00026 
00027 #include <cmath>
00028 #include <functional>
00029 #include "vigra/utilities.hxx"
00030 #include "vigra/array_vector.hxx"
00031 #include "vigra/basicimage.hxx"
00032 #include "vigra/combineimages.hxx"
00033 #include "vigra/numerictraits.hxx"
00034 #include "vigra/convolution.hxx"
00035 
00036 namespace vigra {
00037 
00038 /** \addtogroup TensorImaging Tensor Image Processing
00039 */
00040 //@{
00041 
00042 /********************************************************/
00043 /*                                                      */
00044 /*                 gradientEnergyTensor                 */
00045 /*                                                      */
00046 /********************************************************/
00047 
00048 /** \brief Calculate the gradient energy tensor for a scalar valued image.
00049 
00050     These function calculates the gradient energy tensor (GET operator) as described in
00051     
00052     M. Felsberg, U. K&ouml;the: 
00053     <i>"GET: The Connection Between Monogenic Scale-Space and Gaussian Derivatives"</i>, 
00054     in: R. Kimmel, N. Sochen, J. Weickert (Eds.): Scale Space and PDE Methods in Computer Vision, 
00055     Proc. of Scale-Space 2005, Lecture Notes in Computer Science 3459, pp. 192-203, Heidelberg: Springer, 2005.
00056     
00057     U. K&ouml;the, M. Felsberg: 
00058     <i>"Riesz-Transforms Versus Derivatives: On the Relationship Between the Boundary Tensor and the Energy Tensor"</i>, 
00059     in: ditto, pp. 179-191.
00060 
00061     with the given filters: The derivative filter \a derivKernel is applied to the appropriate image dimensions 
00062     in turn (see the papers above for details), and the other dimension is smoothed with \a smoothKernel. 
00063     The kernels can be as small as 3x1, e.g. [0.5, 0, -0.5] and [3.0/16.0, 10.0/16.0, 3.0/16.0] respectively.  
00064     The output image must have 3 bands which will hold the
00065     tensor components in the order t11, t12 (== t21), t22. The signs of the output are adjusted for a right-handed
00066     coordinate system. Thus, orientations derived from the tensor will be in counter-clockwise (mathematically positive)
00067     order, with the x-axis at zero degrees (this is the standard in all VIGRA functions that deal with orientation).
00068     
00069     <b> Declarations:</b>
00070 
00071     pass arguments explicitly:
00072     \code
00073     namespace vigra {
00074         template <class SrcIterator, class SrcAccessor,
00075                   class DestIterator, class DestAccessor>
00076         void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
00077                                   DestIterator dupperleft, DestAccessor dest,
00078                                   Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel);
00079     }
00080     \endcode
00081 
00082     use argument objects in conjunction with \ref ArgumentObjectFactories:
00083     \code
00084     namespace vigra {
00085         template <class SrcIterator, class SrcAccessor,
00086                   class DestIterator, class DestAccessor>
00087         void gradientEnergyTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00088                                   pair<DestIterator, DestAccessor> dest,
00089                                   Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel);
00090     }
00091     \endcode
00092 
00093     <b> Usage:</b>
00094 
00095     <b>\#include</b> "<a href="gradient__energy__tensor_8hxx-source.html">vigra/gradient_energy_tensor.hxx</a>"
00096 
00097     \code
00098     FImage img(w,h);
00099     FVector3Image get(w,h);
00100     Kernel1D<double> grad, smooth;
00101     grad.initGaussianDerivative(0.7, 1);
00102     smooth.initGaussian(0.7);
00103     ...
00104     gradientEnergyTensor(srcImageRange(img), destImage(get), grad, smooth);
00105     \endcode
00106 
00107 */
00108 template <class SrcIterator, class SrcAccessor,
00109           class DestIterator, class DestAccessor>
00110 void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
00111                           DestIterator dupperleft, DestAccessor dest,
00112                           Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel)
00113 {
00114     vigra_precondition(dest.size(dupperleft) == 3,
00115                        "gradientEnergyTensor(): output image must have 3 bands.");
00116 
00117     int w = slowerright.x - supperleft.x;
00118     int h = slowerright.y - supperleft.y;
00119     
00120     typedef typename 
00121        NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
00122     typedef BasicImage<TmpType> TmpImage;    
00123     TmpImage gx(w, h), gy(w, h), 
00124              gxx(w, h), gxy(w, h), gyy(w, h), 
00125              laplace(w, h), gx3(w, h), gy3(w, h);
00126     
00127     convolveImage(srcIterRange(supperleft, slowerright, src), destImage(gx), 
00128                   derivKernel, smoothKernel);
00129     convolveImage(srcIterRange(supperleft, slowerright, src), destImage(gy), 
00130                   smoothKernel, derivKernel);
00131     convolveImage(srcImageRange(gx), destImage(gxx), 
00132                   derivKernel, smoothKernel);
00133     convolveImage(srcImageRange(gx), destImage(gxy), 
00134                   smoothKernel, derivKernel);
00135     convolveImage(srcImageRange(gy), destImage(gyy), 
00136                   smoothKernel, derivKernel);
00137     combineTwoImages(srcImageRange(gxx), srcImage(gyy), destImage(laplace), 
00138                      std::plus<TmpType>());
00139     convolveImage(srcImageRange(laplace), destImage(gx3), 
00140                   derivKernel, smoothKernel);
00141     convolveImage(srcImageRange(laplace), destImage(gy3), 
00142                   smoothKernel, derivKernel);
00143     typename TmpImage::iterator gxi  = gx.begin(),
00144                                 gyi  = gy.begin(),
00145                                 gxxi = gxx.begin(),
00146                                 gxyi = gxy.begin(),
00147                                 gyyi = gyy.begin(),
00148                                 gx3i = gx3.begin(),
00149                                 gy3i = gy3.begin();
00150     for(int y = 0; y < h; ++y, ++dupperleft.y)
00151     {
00152         typename DestIterator::row_iterator d = dupperleft.rowIterator(); 
00153         for(int x = 0; x < w; ++x, ++d, ++gxi, ++gyi, ++gxxi, ++gxyi, ++gyyi, ++gx3i, ++gy3i)
00154         {
00155             dest.setComponent(sq(*gxxi) + sq(*gxyi) - *gxi * *gx3i, d, 0);
00156             dest.setComponent(- *gxyi * (*gxxi + *gyyi) + 0.5 * (*gxi * *gy3i + *gyi * *gx3i), d, 1);
00157             dest.setComponent(sq(*gxyi) + sq(*gyyi) - *gyi * *gy3i, d, 2);
00158         }
00159     }
00160 }
00161 
00162 template <class SrcIterator, class SrcAccessor,
00163           class DestIterator, class DestAccessor>
00164 inline
00165 void gradientEnergyTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00166                           pair<DestIterator, DestAccessor> dest,
00167                           Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel)
00168 {
00169     gradientEnergyTensor(src.first, src.second, src.third,
00170                          dest.first, dest.second, derivKernel, smoothKernel);
00171 }
00172 
00173 //@}
00174 
00175 } // namespace vigra
00176 
00177 #endif // VIGRA_GRADIENT_ENERGY_TENSOR_HXX

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

html generated using doxygen and Python
VIGRA 1.3.3 (18 Aug 2005)