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