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

details vigra/convolution.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.5.0, Dec 07 2006 )                                    */
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 /*        koethe@informatik.uni-hamburg.de          or                  */
00012 /*        vigra@kogs1.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_CONVOLUTION_HXX
00040 #define VIGRA_CONVOLUTION_HXX
00041 
00042 #include <functional>
00043 #include "stdconvolution.hxx"
00044 #include "separableconvolution.hxx"
00045 #include "recursiveconvolution.hxx"
00046 #include "nonlineardiffusion.hxx"
00047 #include "combineimages.hxx"
00048 
00049 /** \page Convolution Functions to Convolve Images and Signals
00050 
00051     1D and 2D filters, including separable and recursive convolution, and non-linear diffusion
00052 
00053     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"<br>
00054     Namespace: vigra
00055 
00056     <DL>
00057     <DT>
00058         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00059         \ref CommonConvolutionFilters
00060         <DD><em>Short-hands for the most common 2D convolution filters</em>
00061     <DT>
00062         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00063         \ref MultiArrayConvolutionFilters
00064         <DD><em>Convolution filters for arbitrary dimensional arrays (MultiArray etc.)</em>
00065     <DT>
00066         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00067         \ref ResamplingConvolutionFilters
00068         <DD><em>Resampling convolution filters</em>
00069     <DT>
00070         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00071         \ref StandardConvolution
00072         <DD><em>2D non-separable convolution, with and without ROI mask </em>
00073     <DT>
00074         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00075         \ref vigra::Kernel2D
00076         <DD><em>Generic 2-dimensional discrete convolution kernel </em>
00077     <DT>
00078         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00079         \ref SeparableConvolution
00080         <DD> <em>1D convolution and separable filters in 2 dimensions </em>
00081     <DT>
00082         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00083         \ref vigra::Kernel1D
00084         <DD> <em>Generic 1-dimensional discrete convolution kernel </em>
00085     <DT>
00086         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00087         \ref RecursiveConvolution
00088         <DD> <em>Recursive filters (1st and 2nd order)</em>
00089     <DT>
00090         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00091         \ref NonLinearDiffusion
00092         <DD> <em>Edge-preserving smoothing </em>
00093     <DT>
00094         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00095         \ref BorderTreatmentMode
00096         <DD><em>Choose between different border treatment modes </em>
00097     <DT>
00098         <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
00099         \ref KernelArgumentObjectFactories
00100         <DD> <em>Factory functions to create argument objects to simplify passing kernels</em>
00101     </DL>
00102 */
00103 
00104 /** \page KernelArgumentObjectFactories Kernel Argument Object Factories
00105 
00106     These factory functions allow to create argument objects for 1D
00107     and 2D convolution kernel analogously to
00108     \ref ArgumentObjectFactories for images.
00109 
00110     \section Kernel1dFactory kernel1d()
00111 
00112         Pass a \ref vigra::Kernel1D to a 1D or separable convolution algorithm.
00113 
00114         These factories can be used to create argument objects when we
00115         are given instances or subclasses of \ref vigra::Kernel1D
00116         (analogous to the \ref ArgumentObjectFactories for images).
00117         These factory functions access <TT>kernel.center()</TT>,
00118         <TT>kernel.left()</TT>, <TT>kernel.right()</TT>, <TT>kernel.accessor()</TT>,
00119         and  <TT>kernel.borderTreatment()</TT> to obtain the necessary
00120         information. The following factory functions are provided:
00121 
00122         <table>
00123         <tr><td>
00124             \htmlonly
00125             <th bgcolor="#f0e0c0" colspan=2 align=left>
00126             \endhtmlonly
00127             <TT>\ref vigra::Kernel1D "vigra::Kernel1D<SomeType>" kernel;</TT>
00128             \htmlonly
00129             </th>
00130             \endhtmlonly
00131         </td></tr>
00132         <tr><td>
00133         <TT>kernel1d(kernel)</TT>
00134         </td><td>
00135             create argument object from information provided by
00136             kernel
00137 
00138         </td></tr>
00139         <tr><td>
00140         <TT>kernel1d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT>
00141         </td><td>
00142             create argument object from information provided by
00143             kernel, but use given border treatment mode
00144 
00145         </td></tr>
00146         <tr><td>
00147         <TT>kernel1d(kerneliterator, kernelaccessor,</TT><br>
00148         <TT>                kernelleft, kernelright,</TT><br>
00149         <TT>                vigra::BORDER_TREATMENT_CLIP)</TT>
00150         </td><td>
00151             create argument object from explicitly given iterator
00152             (pointing to the center of th kernel), accessor,
00153             left and right boundaries, and border treatment mode
00154 
00155         </table>
00156 
00157         For usage examples see
00158         \ref SeparableConvolution "one-dimensional and separable convolution functions".
00159 
00160     \section Kernel2dFactory kernel2d()
00161 
00162         Pass a \ref vigra::Kernel2D to a 2D (non-separable) convolution algorithm.
00163 
00164         These factories can be used to create argument objects when we
00165         are given instances or subclasses of \ref vigra::Kernel2D
00166         (analogous to the \ref ArgumentObjectFactories for images).
00167         These factory functions access <TT>kernel.center()</TT>,
00168         <TT>kernel.upperLeft()</TT>, <TT>kernel.lowerRight()</TT>, <TT>kernel.accessor()</TT>,
00169         and  <TT>kernel.borderTreatment()</TT> to obtain the necessary
00170         information. The following factory functions are provided:
00171 
00172         <table>
00173         <tr><td>
00174             \htmlonly
00175             <th bgcolor="#f0e0c0" colspan=2 align=left>
00176             \endhtmlonly
00177             <TT>\ref vigra::Kernel2D "vigra::Kernel2D<SomeType>" kernel;</TT>
00178             \htmlonly
00179             </th>
00180             \endhtmlonly
00181         </td></tr>
00182         <tr><td>
00183         <TT>kernel2d(kernel)</TT>
00184         </td><td>
00185             create argument object from information provided by
00186             kernel
00187 
00188         </td></tr>
00189         <tr><td>
00190         <TT>kernel2d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT>
00191         </td><td>
00192             create argument object from information provided by
00193             kernel, but use given border treatment mode
00194 
00195         </td></tr>
00196         <tr><td>
00197         <TT>kernel2d(kerneliterator, kernelaccessor,</TT>
00198         <TT>                upperleft, lowerright,</TT>
00199         <TT>                vigra::BORDER_TREATMENT_CLIP)</TT>
00200         </td><td>
00201             create argument object from explicitly given iterator
00202             (pointing to the center of th kernel), accessor,
00203             upper left and lower right corners, and border treatment mode
00204 
00205         </table>
00206 
00207         For usage examples see \ref StandardConvolution "two-dimensional convolution functions".
00208 */
00209 
00210 namespace vigra {
00211 
00212 
00213 
00214 /********************************************************/
00215 /*                                                      */
00216 /*             Common convolution filters               */
00217 /*                                                      */
00218 /********************************************************/
00219 
00220 /** \addtogroup CommonConvolutionFilters Common Filters
00221 
00222     These functions calculate common filters by appropriate sequences of calls 
00223     to \link SeparableConvolution#separableConvolveX separableConvolveX\endlink()
00224     and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink().
00225 */
00226 //@{
00227 
00228 /********************************************************/
00229 /*                                                      */
00230 /*                    convolveImage                     */
00231 /*                                                      */
00232 /********************************************************/
00233 
00234 /** \brief Apply two separable filters successively, the first in x-direction, 
00235            the second in y-direction.
00236 
00237     This function is a shorthand for the concatenation of a call to
00238     \link SeparableConvolution#separableConvolveX separableConvolveX\endlink()
00239     and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() 
00240     with the given kernels.
00241 
00242     <b> Declarations:</b>
00243 
00244     pass arguments explicitly:
00245     \code
00246     namespace vigra {
00247         template <class SrcIterator, class SrcAccessor,
00248                   class DestIterator, class DestAccessor,
00249                   class T>
00250         void convolveImage(SrcIterator supperleft,
00251                            SrcIterator slowerright, SrcAccessor sa,
00252                            DestIterator dupperleft, DestAccessor da,
00253                            Kernel1D<T> const & kx, Kernel1D<T> const & ky);
00254     }
00255     \endcode
00256 
00257 
00258     use argument objects in conjunction with \ref ArgumentObjectFactories:
00259     \code
00260     namespace vigra {
00261         template <class SrcIterator, class SrcAccessor,
00262                   class DestIterator, class DestAccessor,
00263                   class T>
00264         inline void
00265         convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00266                       pair<DestIterator, DestAccessor> dest,
00267                       Kernel1D<T> const & kx, Kernel1D<T> const & ky);
00268     }
00269     \endcode
00270 
00271     <b> Usage:</b>
00272 
00273     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
00274 
00275 
00276     \code
00277     vigra::FImage src(w,h), dest(w,h);
00278     ...
00279 
00280     // implement sobel filter in x-direction
00281     Kernel1D<double> kx, ky;
00282     kx.initSymmetricGradient();
00283     ky.initBinomial(1);
00284     
00285     vigra::convolveImage(srcImageRange(src), destImage(dest), kx, ky);
00286 
00287     \endcode
00288 
00289 */
00290 template <class SrcIterator, class SrcAccessor,
00291           class DestIterator, class DestAccessor,
00292           class T>
00293 void convolveImage(SrcIterator supperleft,
00294                    SrcIterator slowerright, SrcAccessor sa,
00295                    DestIterator dupperleft, DestAccessor da,
00296                    Kernel1D<T> const & kx, Kernel1D<T> const & ky)
00297 {
00298     typedef typename
00299         NumericTraits<typename SrcAccessor::value_type>::RealPromote
00300         TmpType;
00301     BasicImage<TmpType> tmp(slowerright - supperleft);
00302 
00303     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
00304                        destImage(tmp), kernel1d(kx));
00305     separableConvolveY(srcImageRange(tmp),
00306                        destIter(dupperleft, da), kernel1d(ky));
00307 }
00308 
00309 template <class SrcIterator, class SrcAccessor,
00310           class DestIterator, class DestAccessor,
00311           class T>
00312 inline void
00313 convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00314               pair<DestIterator, DestAccessor> dest,
00315               Kernel1D<T> const & kx, Kernel1D<T> const & ky)
00316 {
00317     convolveImage(src.first, src.second, src.third,
00318                   dest.first, dest.second, kx, ky);
00319 }
00320 
00321 /********************************************************/
00322 /*                                                      */
00323 /*                    simpleSharpening                  */
00324 /*                                                      */
00325 /********************************************************/
00326 
00327 /** \brief Perform simple sharpening function.
00328 
00329     This function use \link StandardConvolution#convolveImage convolveImage\endlink( ) with following filter:
00330     
00331     \code
00332     -sharpening_factor/16.0,    -sharpening_factor/8.0,    -sharpening_factor/16.0,
00333     -sharpening_factor/8.0,   1.0+sharpening_factor*0.75,  -sharpening_factor/8.0,
00334     -sharpening_factor/16.0,    -sharpening_factor/8.0,    -sharpening_factor/16.0;    
00335     \endcode
00336     
00337     and use <TT>BORDER_TREATMENT_REFLECT</TT> as border treatment mode.
00338 
00339     <b> Preconditions:</b>
00340     \code  
00341     1. sharpening_factor >= 0
00342     2. scale >= 0
00343     \endcode
00344 
00345     <b> Declarations:</b>
00346 
00347     <b> Declarations:</b>
00348 
00349     pass arguments explicitly:
00350     \code
00351     namespace vigra {
00352       template <class SrcIterator, class SrcAccessor,
00353                 class DestIterator, class DestAccessor>
00354       void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
00355                             DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor)
00356 
00357     }
00358     \endcode
00359 
00360 
00361     use argument objects in conjunction with \ref ArgumentObjectFactories:
00362     \code
00363     namespace vigra {
00364       template <class SrcIterator, class SrcAccessor, 
00365                 class DestIterator, class DestAccessor>
00366       inline
00367       void simpleSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00368                                     pair<DestIterator, DestAccessor> dest, double sharpening_factor)
00369       {
00370           simpleSharpening(src.first, src.second, src.third,
00371                              dest.first, dest.second, sharpening_factor);
00372       }
00373 
00374     }
00375     \endcode
00376 
00377     <b> Usage:</b>
00378 
00379     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
00380 
00381 
00382     \code
00383     vigra::FImage src(w,h), dest(w,h);
00384     ...
00385 
00386     // sharpening with sharpening_factor = 0.1
00387     vigra::simpleSharpening(srcImageRange(src), destImage(dest), 0.1);
00388 
00389     \endcode
00390 
00391 */    
00392 template <class SrcIterator, class SrcAccessor,
00393           class DestIterator, class DestAccessor>
00394 void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
00395                     DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor)
00396 {
00397 
00398     vigra_precondition(sharpening_factor >= 0.0,
00399                        "simpleSharpening(): amount of sharpening must be >= 0.");
00400 
00401     Kernel2D<double> kernel;
00402 
00403     kernel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = -sharpening_factor/16.0,    -sharpening_factor/8.0,    -sharpening_factor/16.0,
00404                                                         -sharpening_factor/8.0,   1.0+sharpening_factor*0.75,  -sharpening_factor/8.0,
00405                                                         -sharpening_factor/16.0,    -sharpening_factor/8.0,    -sharpening_factor/16.0;
00406 
00407     convolveImage(src_ul, src_lr, src_acc, dest_ul, dest_acc, 
00408                   kernel.center(), kernel.accessor(), 
00409                   kernel.upperLeft(), kernel.lowerRight() , BORDER_TREATMENT_REFLECT );
00410 }
00411 
00412 template <class SrcIterator, class SrcAccessor, 
00413           class DestIterator, class DestAccessor>
00414 inline
00415 void simpleSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00416                     pair<DestIterator, DestAccessor> dest, double sharpening_factor)
00417 {
00418     simpleSharpening(src.first, src.second, src.third,
00419                      dest.first, dest.second, sharpening_factor);
00420 }
00421 
00422 
00423 /********************************************************/
00424 /*                                                      */
00425 /*                    gaussianSharpening                */
00426 /*                                                      */
00427 /********************************************************/
00428 
00429 /** \brief Perform sharpening function with gaussian filter.
00430 
00431 
00432     This function use the 
00433     \link vigra::gaussianSmoothing gaussianSmoothing \endlink()
00434     at first and scale the source image 
00435     (\code src \endcode) with the \code scale \endcode
00436     factor in an temporary image (\code tmp \endcode). At second the new 
00437     pixel in the destination image will be with following
00438     formel calculate:
00439     \code
00440     dest = (1 + sharpening_factor)*src - sharpening_factor*tmp
00441     \endcode
00442 
00443     <b> Preconditions:</b>
00444     \code  
00445     1. sharpening_factor >= 0
00446     2. scale >= 0
00447     \endcode
00448 
00449     <b> Declarations:</b>
00450 
00451     pass arguments explicitly:
00452     \code
00453     namespace vigra {
00454       template <class SrcIterator, class SrcAccessor,
00455                 class DestIterator, class DestAccessor>
00456       void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
00457                                 DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor, 
00458                               double scale)
00459     }
00460     \endcode
00461 
00462 
00463     use argument objects in conjunction with \ref ArgumentObjectFactories:
00464     \code
00465     namespace vigra {
00466       template <class SrcIterator, class SrcAccessor,
00467                 class DestIterator, class DestAccessor>
00468       void gaussianSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00469                                pair<DestIterator, DestAccessor> dest, double sharpening_factor, 
00470                               double scale)
00471     }
00472     \endcode
00473 
00474     <b> Usage:</b>
00475 
00476     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
00477 
00478 
00479     \code
00480     vigra::FImage src(w,h), dest(w,h);
00481     ...
00482 
00483     // sharpening with sharpening_factor = 3.0
00484     // smoothing with scale = 0.5
00485     vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0, 0.5);
00486 
00487     \endcode
00488 
00489 */    
00490 template <class SrcIterator, class SrcAccessor,
00491           class DestIterator, class DestAccessor>
00492 void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
00493                         DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor, 
00494                         double scale)
00495 {
00496     vigra_precondition(sharpening_factor >= 0.0,
00497                        "gaussianSharpening(): amount of sharpening must be >= 0");
00498     vigra_precondition(scale >= 0.0,
00499                        "gaussianSharpening(): scale parameter should be >= 0.");
00500 
00501     typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote ValueType;
00502 
00503     BasicImage<ValueType> tmp(src_lr - src_ul);
00504 
00505     gaussianSmoothing(src_ul, src_lr, src_acc, tmp.upperLeft(), tmp.accessor(), scale);
00506 
00507     SrcIterator i_src = src_ul;
00508     DestIterator i_dest = dest_ul;
00509     typename BasicImage<ValueType>::traverser tmp_ul = tmp.upperLeft();
00510     typename BasicImage<ValueType>::traverser i_tmp = tmp_ul;
00511     typename BasicImage<ValueType>::Accessor tmp_acc = tmp.accessor();
00512 
00513     for(; i_src.y != src_lr.y ; i_src.y++, i_dest.y++, i_tmp.y++ )
00514     {
00515         for (;i_src.x != src_lr.x ; i_src.x++, i_dest.x++, i_tmp.x++ )
00516         {
00517             dest_acc.set((1.0 + sharpening_factor)*src_acc(i_src) - sharpening_factor*tmp_acc(i_tmp), i_dest);
00518         }
00519         i_src.x = src_ul.x;
00520         i_dest.x = dest_ul.x;
00521         i_tmp.x = tmp_ul.x;
00522     }
00523 }
00524 
00525 template <class SrcIterator, class SrcAccessor,
00526           class DestIterator, class DestAccessor>
00527 void gaussianSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00528                         pair<DestIterator, DestAccessor> dest, double sharpening_factor, 
00529                         double scale)
00530 {
00531     gaussianSharpening(src.first, src.second, src.third,
00532                        dest.first, dest.second,
00533                        sharpening_factor, scale);
00534 }
00535 
00536 
00537 
00538 /********************************************************/
00539 /*                                                      */
00540 /*                    gaussianSmoothing                 */
00541 /*                                                      */
00542 /********************************************************/
00543 
00544 /** \brief Perform isotropic Gaussian convolution.
00545 
00546     This function is a shorthand for the concatenation of a call to
00547     \link SeparableConvolution#separableConvolveX separableConvolveX\endlink()
00548     and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with a
00549     Gaussian kernel of the given scale. The function uses 
00550     <TT>BORDER_TREATMENT_REFLECT</TT>.
00551 
00552     <b> Declarations:</b>
00553 
00554     pass arguments explicitly:
00555     \code
00556     namespace vigra {
00557         template <class SrcIterator, class SrcAccessor,
00558                   class DestIterator, class DestAccessor>
00559         void gaussianSmoothing(SrcIterator supperleft,
00560                                 SrcIterator slowerright, SrcAccessor sa,
00561                                 DestIterator dupperleft, DestAccessor da,
00562                                 double scale);
00563     }
00564     \endcode
00565 
00566 
00567     use argument objects in conjunction with \ref ArgumentObjectFactories:
00568     \code
00569     namespace vigra {
00570         template <class SrcIterator, class SrcAccessor,
00571                   class DestIterator, class DestAccessor>
00572         inline void
00573         gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00574                           pair<DestIterator, DestAccessor> dest,
00575                           double scale);
00576     }
00577     \endcode
00578 
00579     <b> Usage:</b>
00580 
00581     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
00582 
00583 
00584     \code
00585     vigra::FImage src(w,h), dest(w,h);
00586     ...
00587 
00588     // smooth with scale = 3.0
00589     vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0);
00590 
00591     \endcode
00592 
00593 */
00594 template <class SrcIterator, class SrcAccessor,
00595           class DestIterator, class DestAccessor>
00596 void gaussianSmoothing(SrcIterator supperleft,
00597                         SrcIterator slowerright, SrcAccessor sa,
00598                         DestIterator dupperleft, DestAccessor da,
00599                         double scale)
00600 {
00601     typedef typename
00602         NumericTraits<typename SrcAccessor::value_type>::RealPromote
00603         TmpType;
00604     BasicImage<TmpType> tmp(slowerright - supperleft);
00605 
00606     Kernel1D<double> smooth;
00607     smooth.initGaussian(scale);
00608     smooth.setBorderTreatment(BORDER_TREATMENT_REFLECT);
00609 
00610     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
00611                        destImage(tmp), kernel1d(smooth));
00612     separableConvolveY(srcImageRange(tmp),
00613                        destIter(dupperleft, da), kernel1d(smooth));
00614 }
00615 
00616 template <class SrcIterator, class SrcAccessor,
00617           class DestIterator, class DestAccessor>
00618 inline void
00619 gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00620                   pair<DestIterator, DestAccessor> dest,
00621                   double scale)
00622 {
00623     gaussianSmoothing(src.first, src.second, src.third,
00624                  dest.first, dest.second, scale);
00625 }
00626 
00627 /********************************************************/
00628 /*                                                      */
00629 /*                     gaussianGradient                 */
00630 /*                                                      */
00631 /********************************************************/
00632 
00633 /** \brief Calculate the gradient vector by means of a 1st derivatives of
00634     Gaussian filter.
00635 
00636     This function is a shorthand for the concatenation of a call to
00637     \link SeparableConvolution#separableConvolveX separableConvolveX\endlink()
00638     and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with the
00639     appropriate kernels at the given scale. Note that this function can either produce
00640     two separate result images for the x- and y-components of the gradient, or write
00641     into a vector valued image (with at least two components).
00642 
00643     <b> Declarations:</b>
00644 
00645     pass arguments explicitly:
00646     \code
00647     namespace vigra {
00648         // write x and y component of the gradient into separate images
00649         template <class SrcIterator, class SrcAccessor,
00650                   class DestIteratorX, class DestAccessorX,
00651                   class DestIteratorY, class DestAccessorY>
00652         void gaussianGradient(SrcIterator supperleft,
00653                               SrcIterator slowerright, SrcAccessor sa,
00654                               DestIteratorX dupperleftx, DestAccessorX dax,
00655                               DestIteratorY dupperlefty, DestAccessorY day,
00656                               double scale);
00657 
00658         // write x and y component of the gradient into a vector-valued image
00659         template <class SrcIterator, class SrcAccessor,
00660                  class DestIterator, class DestAccessor>
00661         void gaussianGradient(SrcIterator supperleft,
00662                               SrcIterator slowerright, SrcAccessor src,
00663                               DestIterator dupperleft, DestAccessor dest,
00664                               double scale);
00665     }
00666     \endcode
00667 
00668 
00669     use argument objects in conjunction with \ref ArgumentObjectFactories:
00670     \code
00671     namespace vigra {
00672         // write x and y component of the gradient into separate images
00673         template <class SrcIterator, class SrcAccessor,
00674                   class DestIteratorX, class DestAccessorX,
00675                   class DestIteratorY, class DestAccessorY>
00676         void
00677         gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00678                          pair<DestIteratorX, DestAccessorX> destx,
00679                          pair<DestIteratorY, DestAccessorY> desty,
00680                          double scale);
00681 
00682         // write x and y component of the gradient into a vector-valued image
00683         template <class SrcIterator, class SrcAccessor,
00684                  class DestIterator, class DestAccessor>
00685         void
00686         gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00687                          pair<DestIterator, DestAccessor> dest,
00688                          double scale);
00689     }
00690     \endcode
00691 
00692     <b> Usage:</b>
00693 
00694     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
00695 
00696 
00697     \code
00698     vigra::FImage src(w,h), gradx(w,h), grady(w,h);
00699     ...
00700 
00701     // calculate gradient vector at scale = 3.0
00702     vigra::gaussianGradient(srcImageRange(src),
00703                              destImage(gradx), destImage(grady), 3.0);
00704 
00705     \endcode
00706 
00707 */
00708 template <class SrcIterator, class SrcAccessor,
00709           class DestIteratorX, class DestAccessorX,
00710           class DestIteratorY, class DestAccessorY>
00711 void gaussianGradient(SrcIterator supperleft,
00712                         SrcIterator slowerright, SrcAccessor sa,
00713                         DestIteratorX dupperleftx, DestAccessorX dax,
00714                         DestIteratorY dupperlefty, DestAccessorY day,
00715                         double scale)
00716 {
00717     typedef typename
00718         NumericTraits<typename SrcAccessor::value_type>::RealPromote
00719         TmpType;
00720     BasicImage<TmpType> tmp(slowerright - supperleft);
00721 
00722     Kernel1D<double> smooth, grad;
00723     smooth.initGaussian(scale);
00724     grad.initGaussianDerivative(scale, 1);
00725 
00726     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
00727                        destImage(tmp), kernel1d(grad));
00728     separableConvolveY(srcImageRange(tmp),
00729                        destIter(dupperleftx, dax), kernel1d(smooth));
00730     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
00731                        destImage(tmp), kernel1d(smooth));
00732     separableConvolveY(srcImageRange(tmp),
00733                        destIter(dupperlefty, day), kernel1d(grad));
00734 }
00735 
00736 template <class SrcIterator, class SrcAccessor,
00737           class DestIterator, class DestAccessor>
00738 void gaussianGradient(SrcIterator supperleft,
00739                         SrcIterator slowerright, SrcAccessor src,
00740                         DestIterator dupperleft, DestAccessor dest,
00741                         double scale)
00742 {
00743     VectorElementAccessor<DestAccessor> gradx(0, dest), grady(1, dest);
00744     gaussianGradient(supperleft, slowerright, src, 
00745                      dupperleft, gradx, dupperleft, grady, scale);
00746 }
00747 
00748 template <class SrcIterator, class SrcAccessor,
00749           class DestIteratorX, class DestAccessorX,
00750           class DestIteratorY, class DestAccessorY>
00751 inline void
00752 gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00753                  pair<DestIteratorX, DestAccessorX> destx,
00754                  pair<DestIteratorY, DestAccessorY> desty,
00755                  double scale)
00756 {
00757     gaussianGradient(src.first, src.second, src.third,
00758                  destx.first, destx.second, desty.first, desty.second, scale);
00759 }
00760 
00761 template <class SrcIterator, class SrcAccessor,
00762           class DestIterator, class DestAccessor>
00763 inline void
00764 gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00765                  pair<DestIterator, DestAccessor> dest,
00766                  double scale)
00767 {
00768     gaussianGradient(src.first, src.second, src.third,
00769                      dest.first, dest.second, scale);
00770 }
00771 
00772 /** \brief Calculate the gradient magnitude by means of a 1st derivatives of
00773     Gaussian filter.
00774 
00775     This function calls gaussianGradient() and returns the pixel-wise magnitude of
00776     the resulting gradient vectors. If the original image has multiple bands,
00777     the squared gradient magnitude is computed for each band separately, and the
00778     return value is the square root of the sum of these sqaured magnitudes.
00779 
00780     <b> Declarations:</b>
00781 
00782     pass arguments explicitly:
00783     \code
00784     namespace vigra {
00785         template <class SrcIterator, class SrcAccessor,
00786                   class DestIterator, class DestAccessor>
00787         void gaussianGradientMagnitude(SrcIterator sul,
00788                                        SrcIterator slr, SrcAccessor src,
00789                                        DestIterator dupperleft, DestAccessor dest,
00790                                        double scale);
00791     }
00792     \endcode
00793 
00794 
00795     use argument objects in conjunction with \ref ArgumentObjectFactories:
00796     \code
00797     namespace vigra {
00798         template <class SrcIterator, class SrcAccessor,
00799                   class DestIterator, class DestAccessor>
00800         void
00801         gaussianGradientMagnitude(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00802                                   pair<DestIterator, DestAccessor> dest,
00803                                   double scale);
00804     }
00805     \endcode
00806 
00807     <b> Usage:</b>
00808 
00809     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
00810 
00811 
00812     \code
00813     vigra::FImage src(w,h), grad(w,h);
00814     ...
00815 
00816     // calculate gradient magnitude at scale = 3.0
00817     vigra::gaussianGradientMagnitude(srcImageRange(src), destImage(grad), 3.0);
00818 
00819     \endcode
00820 
00821 */
00822 template <class SrcIterator, class SrcAccessor,
00823           class DestIterator, class DestAccessor>
00824 void gaussianGradientMagnitude(SrcIterator sul,
00825                                SrcIterator slr, SrcAccessor src,
00826                                DestIterator dupperleft, DestAccessor dest,
00827                                double scale)
00828 {
00829     typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
00830     BasicImage<TmpType> gradx(slr-sul), grady(slr-sul);
00831 
00832     gaussianGradient(srcIterRange(sul, slr, src),
00833                      destImage(gradx), destImage(grady), scale);
00834     combineTwoImages(srcImageRange(gradx), srcImage(grady), destIter(dupperleft, dest),
00835                      MagnitudeFunctor<TmpType>());
00836 }
00837 
00838 template <class SrcIterator, class SrcAccessor,
00839           class DestIterator, class DestAccessor>
00840 inline void
00841 gaussianGradientMagnitude(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00842                           pair<DestIterator, DestAccessor> dest,
00843                           double scale)
00844 {
00845     gaussianGradientMagnitude(src.first, src.second, src.third,
00846                               dest.first, dest.second, scale);
00847 }
00848 
00849 /********************************************************/
00850 /*                                                      */
00851 /*                 laplacianOfGaussian                  */
00852 /*                                                      */
00853 /********************************************************/
00854 
00855 /** \brief Filter image with the Laplacian of Gaussian operator
00856     at the given scale.
00857 
00858     This function calls \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() and
00859     \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with the appropriate 2nd derivative
00860     of Gaussian kernels in x- and y-direction and then sums the results
00861     to get the Laplacian.
00862 
00863     <b> Declarations:</b>
00864 
00865     pass arguments explicitly:
00866     \code
00867     namespace vigra {
00868         template <class SrcIterator, class SrcAccessor,
00869                   class DestIterator, class DestAccessor>
00870         void laplacianOfGaussian(SrcIterator supperleft,
00871                                 SrcIterator slowerright, SrcAccessor sa,
00872                                 DestIterator dupperleft, DestAccessor da,
00873                                 double scale);
00874     }
00875     \endcode
00876 
00877 
00878     use argument objects in conjunction with \ref ArgumentObjectFactories:
00879     \code
00880     namespace vigra {
00881         template <class SrcIterator, class SrcAccessor,
00882                   class DestIterator, class DestAccessor>
00883         inline void
00884         laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00885                           pair<DestIterator, DestAccessor> dest,
00886                           double scale);
00887     }
00888     \endcode
00889 
00890     <b> Usage:</b>
00891 
00892     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
00893 
00894 
00895     \code
00896     vigra::FImage src(w,h), dest(w,h);
00897     ...
00898 
00899     // calculate Laplacian of Gaussian at scale = 3.0
00900     vigra::laplacianOfGaussian(srcImageRange(src), destImage(dest), 3.0);
00901 
00902     \endcode
00903 
00904 */
00905 template <class SrcIterator, class SrcAccessor,
00906           class DestIterator, class DestAccessor>
00907 void laplacianOfGaussian(SrcIterator supperleft,
00908                         SrcIterator slowerright, SrcAccessor sa,
00909                         DestIterator dupperleft, DestAccessor da,
00910                         double scale)
00911 {
00912     typedef typename
00913         NumericTraits<typename SrcAccessor::value_type>::RealPromote
00914         TmpType;
00915     BasicImage<TmpType> tmp(slowerright - supperleft),
00916                         tmpx(slowerright - supperleft),
00917                         tmpy(slowerright - supperleft);
00918 
00919     Kernel1D<double> smooth, deriv;
00920     smooth.initGaussian(scale);
00921     deriv.initGaussianDerivative(scale, 2);
00922 
00923     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
00924                        destImage(tmp), kernel1d(deriv));
00925     separableConvolveY(srcImageRange(tmp),
00926                        destImage(tmpx), kernel1d(smooth));
00927     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
00928                        destImage(tmp), kernel1d(smooth));
00929     separableConvolveY(srcImageRange(tmp),
00930                        destImage(tmpy), kernel1d(deriv));
00931     combineTwoImages(srcImageRange(tmpx), srcImage(tmpy),
00932                        destIter(dupperleft, da), std::plus<TmpType>());
00933 }
00934 
00935 template <class SrcIterator, class SrcAccessor,
00936           class DestIterator, class DestAccessor>
00937 inline void
00938 laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00939                   pair<DestIterator, DestAccessor> dest,
00940                   double scale)
00941 {
00942     laplacianOfGaussian(src.first, src.second, src.third,
00943                  dest.first, dest.second, scale);
00944 }
00945 
00946 /********************************************************/
00947 /*                                                      */
00948 /*               hessianMatrixOfGaussian                */
00949 /*                                                      */
00950 /********************************************************/
00951 
00952 /** \brief Filter image with the 2nd derivatives of the Gaussian
00953     at the given scale to get the Hessian matrix.
00954 
00955     The Hessian matrix is a symmetric matrix defined as:
00956 
00957     \f[
00958         \mbox{\rm Hessian}(I) = \left(
00959         \begin{array}{cc}
00960         G_{xx} \ast I & G_{xy} \ast I \\
00961         G_{xy} \ast I & G_{yy} \ast I
00962         \end{array} \right)
00963     \f]
00964 
00965     where \f$G_{xx}, G_{xy}, G_{yy}\f$ denote 2nd derivatives of Gaussians
00966     at the given scale, and
00967     \f$\ast\f$ is the convolution symbol. This function calls
00968     \link SeparableConvolution#separableConvolveX separableConvolveX\endlink() and
00969     \link SeparableConvolution#separableConvolveY separableConvolveY\endlink()
00970     with the appropriate 2nd derivative
00971     of Gaussian kernels and puts the results in
00972     the three destination images. The first destination image will
00973     contain the second derivative in x-direction, the second one the mixed
00974     derivative, and the third one holds the derivative in y-direction.
00975 
00976     <b> Declarations:</b>
00977 
00978     pass arguments explicitly:
00979     \code
00980     namespace vigra {
00981         template <class SrcIterator, class SrcAccessor,
00982                   class DestIteratorX, class DestAccessorX,
00983                   class DestIteratorXY, class DestAccessorXY,
00984                   class DestIteratorY, class DestAccessorY>
00985         void hessianMatrixOfGaussian(SrcIterator supperleft,
00986                                 SrcIterator slowerright, SrcAccessor sa,
00987                                 DestIteratorX dupperleftx, DestAccessorX dax,
00988                                 DestIteratorXY dupperleftxy, DestAccessorXY daxy,
00989                                 DestIteratorY dupperlefty, DestAccessorY day,
00990                                 double scale);
00991     }
00992     \endcode
00993 
00994 
00995     use argument objects in conjunction with \ref ArgumentObjectFactories:
00996     \code
00997     namespace vigra {
00998         template <class SrcIterator, class SrcAccessor,
00999                   class DestIteratorX, class DestAccessorX,
01000                   class DestIteratorXY, class DestAccessorXY,
01001                   class DestIteratorY, class DestAccessorY>
01002         inline void
01003         hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
01004                           pair<DestIteratorX, DestAccessorX> destx,
01005                           pair<DestIteratorXY, DestAccessorXY> destxy,
01006                           pair<DestIteratorY, DestAccessorY> desty,
01007                           double scale);
01008     }
01009     \endcode
01010 
01011     <b> Usage:</b>
01012 
01013     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
01014 
01015 
01016     \code
01017     vigra::FImage src(w,h), hxx(w,h), hxy(w,h), hyy(w,h);
01018     ...
01019 
01020     // calculate Hessian of Gaussian at scale = 3.0
01021     vigra::hessianMatrixOfGaussian(srcImageRange(src),
01022         destImage(hxx), destImage(hxy), destImage(hyy), 3.0);
01023 
01024     \endcode
01025 
01026 */
01027 template <class SrcIterator, class SrcAccessor,
01028           class DestIteratorX, class DestAccessorX,
01029           class DestIteratorXY, class DestAccessorXY,
01030           class DestIteratorY, class DestAccessorY>
01031 void hessianMatrixOfGaussian(SrcIterator supperleft,
01032                         SrcIterator slowerright, SrcAccessor sa,
01033                         DestIteratorX dupperleftx, DestAccessorX dax,
01034                         DestIteratorXY dupperleftxy, DestAccessorXY daxy,
01035                         DestIteratorY dupperlefty, DestAccessorY day,
01036                         double scale)
01037 {
01038     typedef typename
01039         NumericTraits<typename SrcAccessor::value_type>::RealPromote
01040         TmpType;
01041     BasicImage<TmpType> tmp(slowerright - supperleft);
01042 
01043     Kernel1D<double> smooth, deriv1, deriv2;
01044     smooth.initGaussian(scale);
01045     deriv1.initGaussianDerivative(scale, 1);
01046     deriv2.initGaussianDerivative(scale, 2);
01047 
01048     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
01049                        destImage(tmp), kernel1d(deriv2));
01050     separableConvolveY(srcImageRange(tmp),
01051                        destIter(dupperleftx, dax), kernel1d(smooth));
01052     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
01053                        destImage(tmp), kernel1d(smooth));
01054     separableConvolveY(srcImageRange(tmp),
01055                        destIter(dupperlefty, day), kernel1d(deriv2));
01056     separableConvolveX(srcIterRange(supperleft, slowerright, sa),
01057                        destImage(tmp), kernel1d(deriv1));
01058     separableConvolveY(srcImageRange(tmp),
01059                        destIter(dupperleftxy, daxy), kernel1d(deriv1));
01060 }
01061 
01062 template <class SrcIterator, class SrcAccessor,
01063           class DestIteratorX, class DestAccessorX,
01064           class DestIteratorXY, class DestAccessorXY,
01065           class DestIteratorY, class DestAccessorY>
01066 inline void
01067 hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
01068                   pair<DestIteratorX, DestAccessorX> destx,
01069                   pair<DestIteratorXY, DestAccessorXY> destxy,
01070                   pair<DestIteratorY, DestAccessorY> desty,
01071                   double scale)
01072 {
01073     hessianMatrixOfGaussian(src.first, src.second, src.third,
01074                  destx.first, destx.second,
01075                  destxy.first, destxy.second,
01076                  desty.first, desty.second,
01077                  scale);
01078 }
01079 
01080 /********************************************************/
01081 /*                                                      */
01082 /*                   structureTensor                    */
01083 /*                                                      */
01084 /********************************************************/
01085 
01086 /** \brief Calculate the Structure Tensor for each pixel of
01087  and image, using Gaussian (derivative) filters.
01088 
01089     The Structure Tensor is is a smoothed version of the Euclidean product
01090     of the gradient vector with itself. I.e. it's a symmetric matrix defined as:
01091 
01092     \f[
01093         \mbox{\rm StructurTensor}(I) = \left(
01094         \begin{array}{cc}
01095         G \ast (I_x I_x) & G \ast (I_x I_y) \\
01096         G \ast (I_x I_y) & G \ast (I_y I_y)
01097         \end{array} \right) = \left(
01098         \begin{array}{cc}
01099         A & C \\
01100         C & B
01101         \end{array} \right)
01102     \f]
01103 
01104     where \f$G\f$ denotes Gaussian smoothing at the <i>outer scale</i>,
01105     \f$I_x, I_y\f$ are the gradient components taken at the <i>inner scale</i>,
01106     \f$\ast\f$ is the convolution symbol, and \f$I_x I_x\f$ etc. are pixelwise
01107     products of the 1st derivative images. This function calls
01108     \link SeparableConvolution#separableConvolveX separableConvolveX\endlink()
01109     and \link SeparableConvolution#separableConvolveY separableConvolveY\endlink() with the
01110     appropriate Gaussian kernels and puts the results in
01111     the three destination images. The first destination image will
01112     contain \f$G \ast (I_x I_x)\f$, the second one \f$G \ast (I_x I_y)\f$, and the
01113     third one holds \f$G \ast (I_y I_y)\f$.
01114 
01115     <b> Declarations:</b>
01116 
01117     pass arguments explicitly:
01118     \code
01119     namespace vigra {
01120         template <class SrcIterator, class SrcAccessor,
01121                   class DestIteratorX, class DestAccessorX,
01122                   class DestIteratorXY, class DestAccessorXY,
01123                   class DestIteratorY, class DestAccessorY>
01124         void structureTensor(SrcIterator supperleft,
01125                                 SrcIterator slowerright, SrcAccessor sa,
01126                                 DestIteratorX dupperleftx, DestAccessorX dax,
01127                                 DestIteratorXY dupperleftxy, DestAccessorXY daxy,
01128                                 DestIteratorY dupperlefty, DestAccessorY day,
01129                                 double inner_scale, double outer_scale);
01130     }
01131     \endcode
01132 
01133 
01134     use argument objects in conjunction with \ref ArgumentObjectFactories:
01135     \code
01136     namespace vigra {
01137         template <class SrcIterator, class SrcAccessor,
01138                   class DestIteratorX, class DestAccessorX,
01139                   class DestIteratorXY, class DestAccessorXY,
01140                   class DestIteratorY, class DestAccessorY>
01141         inline void
01142         structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
01143                           pair<DestIteratorX, DestAccessorX> destx,
01144                           pair<DestIteratorXY, DestAccessorXY> destxy,
01145                           pair<DestIteratorY, DestAccessorY> desty,
01146                           double nner_scale, double outer_scale);
01147     }
01148     \endcode
01149 
01150     <b> Usage:</b>
01151 
01152     <b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolution.hxx</a>"
01153 
01154 
01155     \code
01156     vigra::FImage src(w,h), stxx(w,h), stxy(w,h), styy(w,h);
01157     ...
01158 
01159     // calculate Structure Tensor at inner scale = 1.0 and outer scale = 3.0
01160     vigra::structureTensor(srcImageRange(src),
01161         destImage(stxx), destImage(stxy), destImage(styy), 1.0, 3.0);
01162 
01163     \endcode
01164 
01165 */
01166 template <class SrcIterator, class SrcAccessor,
01167           class DestIteratorX, class DestAccessorX,
01168           class DestIteratorXY, class DestAccessorXY,
01169           class DestIteratorY, class DestAccessorY>
01170 void structureTensor(SrcIterator supperleft,
01171                         SrcIterator slowerright, SrcAccessor sa,
01172                         DestIteratorX dupperleftx, DestAccessorX dax,
01173                         DestIteratorXY dupperleftxy, DestAccessorXY daxy,
01174                         DestIteratorY dupperlefty, DestAccessorY day,
01175                         double inner_scale, double outer_scale)
01176 {
01177     typedef typename
01178         NumericTraits<typename SrcAccessor::value_type>::RealPromote
01179         TmpType;
01180     BasicImage<TmpType> tmp(slowerright - supperleft),
01181                         tmpx(slowerright - supperleft),
01182                         tmpy(slowerright - supperleft);
01183 
01184     gaussianGradient(srcIterRange(supperleft, slowerright, sa),
01185            destImage(tmpx), destImage(tmpy), inner_scale);
01186     combineTwoImages(srcImageRange(tmpx), srcImage(tmpx),
01187                      destImage(tmp), std::multiplies<TmpType>());
01188     gaussianSmoothing(srcImageRange(tmp),
01189                       destIter(dupperleftx, dax), outer_scale);
01190     combineTwoImages(srcImageRange(tmpy), srcImage(tmpy),
01191                      destImage(tmp), std::multiplies<TmpType>());
01192     gaussianSmoothing(srcImageRange(tmp),
01193                       destIter(dupperlefty, day), outer_scale);
01194     combineTwoImages(srcImageRange(tmpx), srcImage(tmpy),
01195                      destImage(tmp), std::multiplies<TmpType>());
01196     gaussianSmoothing(srcImageRange(tmp),
01197                       destIter(dupperleftxy, daxy), outer_scale);
01198 }
01199 
01200 template <class SrcIterator, class SrcAccessor,
01201           class DestIteratorX, class DestAccessorX,
01202           class DestIteratorXY, class DestAccessorXY,
01203           class DestIteratorY, class DestAccessorY>
01204 inline void
01205 structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
01206                   pair<DestIteratorX, DestAccessorX> destx,
01207                   pair<DestIteratorXY, DestAccessorXY> destxy,
01208                   pair<DestIteratorY, DestAccessorY> desty,
01209                   double inner_scale, double outer_scale)
01210 {
01211     structureTensor(src.first, src.second, src.third,
01212                  destx.first, destx.second,
01213                  destxy.first, destxy.second,
01214                  desty.first, desty.second,
01215                  inner_scale, outer_scale);
01216 }
01217 
01218 //@}
01219 
01220 } // namespace vigra
01221 
01222 #endif // VIGRA_CONVOLUTION_HXX

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

html generated using doxygen and Python
VIGRA 1.5.0 (7 Dec 2006)