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

details vigra/recursiveconvolution.hxx VIGRA

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

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

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