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

vigra/recursiveconvolution.hxx

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.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_RECURSIVECONVOLUTION_HXX
00040 #define VIGRA_RECURSIVECONVOLUTION_HXX
00041 
00042 #include <cmath>
00043 #include <vector>
00044 #include "utilities.hxx"
00045 #include "numerictraits.hxx"
00046 #include "imageiteratoradapter.hxx"
00047 #include "bordertreatment.hxx"
00048 
00049 namespace vigra {
00050 
00051 /********************************************************/
00052 /*                                                      */
00053 /*         Recursive convolution functions              */
00054 /*                                                      */
00055 /********************************************************/
00056 
00057 /** \addtogroup RecursiveConvolution Recursive convolution functions
00058     
00059     First order recursive filters and their specialization for 
00060     the exponential filter and its derivatives (1D and separable 2D).
00061     These filters are very fast, and the speed does not depend on the 
00062     filter size. 
00063 */
00064 //@{
00065 
00066 /********************************************************/
00067 /*                                                      */
00068 /*                   recursiveFilterLine                */
00069 /*                                                      */
00070 /********************************************************/
00071 
00072 /** \brief Performs a 1-dimensional recursive convolution of the source signal.
00073 
00074     The function performs a causal and an anti-causal first or second order 
00075     recursive filtering with the given filter parameter <TT>b1</TT> and 
00076     border treatment <TT>border</TT> (first order filter, <TT>b2 = 0</TT>) or parameters 
00077     <TT>b1, b2</TT> and <TT>BORDER_TREATMENT_REFLECT</TT> (second order filter). Thus, 
00078     the result is always a filtering with linear phase.
00079     \f[
00080         \begin{array}{rcl}
00081         a_{i, causal} & = & source_i + b1 * a_{i-1, causal} + b2 * a_{i-2, causal} \\
00082         a_{i, anticausal} & = & source_i + b1 * a_{i+1, anticausal} + b2 * a_{i+2, anticausal} \\
00083         dest_i & = & \frac{1 - b1 - b2}{1 + b1 + b2}(a_{i, causal} + a_{i, anticausal} - source_i)
00084         \end{array}
00085     \f]
00086    
00087     The signal's value_type (SrcAccessor::value_type) must be a
00088     linear space over <TT>double</TT>,
00089     i.e. addition of source values, multiplication with <TT>double</TT>,
00090     and <TT>NumericTraits</TT> must be defined.     
00091     
00092     <b> Declaration:</b>
00093     
00094     <b>First order recursive filter:</b>
00095     
00096     \code
00097     namespace vigra {
00098         template <class SrcIterator, class SrcAccessor,
00099               class DestIterator, class DestAccessor>
00100         void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00101                      DestIterator id, DestAccessor ad, 
00102                      double b1, BorderTreatmentMode border)
00103     }
00104     \endcode
00105     
00106     <b>Second order recursive filter:</b>
00107     
00108     \code
00109     namespace vigra {
00110         template <class SrcIterator, class SrcAccessor,
00111               class DestIterator, class DestAccessor>
00112         void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00113                      DestIterator id, DestAccessor ad, 
00114                      double b1, double b2)
00115     }
00116     \endcode
00117     
00118     <b> Usage:</b>
00119     
00120     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
00121     Namespace: vigra
00122     
00123     
00124     \code
00125     vector<float> src, dest;    
00126     ...
00127     
00128     vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
00129     
00130     
00131     vigra::recursiveFilterLine(src.begin(), src.end(), FAccessor(), 
00132                                dest.begin(), FAccessor(), 
00133                                0.5, BORDER_TREATMENT_REFLECT);
00134     \endcode
00135 
00136     <b> Required Interface:</b>
00137     
00138     \code
00139     RandomAccessIterator is, isend;
00140     RandomAccessIterator id;
00141     
00142     SrcAccessor src_accessor;
00143     DestAccessor dest_accessor;
00144     
00145     NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
00146     double d;
00147     
00148     s = s + s;
00149     s = d * s;
00150 
00151     dest_accessor.set(
00152         NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
00153 
00154     \endcode
00155 
00156     <b> Preconditions:</b>
00157     
00158     \code
00159     -1 < b  < 1
00160     \endcode
00161 
00162 */
00163 doxygen_overloaded_function(template <...> void recursiveFilterLine)
00164 
00165 template <class SrcIterator, class SrcAccessor,
00166           class DestIterator, class DestAccessor>
00167 void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00168                          DestIterator id, DestAccessor ad, double b, BorderTreatmentMode border)
00169 {
00170     int w = isend - is;
00171     SrcIterator istart = is;
00172     
00173     int x;
00174     
00175     vigra_precondition(-1.0 < b && b < 1.0,
00176                  "recursiveFilterLine(): -1 < factor < 1 required.\n");
00177                  
00178     if(b == 0.0)
00179     {
00180         for(; is != isend; ++is, ++id)
00181         {
00182             ad.set(as(is), id);
00183         }
00184         return;
00185     }
00186 
00187     double eps = 0.00001;
00188     int kernelw = std::min(w-1, (int)(VIGRA_CSTD::log(eps)/VIGRA_CSTD::log(VIGRA_CSTD::fabs(b))));
00189     
00190     typedef typename
00191         NumericTraits<typename SrcAccessor::value_type>::RealPromote TempType;
00192     typedef NumericTraits<typename DestAccessor::value_type> DestTraits;
00193     
00194     // store result of causal filtering
00195     std::vector<TempType> vline(w);
00196     typename std::vector<TempType>::iterator line = vline.begin();
00197     
00198     double norm = (1.0 - b) / (1.0 + b);
00199 
00200     TempType old;
00201     
00202     if(border == BORDER_TREATMENT_REPEAT ||
00203        border == BORDER_TREATMENT_AVOID)
00204     {
00205          old = (1.0 / (1.0 - b)) * as(is);
00206     }
00207     else if(border == BORDER_TREATMENT_REFLECT)
00208     {
00209         is += kernelw;
00210         old = (1.0 / (1.0 - b)) * as(is);
00211         for(x = 0; x < kernelw; ++x, --is)
00212             old = as(is) + b * old;
00213     }
00214     else if(border == BORDER_TREATMENT_WRAP)
00215     {
00216         is = isend - kernelw; 
00217         old = (1.0 / (1.0 - b)) * as(is);
00218         for(x = 0; x < kernelw; ++x, ++is)
00219             old = as(is) + b * old;
00220     }
00221     else if(border == BORDER_TREATMENT_CLIP)
00222     {
00223         old = NumericTraits<TempType>::zero();
00224     }
00225     else
00226         vigra_fail("recursiveFilterLine(): Unknown border treatment mode.\n");
00227 
00228     // left side of filter
00229     for(x=0, is = istart; x < w; ++x, ++is)
00230     {
00231         old = as(is) + b * old;
00232         line[x] = old;
00233     }
00234 
00235     // right side of the filter
00236     if(border == BORDER_TREATMENT_REPEAT ||
00237        border == BORDER_TREATMENT_AVOID)
00238     {
00239         is = isend - 1;
00240         old = (1.0 / (1.0 - b)) * as(is);
00241     }
00242     else if(border == BORDER_TREATMENT_REFLECT)
00243     {
00244         old = line[w-2];
00245     }
00246     else if(border == BORDER_TREATMENT_WRAP)
00247     {
00248       is = istart + kernelw - 1;
00249       old = (1.0 / (1.0 - b)) * as(is);
00250       for(x = 0; x < kernelw; ++x, --is)
00251           old = as(is) + b * old;
00252     }
00253     else if(border == BORDER_TREATMENT_CLIP)
00254     {
00255         old = NumericTraits<TempType>::zero();
00256     }
00257     
00258     is = isend - 1;
00259     id += w - 1;
00260     if(border == BORDER_TREATMENT_CLIP)
00261     {    
00262        // correction factors for b
00263         double bright = b;
00264         double bleft = VIGRA_CSTD::pow(b, w);
00265 
00266         for(x=w-1; x>=0; --x, --is, --id)
00267         {    
00268             TempType f = b * old;
00269             old = as(is) + f;
00270             double norm = (1.0 - b) / (1.0 + b - bleft - bright);
00271             bleft /= b;
00272             bright *= b;
00273             ad.set(norm * (line[x] + f), id);
00274         }
00275     }
00276     else if(border == BORDER_TREATMENT_AVOID)
00277     {
00278         for(x=w-1; x >= kernelw; --x, --is, --id)
00279         {    
00280             TempType f = b * old;
00281             old = as(is) + f;
00282             if(x < w - kernelw)
00283                 ad.set(DestTraits::fromRealPromote(norm * (line[x] + f)), id);
00284         }
00285     }
00286     else
00287     {
00288         for(x=w-1; x>=0; --x, --is, --id)
00289         {    
00290             TempType f = b * old;
00291             old = as(is) + f;
00292             ad.set(DestTraits::fromRealPromote(norm * (line[x] + f)), id);
00293         }
00294     }
00295 }
00296             
00297 /********************************************************/
00298 /*                                                      */
00299 /*            recursiveFilterLine (2nd order)           */
00300 /*                                                      */
00301 /********************************************************/
00302 
00303 template <class SrcIterator, class SrcAccessor,
00304           class DestIterator, class DestAccessor>
00305 void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00306                          DestIterator id, DestAccessor ad, double b1, double b2)
00307 {
00308     int w = isend - is;
00309     SrcIterator istart = is;
00310     
00311     int x;
00312     
00313     typedef typename
00314         NumericTraits<typename SrcAccessor::value_type>::RealPromote TempType;
00315     typedef NumericTraits<typename DestAccessor::value_type> DestTraits;
00316     
00317     // speichert den Ergebnis der linkseitigen Filterung.
00318     std::vector<TempType> vline(w+1);
00319     typename std::vector<TempType>::iterator line = vline.begin();
00320     
00321     double norm  = 1.0 - b1 - b2;
00322     double norm1 = (1.0 - b1 - b2) / (1.0 + b1 + b2);
00323     double norm2 = norm * norm;
00324     
00325 
00326     // init left side of filter
00327     int kernelw = std::min(w-1, std::max(8, (int)(1.0 / norm + 0.5)));  
00328     is += (kernelw - 2);
00329     line[kernelw] = as(is);
00330     line[kernelw-1] = as(is);
00331     for(x = kernelw - 2; x > 0; --x, --is)
00332     {
00333         line[x] = as(is) + b1 * line[x+1] + b2 * line[x+2];
00334     }
00335     line[0] = as(is) + b1 * line[1] + b2 * line[2];
00336     ++is;
00337     line[1] = as(is) + b1 * line[0] + b2 * line[1];
00338     ++is;
00339     for(x=2; x < w; ++x, ++is)
00340     {
00341         line[x] = as(is) + b1 * line[x-1] + b2 * line[x-2];
00342     }
00343     line[w] = line[w-1];
00344 
00345     line[w-1] = norm1 * (line[w-1] + b1 * line[w-2] + b2 * line[w-3]);
00346     line[w-2] = norm1 * (line[w-2] + b1 * line[w] + b2 * line[w-2]);
00347     id += w-1;
00348     ad.set(line[w-1], id);
00349     --id;
00350     ad.set(line[w-2], id);
00351     --id;
00352     for(x=w-3; x>=0; --x, --id, --is)
00353     {    
00354         line[x] = norm2 * line[x] + b1 * line[x+1] + b2 * line[x+2];
00355         ad.set(line[x], id);
00356     }
00357 }
00358             
00359 /********************************************************/
00360 /*                                                      */
00361 /*                    recursiveSmoothLine               */
00362 /*                                                      */
00363 /********************************************************/
00364 
00365 /** \brief Convolves the image with a 1-dimensional exponential filter.
00366 
00367     This function calls \ref recursiveFilterLine() with <TT>b = exp(-1.0/scale)</TT>
00368     and <TT>border = BORDER_TREATMENT_REPEAT</TT>. See 
00369     \ref recursiveFilterLine() for more documentation.
00370     
00371     <b> Declaration:</b>
00372     
00373     \code
00374     namespace vigra {
00375         template <class SrcIterator, class SrcAccessor,
00376               class DestIterator, class DestAccessor>
00377         void recursiveSmoothLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00378                      DestIterator id, DestAccessor ad, double scale)
00379     }
00380     \endcode
00381     
00382     <b> Usage:</b>
00383     
00384     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
00385     Namespace: vigra
00386     
00387     
00388     \code
00389     vector<float> src, dest;    
00390     ...
00391     
00392     vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
00393     
00394     
00395     vigra::recursiveSmoothLine(src.begin(), src.end(), FAccessor(), 
00396                         dest.begin(), FAccessor(), 3.0);
00397     \endcode
00398 
00399     <b> Required Interface:</b>
00400     
00401     \code
00402     RandomAccessIterator is, isend;
00403     RandomAccessIterator id;
00404     
00405     SrcAccessor src_accessor;
00406     DestAccessor dest_accessor;
00407     
00408     NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
00409     double d;
00410     
00411     s = s + s;
00412     s = d * s;
00413 
00414     dest_accessor.set(
00415         NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
00416 
00417     \endcode
00418 
00419     <b> Preconditions:</b>
00420     
00421     \code
00422     scale > 0
00423     \endcode
00424 
00425 */
00426 doxygen_overloaded_function(template <...> void recursiveSmoothLine)
00427 
00428 template <class SrcIterator, class SrcAccessor,
00429           class DestIterator, class DestAccessor>
00430 inline 
00431 void recursiveSmoothLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00432                          DestIterator id, DestAccessor ad, double scale)
00433 {
00434     vigra_precondition(scale >= 0,
00435                  "recursiveSmoothLine(): scale must be >= 0.\n");
00436                  
00437     double b = (scale == 0.0) ? 
00438                     0.0 :
00439                     VIGRA_CSTD::exp(-1.0/scale);
00440     
00441     recursiveFilterLine(is, isend, as, id, ad, b, BORDER_TREATMENT_REPEAT);
00442 }
00443             
00444 /********************************************************/
00445 /*                                                      */
00446 /*             recursiveFirstDerivativeLine             */
00447 /*                                                      */
00448 /********************************************************/
00449 
00450 /** \brief Performs a 1 dimensional recursive convolution of the source signal.
00451 
00452     It uses the first derivative an exponential  <TT>d/dx exp(-abs(x)/scale)</TT> as 
00453     a kernel. The signal's value_type (SrcAccessor::value_type) must be a
00454     linear space over <TT>double</TT>,
00455     i.e. addition and subtraction of source values, multiplication with 
00456     <TT>double</TT>, and <TT>NumericTraits</TT> must be defined. Border 
00457     treatment is always <TT>BORDER_TREATMENT_REPEAT</TT>.
00458     
00459     <b> Declaration:</b>
00460     
00461     \code
00462     namespace vigra {
00463         template <class SrcIterator, class SrcAccessor,
00464               class DestIterator, class DestAccessor>
00465         void recursiveFirstDerivativeLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00466                      DestIterator id, DestAccessor ad, double scale)
00467     }
00468     \endcode
00469     
00470     <b> Usage:</b>
00471     
00472     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
00473     Namespace: vigra
00474     
00475     
00476     \code
00477     vector<float> src, dest;    
00478     ...
00479     
00480     vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
00481     
00482     
00483     vigra::recursiveFirstDerivativeLine(src.begin(), src.end(), FAccessor(), 
00484                         dest.begin(), FAccessor(), 3.0);
00485     \endcode
00486 
00487     <b> Required Interface:</b>
00488     
00489     \code
00490     RandomAccessIterator is, isend;
00491     RandomAccessIterator id;
00492     
00493     SrcAccessor src_accessor;
00494     DestAccessor dest_accessor;
00495     
00496     NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
00497     double d;
00498     
00499     s = s + s;
00500     s = -s;
00501     s = d * s;
00502 
00503     dest_accessor.set(
00504         NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
00505 
00506     \endcode
00507 
00508     <b> Preconditions:</b>
00509     
00510     \code
00511     scale > 0
00512     \endcode
00513 
00514 */
00515 doxygen_overloaded_function(template <...> void recursiveFirstDerivativeLine)
00516 
00517 template <class SrcIterator, class SrcAccessor,
00518           class DestIterator, class DestAccessor>
00519 void recursiveFirstDerivativeLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00520                          DestIterator id, DestAccessor ad, double scale)
00521 {
00522     vigra_precondition(scale > 0,
00523                  "recursiveFirstDerivativeLine(): scale must be > 0.\n");
00524 
00525     int w = isend -is;
00526     
00527     int x;
00528     
00529     typedef typename
00530         NumericTraits<typename SrcAccessor::value_type>::RealPromote 
00531     TempType;
00532     typedef NumericTraits<typename DestAccessor::value_type> DestTraits;
00533 
00534     std::vector<TempType> vline(w);
00535     typename std::vector<TempType>::iterator line = vline.begin();
00536     
00537     double b = VIGRA_CSTD::exp(-1.0/scale);
00538     double norm = (1.0 - b) * (1.0 - b) / 2.0 / b;
00539     TempType old = (1.0 / (1.0 - b)) * as(is);
00540 
00541     // left side of filter
00542     for(x=0; x<w; ++x, ++is)
00543     {
00544         old = as(is) + b * old;
00545         line[x] = -old;
00546     }
00547     
00548     // right side of the filter
00549     --is;
00550     old = (1.0 / (1.0 - b)) * as(is);
00551     id += w;
00552     ++is;
00553     
00554     for(x=w-1; x>=0; --x)
00555     {    
00556         --is;
00557         --id;
00558 
00559         old = as(is) + b * old;
00560 
00561         ad.set(DestTraits::fromRealPromote(norm * (line[x] + old)), id);
00562     }
00563 }
00564             
00565 /********************************************************/
00566 /*                                                      */
00567 /*            recursiveSecondDerivativeLine             */
00568 /*                                                      */
00569 /********************************************************/
00570 
00571 /** \brief Performs a 1 dimensional recursive convolution of the source signal.
00572 
00573     It uses the second derivative an exponential  <TT>d2/dx2 exp(-abs(x)/scale)</TT> as 
00574     a kernel. The signal's value_type (SrcAccessor::value_type) must be a
00575     linear space over <TT>double</TT>,
00576     i.e. addition and subtraction of source values, multiplication with 
00577     <TT>double</TT>, and <TT>NumericTraits</TT> must be defined. Border 
00578     treatment is always <TT>BORDER_TREATMENT_REPEAT</TT>.
00579     
00580     <b> Declaration:</b>
00581     
00582     \code
00583     namespace vigra {
00584         template <class SrcIterator, class SrcAccessor,
00585               class DestIterator, class DestAccessor>
00586         void recursiveSecondDerivativeLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00587                      DestIterator id, DestAccessor ad, double scale)
00588     }
00589     \endcode
00590     
00591     <b> Usage:</b>
00592     
00593     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
00594     Namespace: vigra
00595     
00596     
00597     \code
00598     vector<float> src, dest;    
00599     ...
00600     
00601     vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
00602     
00603     
00604     vigra::recursiveSecondDerivativeLine(src.begin(), src.end(), FAccessor(), 
00605                         dest.begin(), FAccessor(), 3.0);
00606     \endcode
00607 
00608     <b> Required Interface:</b>
00609     
00610     \code
00611     RandomAccessIterator is, isend;
00612     RandomAccessIterator id;
00613     
00614     SrcAccessor src_accessor;
00615     DestAccessor dest_accessor;
00616     
00617     NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
00618     double d;
00619     
00620     s = s + s;
00621     s = s - s;
00622     s = d * s;
00623 
00624     dest_accessor.set(
00625         NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
00626 
00627     \endcode
00628 
00629     <b> Preconditions:</b>
00630     
00631     \code
00632     scale > 0
00633     \endcode
00634 
00635 */
00636 doxygen_overloaded_function(template <...> void recursiveSecondDerivativeLine)
00637 
00638 template <class SrcIterator, class SrcAccessor,
00639           class DestIterator, class DestAccessor>
00640 void recursiveSecondDerivativeLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
00641                          DestIterator id, DestAccessor ad, double scale)
00642 {
00643     vigra_precondition(scale > 0,
00644                  "recursiveSecondDerivativeLine(): scale must be > 0.\n");
00645 
00646     int w = isend -is;
00647     
00648     int x;
00649     
00650     typedef typename
00651         NumericTraits<typename SrcAccessor::value_type>::RealPromote 
00652     TempType;
00653     typedef NumericTraits<typename DestAccessor::value_type> DestTraits;
00654     
00655     std::vector<TempType> vline(w);
00656     typename std::vector<TempType>::iterator line = vline.begin();
00657         
00658     double b = VIGRA_CSTD::exp(-1.0/scale);
00659     double a = -2.0 / (1.0 - b);
00660     double norm = (1.0 - b) * (1.0 - b) * (1.0 - b) / (1.0 + b);
00661     TempType old = (1.0 / (1.0 - b)) * as(is);
00662 
00663     // left side of filter
00664     for(x=0; x<w; ++x, ++is)
00665     {
00666         line[x] = old;
00667         old = as(is) + b * old;
00668     }
00669     
00670     // right side of the filter
00671     --is;
00672     old = (1.0 / (1.0 - b)) * as(is);
00673     id += w;
00674     ++is;
00675     
00676     for(x=w-1; x>=0; --x)
00677     {    
00678         --is;
00679         --id;
00680 
00681         TempType f = old + a * as(is);
00682         old = as(is) + b * old;
00683         ad.set(DestTraits::fromRealPromote(norm * (line[x] + f)), id);
00684     }
00685 }
00686             
00687 /********************************************************/
00688 /*                                                      */
00689 /*                   recursiveFilterX                   */
00690 /*                                                      */
00691 /********************************************************/
00692 
00693 /** \brief Performs 1 dimensional recursive filtering (1st and 2nd order) in x direction.
00694 
00695     It calls \ref recursiveFilterLine() for every row of the
00696     image. See \ref recursiveFilterLine() for more information about 
00697     required interfaces and vigra_preconditions.
00698     
00699     <b> Declarations:</b>
00700     
00701     pass arguments explicitly:
00702     \code
00703     namespace vigra {
00704         // first order filter
00705         template <class SrcImageIterator, class SrcAccessor,
00706                   class DestImageIterator, class DestAccessor>
00707         void recursiveFilterX(SrcImageIterator supperleft, 
00708                                SrcImageIterator slowerright, SrcAccessor as,
00709                                DestImageIterator dupperleft, DestAccessor ad, 
00710                                double b, BorderTreatmentMode border);
00711 
00712         // second order filter
00713         template <class SrcImageIterator, class SrcAccessor,
00714                   class DestImageIterator, class DestAccessor>
00715         void recursiveFilterX(SrcImageIterator supperleft, 
00716                                SrcImageIterator slowerright, SrcAccessor as,
00717                                DestImageIterator dupperleft, DestAccessor ad, 
00718                                double b1, double b2);
00719     }
00720     \endcode
00721     
00722     
00723     use argument objects in conjunction with \ref ArgumentObjectFactories :
00724     \code
00725     namespace vigra {
00726         // first order filter
00727         template <class SrcImageIterator, class SrcAccessor,
00728                   class DestImageIterator, class DestAccessor>
00729         void recursiveFilterX(
00730                     triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00731                     pair<DestImageIterator, DestAccessor> dest, 
00732                     double b, BorderTreatmentMode border);
00733 
00734         // second order filter
00735         template <class SrcImageIterator, class SrcAccessor,
00736                   class DestImageIterator, class DestAccessor>
00737         void recursiveFilterX(
00738                     triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00739                     pair<DestImageIterator, DestAccessor> dest, 
00740                     double b1, double b2);
00741             }
00742     \endcode
00743     
00744     <b> Usage:</b>
00745     
00746     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
00747     Namespace: vigra
00748     
00749     \code
00750     vigra::FImage src(w,h), dest(w,h);    
00751     ...
00752     
00753     vigra::recursiveSmoothX(srcImageRange(src), destImage(dest), 
00754            0.5, BORDER_TREATMENT_REFLECT);
00755     
00756     \endcode
00757 
00758 */
00759 doxygen_overloaded_function(template <...> void recursiveFilterX)
00760 
00761 template <class SrcImageIterator, class SrcAccessor,
00762           class DestImageIterator, class DestAccessor>
00763 void recursiveFilterX(SrcImageIterator supperleft, 
00764                        SrcImageIterator slowerright, SrcAccessor as,
00765                        DestImageIterator dupperleft, DestAccessor ad, 
00766                        double b, BorderTreatmentMode border)
00767 {
00768     int w = slowerright.x - supperleft.x;
00769     int h = slowerright.y - supperleft.y;
00770     
00771     int y;
00772     
00773     for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
00774     {
00775         typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
00776         typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
00777 
00778         recursiveFilterLine(rs, rs+w, as, 
00779                              rd, ad, 
00780                              b, border);
00781     }
00782 }
00783             
00784 template <class SrcImageIterator, class SrcAccessor,
00785           class DestImageIterator, class DestAccessor>
00786 inline void recursiveFilterX(
00787             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00788             pair<DestImageIterator, DestAccessor> dest, 
00789             double b, BorderTreatmentMode border)
00790 {
00791     recursiveFilterX(src.first, src.second, src.third,
00792                       dest.first, dest.second, b, border);
00793 }
00794 
00795 /********************************************************/
00796 /*                                                      */
00797 /*            recursiveFilterX (2nd order)              */
00798 /*                                                      */
00799 /********************************************************/
00800 
00801 template <class SrcImageIterator, class SrcAccessor,
00802           class DestImageIterator, class DestAccessor>
00803 void recursiveFilterX(SrcImageIterator supperleft, 
00804                        SrcImageIterator slowerright, SrcAccessor as,
00805                        DestImageIterator dupperleft, DestAccessor ad, 
00806                        double b1, double b2)
00807 {
00808     int w = slowerright.x - supperleft.x;
00809     int h = slowerright.y - supperleft.y;
00810     
00811     int y;
00812     
00813     for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
00814     {
00815         typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
00816         typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
00817 
00818         recursiveFilterLine(rs, rs+w, as, 
00819                              rd, ad, 
00820                              b1, b2);
00821     }
00822 }
00823 
00824 template <class SrcImageIterator, class SrcAccessor,
00825           class DestImageIterator, class DestAccessor>
00826 inline void recursiveFilterX(
00827             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00828             pair<DestImageIterator, DestAccessor> dest, 
00829                        double b1, double b2)
00830 {
00831     recursiveFilterX(src.first, src.second, src.third,
00832                       dest.first, dest.second, b1, b2);
00833 }
00834             
00835 /********************************************************/
00836 /*                                                      */
00837 /*                    recursiveSmoothX                  */
00838 /*                                                      */
00839 /********************************************************/
00840 
00841 /** \brief Performs 1 dimensional recursive smoothing in x direction.
00842 
00843     It calls \ref recursiveSmoothLine() for every row of the
00844     image. See \ref recursiveSmoothLine() for more information about 
00845     required interfaces and vigra_preconditions.
00846     
00847     <b> Declarations:</b>
00848     
00849     pass arguments explicitly:
00850     \code
00851     namespace vigra {
00852         template <class SrcImageIterator, class SrcAccessor,
00853               class DestImageIterator, class DestAccessor>
00854         void recursiveSmoothX(SrcImageIterator supperleft, 
00855                   SrcImageIterator slowerright, SrcAccessor as,
00856                   DestImageIterator dupperleft, DestAccessor ad, 
00857                   double scale)
00858     }
00859     \endcode
00860     
00861     
00862     use argument objects in conjunction with \ref ArgumentObjectFactories :
00863     \code
00864     namespace vigra {
00865         template <class SrcImageIterator, class SrcAccessor,
00866               class DestImageIterator, class DestAccessor>
00867         void recursiveSmoothX(
00868             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00869             pair<DestImageIterator, DestAccessor> dest, 
00870             double scale)
00871     }
00872     \endcode
00873     
00874     <b> Usage:</b>
00875     
00876     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
00877     Namespace: vigra
00878     
00879     \code
00880     vigra::FImage src(w,h), dest(w,h);    
00881     ...
00882     
00883     vigra::recursiveSmoothX(srcImageRange(src), destImage(dest), 3.0);
00884     
00885     \endcode
00886 
00887 */
00888 doxygen_overloaded_function(template <...> void recursiveSmoothX)
00889 
00890 template <class SrcImageIterator, class SrcAccessor,
00891           class DestImageIterator, class DestAccessor>
00892 void recursiveSmoothX(SrcImageIterator supperleft, 
00893                       SrcImageIterator slowerright, SrcAccessor as,
00894                       DestImageIterator dupperleft, DestAccessor ad, 
00895               double scale)
00896 {
00897     int w = slowerright.x - supperleft.x;
00898     int h = slowerright.y - supperleft.y;
00899     
00900     int y;
00901     
00902     for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
00903     {
00904         typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
00905         typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
00906 
00907         recursiveSmoothLine(rs, rs+w, as, 
00908                             rd, ad, 
00909                             scale);
00910     }
00911 }
00912             
00913 template <class SrcImageIterator, class SrcAccessor,
00914           class DestImageIterator, class DestAccessor>
00915 inline void recursiveSmoothX(
00916             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00917             pair<DestImageIterator, DestAccessor> dest, 
00918         double scale)
00919 {
00920     recursiveSmoothX(src.first, src.second, src.third,
00921                      dest. first, dest.second, scale);
00922 }
00923             
00924 /********************************************************/
00925 /*                                                      */
00926 /*                     recursiveFilterY                 */
00927 /*                                                      */
00928 /********************************************************/
00929 
00930 /** \brief Performs 1 dimensional recursive filtering (1st and 2nd order) in y direction.
00931 
00932     It calls \ref recursiveFilterLine() for every column of the
00933     image. See \ref recursiveFilterLine() for more information about 
00934     required interfaces and vigra_preconditions.
00935     
00936     <b> Declarations:</b>
00937     
00938     pass arguments explicitly:
00939     \code
00940     namespace vigra {
00941         // first order filter
00942         template <class SrcImageIterator, class SrcAccessor,
00943                   class DestImageIterator, class DestAccessor>
00944         void recursiveFilterY(SrcImageIterator supperleft, 
00945                                SrcImageIterator slowerright, SrcAccessor as,
00946                                DestImageIterator dupperleft, DestAccessor ad, 
00947                                double b, BorderTreatmentMode border);
00948 
00949         // second order filter
00950         template <class SrcImageIterator, class SrcAccessor,
00951                   class DestImageIterator, class DestAccessor>
00952         void recursiveFilterY(SrcImageIterator supperleft, 
00953                                SrcImageIterator slowerright, SrcAccessor as,
00954                                DestImageIterator dupperleft, DestAccessor ad, 
00955                                double b1, double b2);
00956     }
00957     \endcode
00958     
00959     
00960     use argument objects in conjunction with \ref ArgumentObjectFactories :
00961     \code
00962     namespace vigra {
00963         // first order filter
00964         template <class SrcImageIterator, class SrcAccessor,
00965                   class DestImageIterator, class DestAccessor>
00966         void recursiveFilterY(
00967                     triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00968                     pair<DestImageIterator, DestAccessor> dest, 
00969                     double b, BorderTreatmentMode border);
00970 
00971         // second order filter
00972         template <class SrcImageIterator, class SrcAccessor,
00973                   class DestImageIterator, class DestAccessor>
00974         void recursiveFilterY(
00975                     triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00976                     pair<DestImageIterator, DestAccessor> dest, 
00977                     double b1, double b2);
00978             }
00979     \endcode
00980     
00981     <b> Usage:</b>
00982     
00983     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
00984     Namespace: vigra
00985     
00986     \code
00987     vigra::FImage src(w,h), dest(w,h);    
00988     ...
00989     
00990     vigra::recursiveFilterY(srcImageRange(src), destImage(dest), -0.6, -0.06);
00991     
00992     \endcode
00993 
00994 */
00995 doxygen_overloaded_function(template <...> void recursiveFilterY)
00996 
00997 template <class SrcImageIterator, class SrcAccessor,
00998           class DestImageIterator, class DestAccessor>
00999 void recursiveFilterY(SrcImageIterator supperleft, 
01000                        SrcImageIterator slowerright, SrcAccessor as,
01001                        DestImageIterator dupperleft, DestAccessor ad, 
01002                        double b, BorderTreatmentMode border)
01003 {
01004     int w = slowerright.x - supperleft.x;
01005     int h = slowerright.y - supperleft.y;
01006     
01007     int x;
01008     
01009     for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
01010     {
01011         typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
01012         typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
01013 
01014         recursiveFilterLine(cs, cs+h, as, 
01015                             cd, ad, 
01016                             b, border);
01017     }
01018 }
01019             
01020 template <class SrcImageIterator, class SrcAccessor,
01021           class DestImageIterator, class DestAccessor>
01022 inline void recursiveFilterY(
01023             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01024             pair<DestImageIterator, DestAccessor> dest, 
01025             double b, BorderTreatmentMode border)
01026 {
01027     recursiveFilterY(src.first, src.second, src.third,
01028                       dest.first, dest.second, b, border);
01029 }
01030 
01031 /********************************************************/
01032 /*                                                      */
01033 /*            recursiveFilterY (2nd order)              */
01034 /*                                                      */
01035 /********************************************************/
01036 
01037 template <class SrcImageIterator, class SrcAccessor,
01038           class DestImageIterator, class DestAccessor>
01039 void recursiveFilterY(SrcImageIterator supperleft, 
01040                        SrcImageIterator slowerright, SrcAccessor as,
01041                        DestImageIterator dupperleft, DestAccessor ad, 
01042                        double b1, double b2)
01043 {
01044     int w = slowerright.x - supperleft.x;
01045     int h = slowerright.y - supperleft.y;
01046     
01047     int x;
01048     
01049     for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
01050     {
01051         typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
01052         typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
01053 
01054         recursiveFilterLine(cs, cs+h, as, 
01055                             cd, ad, 
01056                             b1, b2);
01057     }
01058 }
01059 
01060 template <class SrcImageIterator, class SrcAccessor,
01061           class DestImageIterator, class DestAccessor>
01062 inline void recursiveFilterY(
01063             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01064             pair<DestImageIterator, DestAccessor> dest, 
01065                        double b1, double b2)
01066 {
01067     recursiveFilterY(src.first, src.second, src.third,
01068                       dest.first, dest.second, b1, b2);
01069 }
01070             
01071 /********************************************************/
01072 /*                                                      */
01073 /*                     recursiveSmoothY                 */
01074 /*                                                      */
01075 /********************************************************/
01076 
01077 /** \brief Performs 1 dimensional recursive smoothing in y direction.
01078 
01079     It calls \ref recursiveSmoothLine() for every column of the
01080     image. See \ref recursiveSmoothLine() for more information about 
01081     required interfaces and vigra_preconditions.
01082     
01083     <b> Declarations:</b>
01084     
01085     pass arguments explicitly:
01086     \code
01087     namespace vigra {
01088         template <class SrcImageIterator, class SrcAccessor,
01089               class DestImageIterator, class DestAccessor>
01090         void recursiveSmoothY(SrcImageIterator supperleft, 
01091                   SrcImageIterator slowerright, SrcAccessor as,
01092                   DestImageIterator dupperleft, DestAccessor ad, 
01093                   double scale)
01094     }
01095     \endcode
01096     
01097     
01098     use argument objects in conjunction with \ref ArgumentObjectFactories :
01099     \code
01100     namespace vigra {
01101         template <class SrcImageIterator, class SrcAccessor,
01102               class DestImageIterator, class DestAccessor>
01103         void recursiveSmoothY(
01104             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01105             pair<DestImageIterator, DestAccessor> dest, 
01106             double scale)
01107     }
01108     \endcode
01109     
01110     <b> Usage:</b>
01111     
01112     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
01113     Namespace: vigra
01114     
01115     \code
01116     vigra::FImage src(w,h), dest(w,h);    
01117     ...
01118     
01119     vigra::recursiveSmoothY(srcImageRange(src), destImage(dest), 3.0);
01120     
01121     \endcode
01122 
01123 */
01124 doxygen_overloaded_function(template <...> void recursiveSmoothY)
01125 
01126 template <class SrcImageIterator, class SrcAccessor,
01127           class DestImageIterator, class DestAccessor>
01128 void recursiveSmoothY(SrcImageIterator supperleft, 
01129                       SrcImageIterator slowerright, SrcAccessor as,
01130                       DestImageIterator dupperleft, DestAccessor ad, 
01131               double scale)
01132 {
01133     int w = slowerright.x - supperleft.x;
01134     int h = slowerright.y - supperleft.y;
01135     
01136     int x;
01137     
01138     for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
01139     {
01140         typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
01141         typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
01142 
01143         recursiveSmoothLine(cs, cs+h, as, 
01144                             cd, ad, 
01145                             scale);
01146     }
01147 }
01148             
01149 template <class SrcImageIterator, class SrcAccessor,
01150           class DestImageIterator, class DestAccessor>
01151 inline void recursiveSmoothY(
01152             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01153             pair<DestImageIterator, DestAccessor> dest, 
01154             double scale)
01155 {
01156     recursiveSmoothY(src.first, src.second, src.third,
01157                      dest. first, dest.second, scale);
01158 }
01159             
01160 /********************************************************/
01161 /*                                                      */
01162 /*              recursiveFirstDerivativeX               */
01163 /*                                                      */
01164 /********************************************************/
01165 
01166 /** \brief Recursively calculates the 1 dimensional first derivative in x 
01167     direction.
01168     
01169     It calls \ref recursiveFirstDerivativeLine() for every 
01170     row of the image. See \ref recursiveFirstDerivativeLine() for more 
01171     information about required interfaces and vigra_preconditions.
01172     
01173     <b> Declarations:</b>
01174     
01175     pass arguments explicitly:
01176     \code
01177     namespace vigra {
01178         template <class SrcImageIterator, class SrcAccessor,
01179               class DestImageIterator, class DestAccessor>
01180         void recursiveFirstDerivativeX(SrcImageIterator supperleft, 
01181                   SrcImageIterator slowerright, SrcAccessor as,
01182                   DestImageIterator dupperleft, DestAccessor ad, 
01183                   double scale)
01184     }
01185     \endcode
01186     
01187     
01188     use argument objects in conjunction with \ref ArgumentObjectFactories :
01189     \code
01190     namespace vigra {
01191         template <class SrcImageIterator, class SrcAccessor,
01192               class DestImageIterator, class DestAccessor>
01193         void recursiveFirstDerivativeX(
01194             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01195             pair<DestImageIterator, DestAccessor> dest, 
01196             double scale)
01197     }
01198     \endcode
01199     
01200     <b> Usage:</b>
01201     
01202     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
01203     Namespace: vigra
01204     
01205     \code
01206     vigra::FImage src(w,h), dest(w,h);    
01207     ...
01208     
01209     vigra::recursiveFirstDerivativeX(srcImageRange(src), destImage(dest), 3.0);
01210     
01211     \endcode
01212 
01213 */
01214 doxygen_overloaded_function(template <...> void recursiveFirstDerivativeX)
01215 
01216 template <class SrcImageIterator, class SrcAccessor,
01217           class DestImageIterator, class DestAccessor>
01218 void recursiveFirstDerivativeX(SrcImageIterator supperleft, 
01219                       SrcImageIterator slowerright, SrcAccessor as,
01220                       DestImageIterator dupperleft, DestAccessor ad, 
01221               double scale)
01222 {
01223     int w = slowerright.x - supperleft.x;
01224     int h = slowerright.y - supperleft.y;
01225     
01226     int y;
01227     
01228     for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
01229     {
01230         typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
01231         typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
01232 
01233         recursiveFirstDerivativeLine(rs, rs+w, as, 
01234                                      rd, ad, 
01235                                      scale);
01236     }
01237 }
01238             
01239 template <class SrcImageIterator, class SrcAccessor,
01240           class DestImageIterator, class DestAccessor>
01241 inline void recursiveFirstDerivativeX(
01242             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01243             pair<DestImageIterator, DestAccessor> dest, 
01244         double scale)
01245 {
01246     recursiveFirstDerivativeX(src.first, src.second, src.third,
01247                           dest. first, dest.second, scale);
01248 }
01249             
01250 /********************************************************/
01251 /*                                                      */
01252 /*              recursiveFirstDerivativeY               */
01253 /*                                                      */
01254 /********************************************************/
01255 
01256 /** \brief Recursively calculates the 1 dimensional first derivative in y 
01257     direction.
01258     
01259     It calls \ref recursiveFirstDerivativeLine() for every 
01260     column of the image. See \ref recursiveFirstDerivativeLine() for more 
01261     information about required interfaces and vigra_preconditions.
01262     
01263     <b> Declarations:</b>
01264     
01265     pass arguments explicitly:
01266     \code
01267     namespace vigra {
01268         template <class SrcImageIterator, class SrcAccessor,
01269               class DestImageIterator, class DestAccessor>
01270         void recursiveFirstDerivativeY(SrcImageIterator supperleft, 
01271                   SrcImageIterator slowerright, SrcAccessor as,
01272                   DestImageIterator dupperleft, DestAccessor ad, 
01273                   double scale)
01274     }
01275     \endcode
01276     
01277     
01278     use argument objects in conjunction with \ref ArgumentObjectFactories :
01279     \code
01280     namespace vigra {
01281         template <class SrcImageIterator, class SrcAccessor,
01282               class DestImageIterator, class DestAccessor>
01283         void recursiveFirstDerivativeY(
01284             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01285             pair<DestImageIterator, DestAccessor> dest, 
01286             double scale)
01287     }
01288     \endcode
01289     
01290     <b> Usage:</b>
01291     
01292     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
01293     Namespace: vigra
01294     
01295     \code
01296     vigra::FImage src(w,h), dest(w,h);    
01297     ...
01298     
01299     vigra::recursiveFirstDerivativeY(srcImageRange(src), destImage(dest), 3.0);
01300     
01301     \endcode
01302 
01303 */
01304 doxygen_overloaded_function(template <...> void recursiveFirstDerivativeY)
01305 
01306 template <class SrcImageIterator, class SrcAccessor,
01307           class DestImageIterator, class DestAccessor>
01308 void recursiveFirstDerivativeY(SrcImageIterator supperleft, 
01309                       SrcImageIterator slowerright, SrcAccessor as,
01310                       DestImageIterator dupperleft, DestAccessor ad, 
01311               double scale)
01312 {
01313     int w = slowerright.x - supperleft.x;
01314     int h = slowerright.y - supperleft.y;
01315     
01316     int x;
01317     
01318     for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
01319     {
01320         typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
01321         typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
01322 
01323         recursiveFirstDerivativeLine(cs, cs+h, as, 
01324                                      cd, ad, 
01325                                      scale);
01326     }
01327 }
01328             
01329 template <class SrcImageIterator, class SrcAccessor,
01330           class DestImageIterator, class DestAccessor>
01331 inline void recursiveFirstDerivativeY(
01332             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01333             pair<DestImageIterator, DestAccessor> dest, 
01334         double scale)
01335 {
01336     recursiveFirstDerivativeY(src.first, src.second, src.third,
01337                           dest. first, dest.second, scale);
01338 }
01339             
01340 /********************************************************/
01341 /*                                                      */
01342 /*             recursiveSecondDerivativeX               */
01343 /*                                                      */
01344 /********************************************************/
01345 
01346 /** \brief Recursively calculates the 1 dimensional second derivative in x 
01347     direction.
01348     
01349     It calls \ref recursiveSecondDerivativeLine() for every 
01350     row of the image. See \ref recursiveSecondDerivativeLine() for more 
01351     information about required interfaces and vigra_preconditions.
01352     
01353     <b> Declarations:</b>
01354     
01355     pass arguments explicitly:
01356     \code
01357     namespace vigra {
01358         template <class SrcImageIterator, class SrcAccessor,
01359               class DestImageIterator, class DestAccessor>
01360         void recursiveSecondDerivativeX(SrcImageIterator supperleft, 
01361                   SrcImageIterator slowerright, SrcAccessor as,
01362                   DestImageIterator dupperleft, DestAccessor ad, 
01363                   double scale)
01364     }
01365     \endcode
01366     
01367     
01368     use argument objects in conjunction with \ref ArgumentObjectFactories :
01369     \code
01370     namespace vigra {
01371         template <class SrcImageIterator, class SrcAccessor,
01372               class DestImageIterator, class DestAccessor>
01373         void recursiveSecondDerivativeX(
01374             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01375             pair<DestImageIterator, DestAccessor> dest, 
01376             double scale)
01377     }
01378     \endcode
01379     
01380     <b> Usage:</b>
01381     
01382     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
01383     Namespace: vigra
01384     
01385     \code
01386     vigra::FImage src(w,h), dest(w,h);    
01387     ...
01388     
01389     vigra::recursiveSecondDerivativeX(srcImageRange(src), destImage(dest), 3.0);
01390     
01391     \endcode
01392 
01393 */
01394 doxygen_overloaded_function(template <...> void recursiveSecondDerivativeX)
01395 
01396 template <class SrcImageIterator, class SrcAccessor,
01397           class DestImageIterator, class DestAccessor>
01398 void recursiveSecondDerivativeX(SrcImageIterator supperleft, 
01399                       SrcImageIterator slowerright, SrcAccessor as,
01400                       DestImageIterator dupperleft, DestAccessor ad, 
01401               double scale)
01402 {
01403     int w = slowerright.x - supperleft.x;
01404     int h = slowerright.y - supperleft.y;
01405     
01406     int y;
01407     
01408     for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
01409     {
01410         typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
01411         typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
01412 
01413         recursiveSecondDerivativeLine(rs, rs+w, as, 
01414                                       rd, ad, 
01415                                       scale);
01416     }
01417 }
01418             
01419 template <class SrcImageIterator, class SrcAccessor,
01420           class DestImageIterator, class DestAccessor>
01421 inline void recursiveSecondDerivativeX(
01422             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01423             pair<DestImageIterator, DestAccessor> dest, 
01424         double scale)
01425 {
01426     recursiveSecondDerivativeX(src.first, src.second, src.third,
01427                           dest. first, dest.second, scale);
01428 }
01429             
01430 /********************************************************/
01431 /*                                                      */
01432 /*             recursiveSecondDerivativeY               */
01433 /*                                                      */
01434 /********************************************************/
01435 
01436 /** \brief Recursively calculates the 1 dimensional second derivative in y 
01437     direction.
01438     
01439     It calls \ref recursiveSecondDerivativeLine() for every 
01440     column of the image. See \ref recursiveSecondDerivativeLine() for more 
01441     information about required interfaces and vigra_preconditions.
01442     
01443     <b> Declarations:</b>
01444     
01445     pass arguments explicitly:
01446     \code
01447     namespace vigra {
01448         template <class SrcImageIterator, class SrcAccessor,
01449               class DestImageIterator, class DestAccessor>
01450         void recursiveSecondDerivativeY(SrcImageIterator supperleft, 
01451                   SrcImageIterator slowerright, SrcAccessor as,
01452                   DestImageIterator dupperleft, DestAccessor ad, 
01453                   double scale)
01454     }
01455     \endcode
01456     
01457     
01458     use argument objects in conjunction with \ref ArgumentObjectFactories :
01459     \code
01460     namespace vigra {
01461         template <class SrcImageIterator, class SrcAccessor,
01462               class DestImageIterator, class DestAccessor>
01463         void recursiveSecondDerivativeY(
01464             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01465             pair<DestImageIterator, DestAccessor> dest, 
01466             double scale)
01467     }
01468     \endcode
01469     
01470     <b> Usage:</b>
01471     
01472     <b>\#include</b> <<a href="recursiveconvolution_8hxx-source.html">vigra/recursiveconvolution.hxx</a>><br>
01473     Namespace: vigra
01474     
01475     \code
01476     vigra::FImage src(w,h), dest(w,h);    
01477     ...
01478     
01479     vigra::recursiveSecondDerivativeY(srcImageRange(src), destImage(dest), 3.0);
01480     
01481     \endcode
01482 
01483 */
01484 doxygen_overloaded_function(template <...> void recursiveSecondDerivativeY)
01485 
01486 template <class SrcImageIterator, class SrcAccessor,
01487           class DestImageIterator, class DestAccessor>
01488 void recursiveSecondDerivativeY(SrcImageIterator supperleft, 
01489                       SrcImageIterator slowerright, SrcAccessor as,
01490                       DestImageIterator dupperleft, DestAccessor ad, 
01491               double scale)
01492 {
01493     int w = slowerright.x - supperleft.x;
01494     int h = slowerright.y - supperleft.y;
01495     
01496     int x;
01497     
01498     for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
01499     {
01500         typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
01501         typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
01502 
01503         recursiveSecondDerivativeLine(cs, cs+h, as, 
01504                                       cd, ad, 
01505                                       scale);
01506     }
01507 }
01508             
01509 template <class SrcImageIterator, class SrcAccessor,
01510           class DestImageIterator, class DestAccessor>
01511 inline void recursiveSecondDerivativeY(
01512             triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
01513             pair<DestImageIterator, DestAccessor> dest, 
01514         double scale)
01515 {
01516     recursiveSecondDerivativeY(src.first, src.second, src.third,
01517                           dest. first, dest.second, scale);
01518 }
01519             
01520 //@}
01521 
01522 } // namespace vigra
01523 
01524 #endif // VIGRA_RECURSIVECONVOLUTION_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)