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