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