[ 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_INSPECTIMAGE_HXX 00039 #define VIGRA_INSPECTIMAGE_HXX 00040 00041 #pragma warning (disable: 4350) 00042 00043 #include <vector> 00044 #include <algorithm> 00045 #include "utilities.hxx" 00046 #include "numerictraits.hxx" 00047 #include "iteratortraits.hxx" 00048 #include "functortraits.hxx" 00049 #include "rgbvalue.hxx" 00050 00051 namespace vigra { 00052 00053 /** \addtogroup InspectAlgo Algorithms to Inspect Images 00054 00055 Apply read-only functor to every pixel 00056 */ 00057 //@{ 00058 00059 /********************************************************/ 00060 /* */ 00061 /* inspectLine */ 00062 /* */ 00063 /********************************************************/ 00064 00065 template <class SrcIterator, class SrcAccessor, class Functor> 00066 void 00067 inspectLine(SrcIterator s, 00068 SrcIterator send, SrcAccessor src, 00069 Functor & f) 00070 { 00071 for(; s != send; ++s) 00072 f(src(s)); 00073 } 00074 00075 template <class SrcIterator, class SrcAccessor, 00076 class MaskIterator, class MaskAccessor, 00077 class Functor> 00078 void 00079 inspectLineIf(SrcIterator s, 00080 SrcIterator send, SrcAccessor src, 00081 MaskIterator m, MaskAccessor mask, 00082 Functor & f) 00083 { 00084 for(; s != send; ++s, ++m) 00085 if(mask(m)) 00086 f(src(s)); 00087 } 00088 00089 template <class SrcIterator1, class SrcAccessor1, 00090 class SrcIterator2, class SrcAccessor2, 00091 class Functor> 00092 void 00093 inspectTwoLines(SrcIterator1 s1, 00094 SrcIterator1 s1end, SrcAccessor1 src1, 00095 SrcIterator2 s2, SrcAccessor2 src2, 00096 Functor & f) 00097 { 00098 for(; s1 != s1end; ++s1, ++s2) 00099 f(src1(s1), src2(s2)); 00100 } 00101 00102 template <class SrcIterator1, class SrcAccessor1, 00103 class SrcIterator2, class SrcAccessor2, 00104 class MaskIterator, class MaskAccessor, 00105 class Functor> 00106 void 00107 inspectTwoLinesIf(SrcIterator1 s1, 00108 SrcIterator1 s1end, SrcAccessor1 src1, 00109 SrcIterator2 s2, SrcAccessor2 src2, 00110 MaskIterator m, MaskAccessor mask, 00111 Functor & f) 00112 { 00113 for(; s1 != s1end; ++s1, ++s2, ++m) 00114 if(mask(m)) 00115 f(src1(s1), src2(s2)); 00116 } 00117 00118 /********************************************************/ 00119 /* */ 00120 /* inspectImage */ 00121 /* */ 00122 /********************************************************/ 00123 00124 /** \brief Apply read-only functor to every pixel in the image. 00125 00126 This function can be used to collect statistics of the image etc. 00127 The results must be stored in the functor, which serves as a return 00128 value. 00129 The function uses an accessor to access the pixel data. 00130 00131 <b> Declarations:</b> 00132 00133 pass arguments explicitly: 00134 \code 00135 namespace vigra { 00136 template <class ImageIterator, class Accessor, class Functor> 00137 void 00138 inspectImage(ImageIterator upperleft, ImageIterator lowerright, 00139 Accessor a, Functor & f) 00140 } 00141 \endcode 00142 00143 use argument objects in conjunction with \ref ArgumentObjectFactories : 00144 \code 00145 namespace vigra { 00146 template <class ImageIterator, class Accessor, class Functor> 00147 void 00148 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img, 00149 Functor & f) 00150 } 00151 \endcode 00152 00153 <b> Usage:</b> 00154 00155 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 00156 Namespace: vigra 00157 00158 \code 00159 // init functor 00160 vigra::BImage img; 00161 00162 vigra::FindMinMax<vigra::BImage::PixelType> minmax; 00163 00164 vigra::inspectImage(srcImageRange(img), minmax); 00165 00166 cout << "Min: " << minmax.min << " Max: " << minmax.max; 00167 00168 \endcode 00169 00170 <b> Required Interface:</b> 00171 00172 \code 00173 ConstImageIterator upperleft, lowerright; 00174 ConstImageIterator::row_iterator ix = upperleft.rowIterator(); 00175 00176 Accessor accessor; 00177 Functor functor; 00178 00179 functor(accessor(ix)); // return not used 00180 \endcode 00181 00182 */ 00183 doxygen_overloaded_function(template <...> void inspectImage) 00184 00185 template <class ImageIterator, class Accessor, class Functor> 00186 void 00187 inspectImage(ImageIterator upperleft, ImageIterator lowerright, 00188 Accessor a, Functor & f) 00189 { 00190 int w = lowerright.x - upperleft.x; 00191 00192 for(; upperleft.y<lowerright.y; ++upperleft.y) 00193 { 00194 inspectLine(upperleft.rowIterator(), 00195 upperleft.rowIterator() + w, a, f); 00196 } 00197 } 00198 00199 template <class ImageIterator, class Accessor, class Functor> 00200 inline 00201 void 00202 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img, 00203 Functor & f) 00204 { 00205 inspectImage(img.first, img.second, img.third, f); 00206 } 00207 00208 namespace functor 00209 { 00210 template <class T> class UnaryAnalyser; 00211 } 00212 00213 template <class ImageIterator, class Accessor, class Functor> 00214 inline 00215 void 00216 inspectImage(ImageIterator upperleft, ImageIterator lowerright, 00217 Accessor a, functor::UnaryAnalyser<Functor> const & f) 00218 { 00219 inspectImage(upperleft, lowerright, a, 00220 const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00221 } 00222 00223 template <class ImageIterator, class Accessor, class Functor> 00224 inline 00225 void 00226 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img, 00227 functor::UnaryAnalyser<Functor> const & f) 00228 { 00229 inspectImage(img.first, img.second, img.third, 00230 const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00231 } 00232 00233 /********************************************************/ 00234 /* */ 00235 /* inspectImageIf */ 00236 /* */ 00237 /********************************************************/ 00238 00239 /** \brief Apply read-only functor to every pixel in the ROI. 00240 00241 This function can be used to collect statistics of the roi etc. 00242 The functor is called whenever the return value of the mask's 00243 accessor is not zero. 00244 The results must be stored in the functor, which serves as a return 00245 value. 00246 Accessors are used to access the pixel and mask data. 00247 00248 <b> Declarations:</b> 00249 00250 pass arguments explicitly: 00251 \code 00252 namespace vigra { 00253 template <class ImageIterator, class Accessor, 00254 class MaskImageIterator, class MaskAccessor, class Functor> 00255 void 00256 inspectImageIf(ImageIterator upperleft, ImageIterator lowerright, 00257 MaskImageIterator mask_upperleft, MaskAccessor ma, 00258 Functor & f) 00259 } 00260 \endcode 00261 00262 00263 use argument objects in conjunction with \ref ArgumentObjectFactories : 00264 \code 00265 namespace vigra { 00266 template <class ImageIterator, class Accessor, 00267 class MaskImageIterator, class MaskAccessor, class Functor> 00268 void 00269 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img, 00270 pair<MaskImageIterator, MaskAccessor> mask, 00271 Functor & f) 00272 } 00273 \endcode 00274 00275 <b> Usage:</b> 00276 00277 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 00278 Namespace: vigra 00279 00280 \code 00281 vigra::BImage img(100, 100); 00282 vigra::BImage mask(100, 100); 00283 00284 // init functor 00285 vigra::FindMinMax<vigra::BImage::PixelType> minmax(); 00286 00287 vigra::inspectImageIf(srcImageRange(img), 00288 maskImage(mask), minmax); 00289 00290 cout << "Min: " << minmax.min << " Max: " << minmax.max; 00291 00292 \endcode 00293 00294 <b> Required Interface:</b> 00295 00296 \code 00297 ConstImageIterator upperleft, lowerright; 00298 MaskImageIterator mask_upperleft; 00299 ConstImageIterator::row_iterator ix = upperleft.rowIterator(); 00300 MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator(); 00301 00302 Accessor accessor; 00303 MaskAccessor mask_accessor; 00304 00305 Functor functor; 00306 00307 if(mask_accessor(mx)) functor(accessor(ix)); 00308 \endcode 00309 00310 */ 00311 doxygen_overloaded_function(template <...> void inspectImageIf) 00312 00313 template <class ImageIterator, class Accessor, 00314 class MaskImageIterator, class MaskAccessor, class Functor> 00315 void 00316 inspectImageIf(ImageIterator upperleft, 00317 ImageIterator lowerright, Accessor a, 00318 MaskImageIterator mask_upperleft, MaskAccessor ma, 00319 Functor & f) 00320 { 00321 int w = lowerright.x - upperleft.x; 00322 00323 for(; upperleft.y<lowerright.y; ++upperleft.y, ++mask_upperleft.y) 00324 { 00325 inspectLineIf(upperleft.rowIterator(), 00326 upperleft.rowIterator() + w, a, 00327 mask_upperleft.rowIterator(), ma, f); 00328 } 00329 } 00330 00331 template <class ImageIterator, class Accessor, 00332 class MaskImageIterator, class MaskAccessor, class Functor> 00333 inline 00334 void 00335 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img, 00336 pair<MaskImageIterator, MaskAccessor> mask, 00337 Functor & f) 00338 { 00339 inspectImageIf(img.first, img.second, img.third, 00340 mask.first, mask.second, f); 00341 } 00342 00343 template <class ImageIterator, class Accessor, 00344 class MaskImageIterator, class MaskAccessor, class Functor> 00345 inline void 00346 inspectImageIf(ImageIterator upperleft, 00347 ImageIterator lowerright, Accessor a, 00348 MaskImageIterator mask_upperleft, MaskAccessor ma, 00349 functor::UnaryAnalyser<Functor> const & f) 00350 { 00351 inspectImageIf(upperleft, lowerright, a, 00352 mask_upperleft, ma, const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00353 } 00354 00355 template <class ImageIterator, class Accessor, 00356 class MaskImageIterator, class MaskAccessor, class Functor> 00357 inline void 00358 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img, 00359 pair<MaskImageIterator, MaskAccessor> mask, 00360 functor::UnaryAnalyser<Functor> const & f) 00361 { 00362 inspectImageIf(img.first, img.second, img.third, 00363 mask.first, mask.second, const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00364 } 00365 00366 /********************************************************/ 00367 /* */ 00368 /* inspectTwoImages */ 00369 /* */ 00370 /********************************************************/ 00371 00372 /** \brief Apply read-only functor to every pixel of both images. 00373 00374 This function can be used to collect statistics for each region of a 00375 labeled image, especially in conjunction with 00376 the \ref ArrayOfRegionStatistics functor. The results must be 00377 stored in the functor which serves as a return value. 00378 Accessors are used to access the pixel data. 00379 00380 <b> Declarations:</b> 00381 00382 pass arguments explicitly: 00383 \code 00384 namespace vigra { 00385 template <class ImageIterator1, class Accessor1, 00386 class ImageIterator2, class Accessor2, 00387 class Functor> 00388 void 00389 inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00390 ImageIterator2 upperleft2, Accessor2 a2, 00391 Functor & f) 00392 } 00393 \endcode 00394 00395 00396 use argument objects in conjunction with \ref ArgumentObjectFactories : 00397 \code 00398 namespace vigra { 00399 template <class ImageIterator1, class Accessor1, 00400 class ImageIterator2, class Accessor2, 00401 class Functor> 00402 void 00403 inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00404 pair<ImageIterator2, Accessor2> img2, 00405 Functor & f) 00406 } 00407 \endcode 00408 00409 <b> Usage:</b> 00410 00411 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 00412 Namespace: vigra 00413 00414 \code 00415 vigra::BImage image1; 00416 vigra::BImage image2; 00417 00418 SomeStatisticsFunctor stats(...); // init functor 00419 00420 vigra::inspectTwoImages(srcImageRange(image1), srcImage(image2), 00421 stats); 00422 00423 00424 \endcode 00425 00426 <b> Required Interface:</b> 00427 00428 \code 00429 ImageIterator1 upperleft1, lowerright1; 00430 ImageIterator2 upperleft2; 00431 ImageIterator1::row_iterator ix1 = upperleft1.rowIterator(); 00432 ImageIterator2::row_iterator ix2 = upperleft2.rowIterator(); 00433 00434 Accessor1 accessor1; 00435 Accessor2 accessor2; 00436 00437 Functor functor; 00438 functor(accessor1(ix1), accessor2(ix2)); // return not used 00439 \endcode 00440 00441 */ 00442 doxygen_overloaded_function(template <...> void inspectTwoImages) 00443 00444 template <class ImageIterator1, class Accessor1, 00445 class ImageIterator2, class Accessor2, 00446 class Functor> 00447 void 00448 inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00449 ImageIterator2 upperleft2, Accessor2 a2, 00450 Functor & f) 00451 { 00452 int w = lowerright1.x - upperleft1.x; 00453 00454 for(; upperleft1.y<lowerright1.y; ++upperleft1.y, ++upperleft2.y) 00455 { 00456 inspectTwoLines(upperleft1.rowIterator(), 00457 upperleft1.rowIterator() + w, a1, 00458 upperleft2.rowIterator(), a2, f); 00459 } 00460 } 00461 00462 template <class ImageIterator1, class Accessor1, 00463 class ImageIterator2, class Accessor2, 00464 class Functor> 00465 inline 00466 void 00467 inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00468 pair<ImageIterator2, Accessor2> img2, 00469 Functor & f) 00470 { 00471 inspectTwoImages(img1.first, img1.second, img1.third, 00472 img2.first, img2.second, f); 00473 } 00474 00475 template <class ImageIterator1, class Accessor1, 00476 class ImageIterator2, class Accessor2, 00477 class Functor> 00478 inline void 00479 inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00480 ImageIterator2 upperleft2, Accessor2 a2, 00481 functor::UnaryAnalyser<Functor> const & f) 00482 { 00483 inspectTwoImages(upperleft1, lowerright1, a1, 00484 upperleft2, a2, const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00485 } 00486 00487 template <class ImageIterator1, class Accessor1, 00488 class ImageIterator2, class Accessor2, 00489 class Functor> 00490 inline 00491 void 00492 inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00493 pair<ImageIterator2, Accessor2> img2, 00494 functor::UnaryAnalyser<Functor> const & f) 00495 { 00496 inspectTwoImages(img1.first, img1.second, img1.third, 00497 img2.first, img2.second, const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00498 } 00499 00500 /********************************************************/ 00501 /* */ 00502 /* inspectTwoImagesIf */ 00503 /* */ 00504 /********************************************************/ 00505 00506 /** \brief Apply read-only functor to those pixels of both images where 00507 the mask image is non-zero. 00508 00509 This function can be used to collect statistics for selected regions of a 00510 labeled image, especially in conjunction with 00511 the \ref ArrayOfRegionStatistics functor. The results must be 00512 stored in the functor which serves as a return value. 00513 Accessors are used to access the pixel data. 00514 00515 <b> Declarations:</b> 00516 00517 pass arguments explicitly: 00518 \code 00519 namespace vigra { 00520 template <class ImageIterator1, class Accessor1, 00521 class ImageIterator2, class Accessor2, 00522 class MaskImageIterator, class MaskAccessor, 00523 class Functor> 00524 void 00525 inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00526 ImageIterator2 upperleft2, Accessor2 a2, 00527 MaskImageIterator mupperleft, MaskAccessor mask, 00528 Functor & f) 00529 } 00530 \endcode 00531 00532 00533 use argument objects in conjunction with \ref ArgumentObjectFactories : 00534 \code 00535 namespace vigra { 00536 template <class ImageIterator1, class Accessor1, 00537 class ImageIterator2, class Accessor2, 00538 class MaskImageIterator, class MaskAccessor, 00539 class Functor> 00540 void 00541 inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00542 pair<ImageIterator2, Accessor2> img2, 00543 pair<MaskImageIterator, MaskAccessor> mimg, 00544 Functor & f) 00545 } 00546 \endcode 00547 00548 <b> Usage:</b> 00549 00550 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 00551 Namespace: vigra 00552 00553 \code 00554 vigra::BImage image1; 00555 vigra::BImage image2; 00556 vigra::BImage maskimage; 00557 00558 SomeStatisticsFunctor stats(...); // init functor 00559 00560 vigra::inspectTwoImagesIf(srcImageRange(image1), srcImage(image2), 00561 srcImage(maskimage), region_stats); 00562 00563 \endcode 00564 00565 <b> Required Interface:</b> 00566 00567 \code 00568 ImageIterator1 upperleft1, lowerright1; 00569 ImageIterator2 upperleft2; 00570 MaskImageIterator upperleftm; 00571 ImageIterator1::row_iterator ix1 = upperleft1.rowIterator(); 00572 ImageIterator2::row_iterator ix2 = upperleft2.rowIterator(); 00573 MaskImageIterator::row_iterator mx = mupperleft.rowIterator(); 00574 00575 Accessor1 accessor1; 00576 Accessor2 accessor2; 00577 MaskAccessor mask; 00578 00579 Functor functor; 00580 if(mask(mx)) 00581 functor(accessor1(ix1), accessor2(ix2)); 00582 \endcode 00583 00584 */ 00585 doxygen_overloaded_function(template <...> void inspectTwoImagesIf) 00586 00587 template <class ImageIterator1, class Accessor1, 00588 class ImageIterator2, class Accessor2, 00589 class MaskImageIterator, class MaskAccessor, 00590 class Functor> 00591 void 00592 inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00593 ImageIterator2 upperleft2, Accessor2 a2, 00594 MaskImageIterator mupperleft, MaskAccessor mask, 00595 Functor & f) 00596 { 00597 int w = lowerright1.x - upperleft1.x; 00598 00599 for(; upperleft1.y<lowerright1.y; ++upperleft1.y, ++upperleft2.y, ++mupperleft.y) 00600 { 00601 inspectTwoLinesIf(upperleft1.rowIterator(), 00602 upperleft1.rowIterator() + w, a1, 00603 upperleft2.rowIterator(), a2, 00604 mupperleft.rowIterator(), mask, f); 00605 } 00606 } 00607 00608 template <class ImageIterator1, class Accessor1, 00609 class ImageIterator2, class Accessor2, 00610 class MaskImageIterator, class MaskAccessor, 00611 class Functor> 00612 inline 00613 void 00614 inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00615 pair<ImageIterator2, Accessor2> img2, 00616 pair<MaskImageIterator, MaskAccessor> m, 00617 Functor & f) 00618 { 00619 inspectTwoImagesIf(img1.first, img1.second, img1.third, 00620 img2.first, img2.second, 00621 m.first, m.second, 00622 f); 00623 } 00624 00625 template <class ImageIterator1, class Accessor1, 00626 class ImageIterator2, class Accessor2, 00627 class MaskImageIterator, class MaskAccessor, 00628 class Functor> 00629 inline void 00630 inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00631 ImageIterator2 upperleft2, Accessor2 a2, 00632 MaskImageIterator mupperleft, MaskAccessor mask, 00633 functor::UnaryAnalyser<Functor> const & f) 00634 { 00635 inspectTwoImagesIf(upperleft1, lowerright1, a1, 00636 upperleft2, a2, 00637 mupperleft, mask, 00638 const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00639 } 00640 00641 template <class ImageIterator1, class Accessor1, 00642 class ImageIterator2, class Accessor2, 00643 class MaskImageIterator, class MaskAccessor, 00644 class Functor> 00645 inline 00646 void 00647 inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00648 pair<ImageIterator2, Accessor2> img2, 00649 pair<MaskImageIterator, MaskAccessor> m, 00650 functor::UnaryAnalyser<Functor> const & f) 00651 { 00652 inspectTwoImagesIf(img1.first, img1.second, img1.third, 00653 img2.first, img2.second, 00654 m.first, m.second, 00655 const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00656 } 00657 00658 //@} 00659 00660 /** \addtogroup InspectFunctor Functors To Inspect Images 00661 Functors which report image statistics 00662 */ 00663 //@{ 00664 00665 /********************************************************/ 00666 /* */ 00667 /* FindMinMax */ 00668 /* */ 00669 /********************************************************/ 00670 00671 /** \brief Find the minimum and maximum pixel value in an image or ROI. 00672 00673 In addition the size of the ROI is calculated. 00674 These functors can also be used in conjunction with 00675 \ref ArrayOfRegionStatistics to find the extremes of all regions in 00676 a labeled image. 00677 00678 <b> Traits defined:</b> 00679 00680 <tt>FunctorTraits::isUnaryAnalyser</tt> is true (<tt>VigraTrueType</tt>) 00681 00682 <b> Usage:</b> 00683 00684 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 00685 Namespace: vigra 00686 00687 \code 00688 vigra::BImage img; 00689 00690 vigra::FindMinMax<vigra::BImage::PixelType> minmax; // init functor 00691 00692 vigra::inspectImage(srcImageRange(img), minmax); 00693 00694 cout << "Min: " << minmax.min << " Max: " << minmax.max; 00695 00696 \endcode 00697 00698 <b> Required Interface:</b> 00699 00700 \code 00701 VALUETYPE v1, v2(v1); 00702 00703 v1 < v2; 00704 v1 = v2; 00705 \endcode 00706 00707 */ 00708 template <class VALUETYPE> 00709 class FindMinMax 00710 { 00711 public: 00712 00713 /** the functor's argument type 00714 */ 00715 typedef VALUETYPE argument_type; 00716 00717 /** the functor's result type 00718 */ 00719 typedef VALUETYPE result_type; 00720 00721 /** \deprecated use argument_type 00722 */ 00723 typedef VALUETYPE value_type; 00724 00725 /** init min and max 00726 */ 00727 FindMinMax() 00728 : min( NumericTraits<value_type>::max() ), 00729 max( NumericTraits<value_type>::min() ), 00730 count(0) 00731 {} 00732 00733 /** (re-)init functor (clear min, max) 00734 */ 00735 void reset() 00736 { 00737 count = 0; 00738 } 00739 00740 /** update min and max 00741 */ 00742 void operator()(argument_type const & v) 00743 { 00744 if(count) 00745 { 00746 if(v < min) min = v; 00747 if(max < v) max = v; 00748 } 00749 else 00750 { 00751 min = v; 00752 max = v; 00753 } 00754 ++count; 00755 } 00756 00757 /** update min and max with components of RGBValue<VALUETYPE> 00758 */ 00759 void operator()(RGBValue<VALUETYPE> const & v) 00760 { 00761 operator()(v.red()); 00762 operator()(v.green()); 00763 operator()(v.blue()); 00764 } 00765 00766 /** merge two statistics 00767 */ 00768 void operator()(FindMinMax const & v) 00769 { 00770 if(v.count) 00771 { 00772 if(count) 00773 { 00774 if(v.min < min) min = v.min; 00775 if((this->max) < v.max) max = v.max; 00776 } 00777 else 00778 { 00779 min = v.min; 00780 max = v.max; 00781 } 00782 } 00783 count += v.count; 00784 } 00785 00786 /** the current min 00787 */ 00788 VALUETYPE min; 00789 00790 /** the current max 00791 */ 00792 VALUETYPE max; 00793 00794 /** the number of values processed so far 00795 */ 00796 unsigned int count; 00797 00798 }; 00799 00800 template <class VALUETYPE> 00801 class FunctorTraits<FindMinMax<VALUETYPE> > 00802 : public FunctorTraitsBase<FindMinMax<VALUETYPE> > 00803 { 00804 public: 00805 typedef VigraTrueType isUnaryAnalyser; 00806 }; 00807 00808 /********************************************************/ 00809 /* */ 00810 /* FindAverage */ 00811 /* */ 00812 /********************************************************/ 00813 00814 /** \brief Find the average pixel value in an image or ROI. 00815 00816 In addition the size of the ROI is calculated. 00817 This Functor can also be used in conjunction with 00818 \ref ArrayOfRegionStatistics to find the average of all regions in 00819 a labeled image. 00820 00821 <b> Traits defined:</b> 00822 00823 <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt> 00824 are true (<tt>VigraTrueType</tt>) 00825 00826 <b> Usage:</b> 00827 00828 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 00829 Namespace: vigra 00830 00831 \code 00832 vigra::BImage img; 00833 00834 vigra::FindAverage<vigra::BImage::PixelType> average; // init functor 00835 00836 vigra::inspectImage(srcImageRange(img), average); 00837 00838 cout << "Average: " << average(); 00839 00840 \endcode 00841 00842 <b> Required Interface:</b> 00843 00844 \code 00845 VALUETYPE v1, v2(v1); 00846 double d; 00847 00848 v1 += v2; 00849 v1 / d; 00850 \endcode 00851 00852 */ 00853 template <class VALUETYPE> 00854 class FindAverage 00855 { 00856 public: 00857 00858 /** the functor's argument type 00859 */ 00860 typedef VALUETYPE argument_type; 00861 00862 /** the functor's first argument type (for calls with a weight) 00863 */ 00864 typedef VALUETYPE first_argument_type; 00865 00866 /** the functor's second argument type (for calls with a weight) 00867 */ 00868 typedef double second_argument_type; 00869 00870 /** the functor's result type 00871 */ 00872 typedef typename NumericTraits<VALUETYPE>::RealPromote result_type; 00873 00874 /** \deprecated use argument_type and result_type 00875 */ 00876 typedef typename NumericTraits<VALUETYPE>::RealPromote value_type; 00877 00878 /** init average 00879 */ 00880 FindAverage() 00881 : sum_(NumericTraits<result_type>::zero()), count_(0) 00882 {} 00883 00884 /** (re-)init average 00885 */ 00886 void reset() 00887 { 00888 count_ = 0; 00889 sum_ = NumericTraits<result_type>::zero(); 00890 } 00891 00892 /** update average 00893 */ 00894 void operator()(argument_type const & v) 00895 { 00896 sum_ += v; 00897 ++count_; 00898 } 00899 00900 /** update average, using weighted input. 00901 * <tt>stats(value, 1.0)</tt> is equivalent to the unweighted 00902 * call <tt>stats(value)</tt>, and <tt>stats(value, 2.0)</tt> 00903 * is equivalent to two unweighted calls. 00904 */ 00905 void operator()(first_argument_type const & v, second_argument_type weight) 00906 { 00907 sum_ += v * weight; 00908 count_ += weight; 00909 } 00910 00911 /** merge two statistics 00912 */ 00913 void operator()(FindAverage const & v) 00914 { 00915 sum_ += v.sum_; 00916 count_ += v.count_; 00917 } 00918 00919 /** return number of values (sum of weights) seen so far 00920 */ 00921 double count() const 00922 { 00923 return count_; 00924 } 00925 00926 /** return current average 00927 */ 00928 result_type average() const 00929 { 00930 return sum_ / (double)count_; 00931 } 00932 00933 /** return current average 00934 */ 00935 result_type operator()() const 00936 { 00937 return sum_ / (double)count_; 00938 } 00939 00940 result_type sum_; 00941 double count_; 00942 }; 00943 00944 template <class VALUETYPE> 00945 class FunctorTraits<FindAverage<VALUETYPE> > 00946 : public FunctorTraitsBase<FindAverage<VALUETYPE> > 00947 { 00948 public: 00949 typedef VigraTrueType isInitializer; 00950 typedef VigraTrueType isUnaryAnalyser; 00951 }; 00952 00953 /********************************************************/ 00954 /* */ 00955 /* FindAverageAndVariance */ 00956 /* */ 00957 /********************************************************/ 00958 00959 /** \brief Find the average pixel value and its variance in an image or ROI. 00960 00961 This Functor uses West's algorithm to accumulate highly accurate values for 00962 the mean and the sum of squared differences of all values seen so far (the 00963 naive incremental algorithm for the computation of the sum of squares 00964 produces large round-off errors when the mean is much larger than the 00965 standard deviation of the data.) This Functor can also be used in 00966 conjunction with \ref ArrayOfRegionStatistics to find the statistics of all 00967 regions in a labeled image. 00968 00969 <b> Traits defined:</b> 00970 00971 <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt> 00972 are true (<tt>VigraTrueType</tt>) 00973 00974 <b> Usage:</b> 00975 00976 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 00977 Namespace: vigra 00978 00979 \code 00980 vigra::BImage img; 00981 00982 vigra::FindAverageAndVariance<vigra::BImage::PixelType> averageAndVariance; // init functor 00983 00984 vigra::inspectImage(srcImageRange(img), averageAndVariance); 00985 00986 cout << "Average: " << averageAndVariance.average() << "\n"; 00987 cout << "Standard deviation: " << sqrt(averageAndVariance.variance()) << "\n"; 00988 00989 \endcode 00990 00991 <b> Required Interface:</b> 00992 00993 \code 00994 VALUETYPE v1, v2(v1); 00995 double d; 00996 00997 v1 += v2; 00998 v1 + v2; 00999 v1 - v2; 01000 v1 * v2; 01001 v1 / d; 01002 d * v1; 01003 \endcode 01004 01005 */ 01006 template <class VALUETYPE> 01007 class FindAverageAndVariance 01008 { 01009 public: 01010 01011 /** the functor's argument type 01012 */ 01013 typedef VALUETYPE argument_type; 01014 01015 /** the functor's first argument type (for calls with a weight) 01016 */ 01017 typedef VALUETYPE first_argument_type; 01018 01019 /** the functor's second argument type (for calls with a weight) 01020 */ 01021 typedef double second_argument_type; 01022 01023 /** the functor's result type 01024 */ 01025 typedef typename NumericTraits<VALUETYPE>::RealPromote result_type; 01026 01027 /** \deprecated use argument_type and result_type 01028 */ 01029 typedef typename NumericTraits<VALUETYPE>::RealPromote value_type; 01030 01031 /** init average 01032 */ 01033 FindAverageAndVariance() 01034 : mean_(NumericTraits<result_type>::zero()), 01035 sumOfSquaredDifferences_(NumericTraits<result_type>::zero()), 01036 count_(0.0) 01037 {} 01038 01039 /** (re-)init average and variance 01040 */ 01041 void reset() 01042 { 01043 count_ = 0.0; 01044 mean_ = NumericTraits<result_type>::zero(); 01045 sumOfSquaredDifferences_ = NumericTraits<result_type>::zero(); 01046 } 01047 01048 /** update average and variance 01049 */ 01050 void operator()(argument_type const & v) 01051 { 01052 ++count_; 01053 result_type t1 = v - mean_; 01054 result_type t2 = t1 / count_; 01055 mean_ += t2; 01056 sumOfSquaredDifferences_ += (count_-1.0)*t1*t2; 01057 } 01058 01059 /** update average and variance, using weighted input. 01060 * <tt>stats(value, 1.0)</tt> is equivalent to the unweighted 01061 * call <tt>stats(value)</tt>, and <tt>stats(value, 2.0)</tt> 01062 * is equivalent to two unweighted calls. 01063 */ 01064 void operator()(first_argument_type const & v, second_argument_type weight) 01065 { 01066 count_ += weight; 01067 result_type t1 = v - mean_; 01068 result_type t2 = t1 * weight / count_; 01069 mean_ += t2; 01070 01071 //sumOfSquaredDifferences_ += (count_ - weight)*t1*t2; 01072 01073 if(count_ > weight) 01074 sumOfSquaredDifferences_ += 01075 (t1 * t1 * weight / count_) * (count_ - weight ); 01076 } 01077 01078 /** merge two statistics 01079 */ 01080 void operator()(FindAverageAndVariance const & v) 01081 { 01082 double newCount = count_ + v.count_; 01083 sumOfSquaredDifferences_ += v.sumOfSquaredDifferences_ + 01084 count_ / newCount * v.count_ * (mean_ - v.mean_) * (mean_ - v.mean_); 01085 mean_ = (count_ * mean_ + v.count_ * v.mean_) / newCount; 01086 count_ += v.count_; 01087 } 01088 01089 /** return number of values (sum of weights) seen so far 01090 */ 01091 unsigned int count() const 01092 { 01093 return (unsigned int)count_; 01094 } 01095 01096 /** return current average 01097 */ 01098 result_type average() const 01099 { 01100 return mean_; 01101 } 01102 01103 /** return current variance. 01104 If <tt>unbiased = true</tt>, the sum of squared differences 01105 is divided by <tt>count()-1</tt> instead of just <tt>count()</tt>. 01106 */ 01107 result_type variance(bool unbiased = false) const 01108 { 01109 return unbiased 01110 ? sumOfSquaredDifferences_ / (count_ - 1.0) 01111 : sumOfSquaredDifferences_ / count_; 01112 } 01113 01114 /** return current variance. calls <tt>variance()</tt>. 01115 */ 01116 result_type operator()() const 01117 { 01118 return variance(); 01119 } 01120 01121 result_type mean_, sumOfSquaredDifferences_; 01122 double count_; 01123 }; 01124 01125 template <class VALUETYPE> 01126 class FunctorTraits<FindAverageAndVariance<VALUETYPE> > 01127 : public FunctorTraitsBase<FindAverageAndVariance<VALUETYPE> > 01128 { 01129 public: 01130 typedef VigraTrueType isInitializer; 01131 typedef VigraTrueType isUnaryAnalyser; 01132 }; 01133 01134 /********************************************************/ 01135 /* */ 01136 /* FindROISize */ 01137 /* */ 01138 /********************************************************/ 01139 01140 /** \brief Calculate the size of an ROI in an image. 01141 01142 This Functor is often used in conjunction with 01143 \ref ArrayOfRegionStatistics to find the sizes of all regions in 01144 a labeled image. 01145 01146 <b> Traits defined:</b> 01147 01148 <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt> 01149 are true (<tt>VigraTrueType</tt>) 01150 01151 <b> Usage:</b> 01152 01153 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 01154 Namespace: vigra 01155 01156 \code 01157 vigra::BImage img, mask; 01158 01159 vigra::FindROISize<vigra::BImage::PixelType> roisize; // init functor 01160 01161 vigra::inspectImageIf(srcImageRange(img), srcImage(mask), roisize); 01162 01163 cout << "Size of ROI: " << roisize.count; 01164 01165 \endcode 01166 01167 */ 01168 template <class VALUETYPE> 01169 class FindROISize 01170 { 01171 public: 01172 01173 /** the functor's argument type 01174 */ 01175 typedef VALUETYPE argument_type; 01176 01177 /** the functor's result type 01178 */ 01179 typedef unsigned int result_type; 01180 01181 /** \deprecated use argument_type and result_type 01182 */ 01183 typedef VALUETYPE value_type; 01184 01185 /** init counter to 0 01186 */ 01187 FindROISize() 01188 : count(0) 01189 {} 01190 01191 /** (re-)init ROI size with 0 01192 */ 01193 void reset() 01194 { 01195 count = 0; 01196 } 01197 01198 /** update counter 01199 */ 01200 void operator()(argument_type const &) 01201 { 01202 ++count; 01203 } 01204 01205 /** return current size 01206 */ 01207 result_type operator()() const 01208 { 01209 return count; 01210 } 01211 01212 /** return current size 01213 */ 01214 result_type size() const 01215 { 01216 return count; 01217 } 01218 01219 /** merge two statistics 01220 */ 01221 void operator()(FindROISize const & o) 01222 { 01223 count += o.count; 01224 } 01225 01226 /** the current counter 01227 */ 01228 result_type count; 01229 01230 }; 01231 01232 template <class VALUETYPE> 01233 class FunctorTraits<FindROISize<VALUETYPE> > 01234 : public FunctorTraitsBase<FindROISize<VALUETYPE> > 01235 { 01236 public: 01237 typedef VigraTrueType isInitializer; 01238 typedef VigraTrueType isUnaryAnalyser; 01239 }; 01240 01241 /********************************************************/ 01242 /* */ 01243 /* FindBoundingRectangle */ 01244 /* */ 01245 /********************************************************/ 01246 01247 /** \brief Calculate the bounding rectangle of an ROI in an image. 01248 01249 As always in VIGRA, <TT>roiRect.lowerRight</TT> is <em> just outside the rectangle</em>. 01250 That is, the last pixel actually in the rectangle is <TT>roiRect.lowerRight - Diff2D(1,1)</TT>. 01251 This Functor is often used in conjunction with 01252 \ref ArrayOfRegionStatistics to find the bounding rectangles 01253 of all regions in a labeled image. 01254 01255 <b> Traits defined:</b> 01256 01257 <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt> 01258 are true (<tt>VigraTrueType</tt>) 01259 01260 <b> Usage:</b> 01261 01262 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 01263 Namespace: vigra 01264 01265 \code 01266 vigra::BImage img, mask; 01267 ... 01268 01269 vigra::FindBoundingRectangle roiRect; // init functor 01270 01271 // Diff2D is used as the iterator for the source image. This 01272 // simulates an image where each pixel value equals that pixel's 01273 // coordinates. Tha image 'mask' determines the ROI. 01274 vigra::inspectImageIf(srcIterRange(Diff2D(0,0), img.size()), 01275 srcImage(mask), roiRect); 01276 01277 cout << "Upper left of ROI: " << 01278 roiRect.upperLeft.x << ", " << roiRect.upperLeft.y << endl; 01279 cout << "Lower right of ROI: " << 01280 roiRect.lowerRight.x << ", " << roiRect.lowerRight.y << endl; 01281 01282 \endcode 01283 01284 */ 01285 class FindBoundingRectangle 01286 { 01287 public: 01288 01289 /** the functor's argument type 01290 */ 01291 typedef Diff2D argument_type; 01292 01293 /** the functors result type 01294 */ 01295 typedef Rect2D result_type; 01296 01297 /** \deprecated use argument_type 01298 */ 01299 typedef Diff2D value_type; 01300 01301 /** Upper left of the region as seen so far 01302 */ 01303 Point2D upperLeft; 01304 01305 /** Lower right of the region as seen so far 01306 */ 01307 Point2D lowerRight; 01308 01309 /** are the functors contents valid ? 01310 */ 01311 bool valid; 01312 01313 /** init rectangle to invalid values 01314 */ 01315 FindBoundingRectangle() 01316 : valid(false) 01317 {} 01318 01319 /** (re-)init functor to find other bounds 01320 */ 01321 void reset() 01322 { 01323 valid = false; 01324 } 01325 01326 /** update rectangle by including the coordinate coord 01327 */ 01328 void operator()(argument_type const & coord) 01329 { 01330 if(!valid) 01331 { 01332 upperLeft = Point2D(coord); 01333 lowerRight = Point2D(coord + Diff2D(1,1)); 01334 valid = true; 01335 } 01336 else 01337 { 01338 upperLeft.x = std::min(upperLeft.x, coord.x); 01339 upperLeft.y = std::min(upperLeft.y, coord.y); 01340 lowerRight.x = std::max(lowerRight.x, coord.x + 1); 01341 lowerRight.y = std::max(lowerRight.y, coord.y + 1); 01342 } 01343 } 01344 01345 /** update rectangle by merging it with another rectangle 01346 */ 01347 void operator()(FindBoundingRectangle const & otherRegion) 01348 { 01349 if(!valid) 01350 { 01351 upperLeft = otherRegion.upperLeft; 01352 lowerRight = otherRegion.lowerRight; 01353 valid = otherRegion.valid; 01354 } 01355 else if(otherRegion.valid) 01356 { 01357 upperLeft.x = std::min(upperLeft.x, otherRegion.upperLeft.x); 01358 upperLeft.y = std::min(upperLeft.y, otherRegion.upperLeft.y); 01359 lowerRight.x = std::max(lowerRight.x, otherRegion.lowerRight.x); 01360 lowerRight.y = std::max(lowerRight.y, otherRegion.lowerRight.y); 01361 } 01362 } 01363 01364 /** Get size of current rectangle. 01365 */ 01366 Size2D size() const 01367 { 01368 return lowerRight - upperLeft; 01369 } 01370 01371 /** Get current rectangle. <TT>result_type::first</TT> is the upper 01372 left corner of the rectangle, <TT>result_type::second</TT> 01373 the lower right. 01374 */ 01375 result_type operator()() const 01376 { 01377 return result_type(upperLeft, lowerRight); 01378 } 01379 }; 01380 01381 template <> 01382 class FunctorTraits<FindBoundingRectangle> 01383 : public FunctorTraitsBase<FindBoundingRectangle> 01384 { 01385 public: 01386 typedef VigraTrueType isInitializer; 01387 typedef VigraTrueType isUnaryAnalyser; 01388 }; 01389 01390 /********************************************************/ 01391 /* */ 01392 /* LastValueFunctor */ 01393 /* */ 01394 /********************************************************/ 01395 01396 /** \brief Stores and returns the last value it has seen. 01397 01398 This Functor is best used in conjunction with 01399 \ref ArrayOfRegionStatistics to realize a look-up table. 01400 01401 <b> Traits defined:</b> 01402 01403 <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt> 01404 are true (<tt>VigraTrueType</tt>) 01405 01406 <b> Usage:</b> 01407 01408 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 01409 Namespace: vigra 01410 01411 \code 01412 vigra::BImage img; 01413 01414 vigra::ArrayOfRegionStatistics<LastValueFunctor<unsigned char> > lut(255); 01415 01416 for(int i=0; i<256; ++i) 01417 { 01418 lut[i] = ...; // init look-up table 01419 } 01420 01421 vigra::transformImage(srcImageRange(img), destImage(img), lut); 01422 01423 \endcode 01424 01425 */ 01426 template <class VALUETYPE> 01427 class LastValueFunctor 01428 { 01429 public: 01430 01431 /** the functor's argument type 01432 */ 01433 typedef VALUETYPE argument_type; 01434 01435 /** the functor's result type 01436 */ 01437 typedef VALUETYPE result_type; 01438 01439 /** \deprecated use argument_type and result_type 01440 */ 01441 typedef VALUETYPE value_type; 01442 01443 /** default construction of value (i.e. builtin types will be set to zero) 01444 */ 01445 LastValueFunctor(argument_type const &initial = argument_type()) 01446 : value(initial) 01447 {} 01448 01449 /** replace value 01450 */ 01451 void operator=(argument_type const & v) { value = v; } 01452 01453 /** reset to initial value (the same as after default construction) 01454 */ 01455 void reset() { value = VALUETYPE(); } 01456 01457 /** replace value 01458 */ 01459 void operator()(argument_type const & v) { value = v; } 01460 01461 /** return current value 01462 */ 01463 result_type const & operator()() const { return value; } 01464 01465 /** the current value 01466 */ 01467 VALUETYPE value; 01468 01469 }; 01470 01471 template <class VALUETYPE> 01472 class FunctorTraits<LastValueFunctor<VALUETYPE> > 01473 : public FunctorTraitsBase<LastValueFunctor<VALUETYPE> > 01474 { 01475 public: 01476 typedef VigraTrueType isInitializer; 01477 typedef VigraTrueType isUnaryAnalyser; 01478 }; 01479 01480 /********************************************************/ 01481 /* */ 01482 /* ReduceFunctor */ 01483 /* */ 01484 /********************************************************/ 01485 01486 /** \brief Apply a functor to reduce the dimensionality of an array. 01487 01488 This functor can be used to emulate the <tt>reduce</tt> standard function of 01489 functional programming using <tt>std::for_each()</tt> or <tt>inspectImage()</tt> 01490 and similar functions. This functor is initialized with a functor encoding 01491 the expression to be applied, and an accumulator storing the current state 01492 of the reduction. For each element of the array, the embedded functor is called 01493 with the accumulator and the current element(s) of the array. The result 01494 of the reduction is available by calling <tt>reduceFunctor()</tt>. 01495 01496 <b> Traits defined:</b> 01497 01498 <tt>FunctorTraits::isUnaryAnalyser</tt>, <tt>FunctorTraits::isBinaryAnalyser</tt> 01499 and <tt>FunctorTraits::isInitializer</tt> 01500 are true (<tt>VigraTrueType</tt>) 01501 01502 <b> Usage:</b> 01503 01504 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 01505 Namespace: vigra 01506 01507 \code 01508 vigra::BImage img; 01509 ... // fill the image 01510 01511 // create a functor to sum the elements of the image 01512 vigra::ReduceFunctor<std::plus<int>, int> sumElements(std::plus<int>, 0); 01513 01514 vigra::inspectImage(srcImageRange(img), sumElements); 01515 01516 cout << "The sum of the elements " << sumElements() << endl; 01517 01518 \endcode 01519 01520 <b> Required Interface:</b> 01521 01522 \code 01523 FUNCTOR f; 01524 VALUETYPE accumulator, current1, current2; 01525 01526 f(accumulator, current1); // for inspectImage() 01527 f(accumulator, current1, current2); // for inspectTwoImages() 01528 \endcode 01529 */ 01530 template <class FUNCTOR, class VALUETYPE> 01531 class ReduceFunctor 01532 { 01533 FUNCTOR f_; 01534 VALUETYPE start_, accumulator_; 01535 public: 01536 01537 /** the functor's argument type 01538 when used as a unary inspector. 01539 (This is not strictly correct since the argument type 01540 is actuall a template parameter.) 01541 */ 01542 typedef VALUETYPE argument_type; 01543 01544 /** the functor's first argument type 01545 when used as a binary inspector. 01546 (This is not strictly correct since the argument type 01547 is actuall a template parameter.) 01548 */ 01549 typedef VALUETYPE first_argument_type; 01550 01551 /** the functor's second argument type 01552 when used as a binary inspector. 01553 (This is not strictly correct since the argument type 01554 is actuall a template parameter.) 01555 */ 01556 typedef VALUETYPE second_argument_type; 01557 01558 /** the functor's result type 01559 */ 01560 typedef VALUETYPE result_type; 01561 01562 /** create with the given functor and initial value \a initial 01563 for the accumulator. 01564 */ 01565 ReduceFunctor(FUNCTOR const & f, VALUETYPE const & initial) 01566 : f_(f), 01567 start_(initial), 01568 accumulator_(initial) 01569 {} 01570 01571 /** Reset accumulator to the initial value. 01572 */ 01573 void reset() 01574 { accumulator_ = start_; } 01575 01576 /** Use binary functor to connect given value with the accumulator. 01577 The accumulator is used as the first argument, the value \a v 01578 as the second. 01579 */ 01580 template <class T> 01581 void operator()(T const & v) 01582 { 01583 accumulator_ = f_(accumulator_, v); 01584 } 01585 01586 /** Use ternary functor to connect given values with accumulator. 01587 The accumulator is used as the first argument, the values \a v1 01588 ans \a v2 as the second and third. 01589 */ 01590 template <class T1, class T2> 01591 void operator()(T1 const & v1, T2 const & v2) 01592 { 01593 accumulator_ = f_(accumulator_, v1, v2); 01594 } 01595 01596 /** return current value 01597 */ 01598 result_type const & operator()() const 01599 { return accumulator_; } 01600 }; 01601 01602 template <class FUNCTOR, class VALUETYPE> 01603 ReduceFunctor<FUNCTOR, VALUETYPE> 01604 reduceFunctor(FUNCTOR const & f, VALUETYPE const & initial) 01605 { 01606 return ReduceFunctor<FUNCTOR, VALUETYPE>(f, initial); 01607 } 01608 01609 template <class FUNCTOR, class VALUETYPE> 01610 class FunctorTraits<ReduceFunctor<FUNCTOR, VALUETYPE> > 01611 : public FunctorTraitsBase<ReduceFunctor<FUNCTOR, VALUETYPE> > 01612 { 01613 public: 01614 typedef VigraTrueType isInitializer; 01615 typedef VigraTrueType isUnaryAnalyser; 01616 typedef VigraTrueType isBinaryAnalyser; 01617 }; 01618 01619 /********************************************************/ 01620 /* */ 01621 /* ArrayOfRegionStatistics */ 01622 /* */ 01623 /********************************************************/ 01624 01625 /** \brief Calculate statistics for all regions of a labeled image. 01626 01627 This Functor encapsulates an array of statistics functors, one 01628 for each label, and selects the one to be updated according to the 01629 pixel's label. 01630 01631 <b> Traits defined:</b> 01632 01633 <tt>FunctorTraits::isBinaryAnalyser</tt> and <tt>FunctorTraits::isUnaryFunctor</tt> 01634 are true (<tt>VigraTrueType</tt>) 01635 01636 <b> Usage:</b> 01637 01638 <b>\#include</b> <<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>><br> 01639 Namespace: vigra 01640 01641 \code 01642 vigra::BImage img; 01643 vigra::IImage labels; 01644 int max_label; 01645 ... 01646 01647 // init functor as an array of 'max_label' FindMinMax-Functors 01648 vigra::ArrayOfRegionStatistics<vigra::FindMinMax<vigra::BImage::PixelType> > 01649 minmax(max_label); 01650 01651 vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), minmax); 01652 01653 for(int i=0; i<= max_label; ++i) 01654 { 01655 cout << "Max gray lavel of region " << i << ": " 01656 << minmax.region[i].max << endl; 01657 } 01658 01659 // init functor as an array of 'max_label' FindAverage-Functors 01660 vigra::ArrayOfRegionStatistics<vigra::FindAverage<vigra::BImage::PixelType> > 01661 average(max_label); 01662 01663 vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), average); 01664 01665 // write back the average of each region into the original image 01666 vigra::transformImage(srcImageRange(labels), destImage(img), average); 01667 01668 \endcode 01669 01670 <b> Required Interface:</b> 01671 01672 \code 01673 RegionStatistics region; 01674 RegionStatistics::argument_type a; 01675 RegionStatistics::result_type r; 01676 01677 region(a); // update statistics 01678 r = region(); // return statistics 01679 01680 \endcode 01681 */ 01682 template <class RegionStatistics, class LabelType = int> 01683 class ArrayOfRegionStatistics 01684 { 01685 typedef std::vector<RegionStatistics> RegionArray; 01686 01687 public: 01688 /** argument type of the contained statistics object 01689 becomes first argument of the analyser 01690 */ 01691 typedef typename RegionStatistics::argument_type first_argument_type; 01692 01693 /** label type is used to determine the region to be updated 01694 */ 01695 typedef LabelType second_argument_type; 01696 01697 /** label type is also used to determine the region to be 01698 returned by the 1 argument operator() 01699 */ 01700 typedef LabelType argument_type; 01701 01702 /** result type of the contained statistics object 01703 becomes result type of the analyser 01704 */ 01705 typedef typename RegionStatistics::result_type result_type; 01706 01707 /** the value type of the array: the contained statistics object. 01708 <b>Note:</b> this definition was different in older 01709 VIGRA versions. The old definition was wrong. 01710 */ 01711 typedef RegionStatistics value_type; 01712 01713 /** the array's reference type 01714 */ 01715 typedef RegionStatistics & reference; 01716 01717 /** the array's const reference type 01718 */ 01719 typedef RegionStatistics const & const_reference; 01720 01721 /** type to iterate over the statistics array 01722 */ 01723 typedef typename RegionArray::iterator iterator; 01724 01725 /** type to iterate over a const statistics array 01726 */ 01727 typedef typename RegionArray::const_iterator const_iterator; 01728 01729 /** init array of RegionStatistics with default size 0. 01730 */ 01731 ArrayOfRegionStatistics() 01732 {} 01733 01734 /** init array of RegionStatistics with index domain 01735 0...max_region_label. 01736 */ 01737 ArrayOfRegionStatistics(unsigned int max_region_label) 01738 : regions(max_region_label+1) 01739 {} 01740 01741 /** resize array to new index domain 0...max_region_label. 01742 All bin are re-initialized. 01743 */ 01744 void resize(unsigned int max_region_label) 01745 { 01746 RegionArray newRegions(max_region_label+1); 01747 regions.swap(newRegions); 01748 } 01749 01750 /** reset the contained functors to their initial state. 01751 */ 01752 void reset() 01753 { 01754 RegionArray newRegions(regions.size()); 01755 regions.swap(newRegions); 01756 } 01757 01758 /** update regions statistics for region <TT>label</TT>. The label type 01759 is converted to <TT>unsigned int</TT>. 01760 */ 01761 void operator()(first_argument_type const & v, second_argument_type label) { 01762 regions[static_cast<unsigned int>(label)](v); 01763 } 01764 01765 /** merge second region into first 01766 */ 01767 void merge(argument_type label1, argument_type label2) { 01768 regions[static_cast<unsigned int>(label1)](regions[static_cast<unsigned int>(label2)]); 01769 } 01770 01771 /** ask for maximal index (label) allowed 01772 */ 01773 unsigned int maxRegionLabel() const 01774 { return size() - 1; } 01775 01776 /** ask for array size (i.e. maxRegionLabel() + 1) 01777 */ 01778 unsigned int size() const 01779 { return regions.size(); } 01780 01781 /** access the statistics for a region via its label. The label type 01782 is converted to <TT>unsigned int</TT>. 01783 */ 01784 result_type operator()(argument_type label) const 01785 { return regions[static_cast<unsigned int>(label)](); } 01786 01787 /** read the statistics functor for a region via its label 01788 */ 01789 const_reference operator[](argument_type label) const 01790 { return regions[static_cast<unsigned int>(label)]; } 01791 01792 /** access the statistics functor for a region via its label 01793 */ 01794 reference operator[](argument_type label) 01795 { return regions[static_cast<unsigned int>(label)]; } 01796 01797 /** iterator to the begin of the region array 01798 */ 01799 iterator begin() 01800 { return regions.begin(); } 01801 01802 /** const iterator to the begin of the region array 01803 */ 01804 const_iterator begin() const 01805 { return regions.begin(); } 01806 01807 /** iterator to the end of the region array 01808 */ 01809 iterator end() 01810 { return regions.end(); } 01811 01812 /** const iterator to the end of the region array 01813 */ 01814 const_iterator end() const 01815 { return regions.end(); } 01816 01817 private: 01818 std::vector<RegionStatistics> regions; 01819 }; 01820 01821 template <class RegionStatistics, class LabelType> 01822 class FunctorTraits<ArrayOfRegionStatistics<RegionStatistics, LabelType> > 01823 : public FunctorTraitsBase<ArrayOfRegionStatistics<RegionStatistics, LabelType> > 01824 { 01825 public: 01826 typedef VigraTrueType isUnaryFunctor; 01827 typedef VigraTrueType isBinaryAnalyser; 01828 }; 01829 01830 //@} 01831 01832 } // namespace vigra 01833 01834 #endif // VIGRA_INSPECTIMAGE_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|