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