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