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