[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
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) |
html generated using doxygen and Python
|