[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/inspectimage.hxx | ![]() |
---|
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2002 by Ullrich Koethe */ 00004 /* Cognitive Systems Group, University of Hamburg, Germany */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* ( Version 1.2.0, Aug 07 2003 ) */ 00008 /* You may use, modify, and distribute this software according */ 00009 /* to the terms stated in the LICENSE file included in */ 00010 /* the VIGRA distribution. */ 00011 /* */ 00012 /* The VIGRA Website is */ 00013 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00014 /* Please direct questions, bug reports, and contributions to */ 00015 /* koethe@informatik.uni-hamburg.de */ 00016 /* */ 00017 /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ 00018 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ 00019 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ 00020 /* */ 00021 /************************************************************************/ 00022 00023 00024 #ifndef VIGRA_INSPECTIMAGE_HXX 00025 #define VIGRA_INSPECTIMAGE_HXX 00026 00027 #include <vector> 00028 #include <algorithm> 00029 #include "vigra/utilities.hxx" 00030 #include "vigra/numerictraits.hxx" 00031 #include "vigra/iteratortraits.hxx" 00032 #include "vigra/rgbvalue.hxx" 00033 00034 namespace vigra { 00035 00036 /** \addtogroup InspectAlgo Algorithms to Inspect Images 00037 00038 Apply read-only functor to every pixel 00039 */ 00040 //@{ 00041 00042 /********************************************************/ 00043 /* */ 00044 /* inspectLine */ 00045 /* */ 00046 /********************************************************/ 00047 00048 template <class SrcIterator, class SrcAccessor, class Functor> 00049 void 00050 inspectLine(SrcIterator s, 00051 SrcIterator send, SrcAccessor src, 00052 Functor & f) 00053 { 00054 for(; s != send; ++s) 00055 f(src(s)); 00056 } 00057 00058 template <class SrcIterator, class SrcAccessor, 00059 class MaskIterator, class MaskAccessor, 00060 class Functor> 00061 void 00062 inspectLineIf(SrcIterator s, 00063 SrcIterator send, SrcAccessor src, 00064 MaskIterator m, MaskAccessor mask, 00065 Functor & f) 00066 { 00067 for(; s != send; ++s, ++m) 00068 if(mask(m)) 00069 f(src(s)); 00070 } 00071 00072 template <class SrcIterator1, class SrcAccessor1, 00073 class SrcIterator2, class SrcAccessor2, 00074 class Functor> 00075 void 00076 inspectTwoLines(SrcIterator1 s1, 00077 SrcIterator1 s1end, SrcAccessor1 src1, 00078 SrcIterator2 s2, SrcAccessor2 src2, 00079 Functor & f) 00080 { 00081 for(; s1 != s1end; ++s1, ++s2) 00082 f(src1(s1), src2(s2)); 00083 } 00084 00085 template <class SrcIterator1, class SrcAccessor1, 00086 class SrcIterator2, class SrcAccessor2, 00087 class MaskIterator, class MaskAccessor, 00088 class Functor> 00089 void 00090 inspectTwoLinesIf(SrcIterator1 s1, 00091 SrcIterator1 s1end, SrcAccessor1 src1, 00092 SrcIterator2 s2, SrcAccessor2 src2, 00093 MaskIterator m, MaskAccessor mask, 00094 Functor & f) 00095 { 00096 for(; s1 != s1end; ++s1, ++s2, ++m) 00097 if(mask(m)) 00098 f(src1(s1), src2(s2)); 00099 } 00100 00101 /********************************************************/ 00102 /* */ 00103 /* inspectImage */ 00104 /* */ 00105 /********************************************************/ 00106 00107 /** \brief Apply read-only functor to every pixel in the image. 00108 00109 This function can be used to collect statistics of the image etc. 00110 The results must be stored in the functor, which serves as a return 00111 value. 00112 The function uses an accessor to access the pixel data. 00113 00114 <b> Declarations:</b> 00115 00116 pass arguments explicitly: 00117 \code 00118 namespace vigra { 00119 template <class ImageIterator, class Accessor, class Functor> 00120 void 00121 inspectImage(ImageIterator upperleft, ImageIterator lowerright, 00122 Accessor a, Functor & f) 00123 } 00124 \endcode 00125 00126 use argument objects in conjuction with \ref ArgumentObjectFactories: 00127 \code 00128 namespace vigra { 00129 template <class ImageIterator, class Accessor, class Functor> 00130 void 00131 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img, 00132 Functor & f) 00133 } 00134 \endcode 00135 00136 <b> Usage:</b> 00137 00138 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 00139 Namespace: vigra 00140 00141 \code 00142 // init functor 00143 vigra::BImage img; 00144 00145 vigra::FindMinMax<vigra::BImage::PixelType> minmax(); 00146 00147 vigra::inspectImage(srcImageRange(img), minmax); 00148 00149 cout << "Min: " << minmax.min << " Max: " << minmax.max; 00150 00151 \endcode 00152 00153 <b> Required Interface:</b> 00154 00155 \code 00156 ConstImageIterator upperleft, lowerright; 00157 ConstImageIterator::row_iterator ix = upperleft.rowIterator(); 00158 00159 Accessor accessor; 00160 Functor functor; 00161 00162 functor(accessor(ix)); // return not used 00163 \endcode 00164 00165 */ 00166 template <class ImageIterator, class Accessor, class Functor> 00167 void 00168 inspectImage(ImageIterator upperleft, ImageIterator lowerright, 00169 Accessor a, Functor & f) 00170 { 00171 int w = lowerright.x - upperleft.x; 00172 00173 for(; upperleft.y<lowerright.y; ++upperleft.y) 00174 { 00175 inspectLine(upperleft.rowIterator(), 00176 upperleft.rowIterator() + w, a, f); 00177 } 00178 } 00179 00180 template <class ImageIterator, class Accessor, class Functor> 00181 inline 00182 void 00183 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img, 00184 Functor & f) 00185 { 00186 inspectImage(img.first, img.second, img.third, f); 00187 } 00188 00189 namespace functor 00190 { 00191 template <class T> class UnaryAnalyser; 00192 } 00193 00194 template <class ImageIterator, class Accessor, class Functor> 00195 inline 00196 void 00197 inspectImage(ImageIterator upperleft, ImageIterator lowerright, 00198 Accessor a, functor::UnaryAnalyser<Functor> const & f) 00199 { 00200 inspectImage(upperleft, lowerright, a, 00201 const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00202 } 00203 00204 template <class ImageIterator, class Accessor, class Functor> 00205 inline 00206 void 00207 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img, 00208 functor::UnaryAnalyser<Functor> const & f) 00209 { 00210 inspectImage(img.first, img.second, img.third, 00211 const_cast<functor::UnaryAnalyser<Functor> &>(f)); 00212 } 00213 00214 /********************************************************/ 00215 /* */ 00216 /* inspectImageIf */ 00217 /* */ 00218 /********************************************************/ 00219 00220 /** \brief Apply read-only functor to every pixel in the ROI. 00221 00222 This function can be used to collect statistics of the roi etc. 00223 The functor is called whenever the return value of the mask's 00224 accessor is not zero. 00225 The results must be stored in the functor, which serves as a return 00226 value. 00227 Accessors are used to access the pixel and mask data. 00228 00229 <b> Declarations:</b> 00230 00231 pass arguments explicitly: 00232 \code 00233 namespace vigra { 00234 template <class ImageIterator, class Accessor, 00235 class MaskImageIterator, class MaskAccessor, class Functor> 00236 void 00237 inspectImageIf(ImageIterator upperleft, ImageIterator lowerright, 00238 MaskImageIterator mask_upperleft, MaskAccessor ma, 00239 Functor & f) 00240 } 00241 \endcode 00242 00243 00244 use argument objects in conjuction with \ref ArgumentObjectFactories: 00245 \code 00246 namespace vigra { 00247 template <class ImageIterator, class Accessor, 00248 class MaskImageIterator, class MaskAccessor, class Functor> 00249 void 00250 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img, 00251 pair<MaskImageIterator, MaskAccessor> mask, 00252 Functor & f) 00253 } 00254 \endcode 00255 00256 <b> Usage:</b> 00257 00258 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 00259 Namespace: vigra 00260 00261 \code 00262 vigra::BImage img(100, 100); 00263 vigra::BImage mask(100, 100); 00264 00265 // init functor 00266 vigra::FindMinMax<vigra::BImage::PixelType> minmax(); 00267 00268 vigra::inspectImageIf(srcImageRange(img), 00269 maskImage(mask), minmax); 00270 00271 cout << "Min: " << minmax.min << " Max: " << minmax.max; 00272 00273 \endcode 00274 00275 <b> Required Interface:</b> 00276 00277 \code 00278 ConstImageIterator upperleft, lowerright; 00279 MaskImageIterator mask_upperleft; 00280 ConstImageIterator::row_iterator ix = upperleft.rowIterator(); 00281 MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator(); 00282 00283 Accessor accessor; 00284 MaskAccessor mask_accessor; 00285 00286 Functor functor; 00287 00288 if(mask_accessor(mx)) functor(accessor(ix)); 00289 \endcode 00290 00291 */ 00292 template <class ImageIterator, class Accessor, 00293 class MaskImageIterator, class MaskAccessor, class Functor> 00294 void 00295 inspectImageIf(ImageIterator upperleft, 00296 ImageIterator lowerright, Accessor a, 00297 MaskImageIterator mask_upperleft, MaskAccessor ma, 00298 Functor & f) 00299 { 00300 int w = lowerright.x - upperleft.x; 00301 00302 for(; upperleft.y<lowerright.y; ++upperleft.y, ++mask_upperleft.y) 00303 { 00304 inspectLineIf(upperleft.rowIterator(), 00305 upperleft.rowIterator() + w, a, 00306 mask_upperleft.rowIterator(), ma, f); 00307 } 00308 } 00309 00310 template <class ImageIterator, class Accessor, 00311 class MaskImageIterator, class MaskAccessor, class Functor> 00312 inline 00313 void 00314 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img, 00315 pair<MaskImageIterator, MaskAccessor> mask, 00316 Functor & f) 00317 { 00318 inspectImageIf(img.first, img.second, img.third, 00319 mask.first, mask.second, f); 00320 } 00321 00322 /********************************************************/ 00323 /* */ 00324 /* inspectTwoImages */ 00325 /* */ 00326 /********************************************************/ 00327 00328 /** \brief Apply read-only functor to every pixel of both images. 00329 00330 This function can be used to collect statistics for each region of a 00331 labeled image, especially in conjunction with 00332 the \ref ArrayOfRegionStatistics functor. The results must be 00333 stored in the functor which serves as a return value. 00334 Accessors are used to access the pixel data. 00335 00336 <b> Declarations:</b> 00337 00338 pass arguments explicitly: 00339 \code 00340 namespace vigra { 00341 template <class ImageIterator1, class Accessor1, 00342 class ImageIterator2, class Accessor2, 00343 class Functor> 00344 void 00345 inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00346 ImageIterator2 upperleft2, Accessor2 a2, 00347 Functor & f) 00348 } 00349 \endcode 00350 00351 00352 use argument objects in conjuction with \ref ArgumentObjectFactories: 00353 \code 00354 namespace vigra { 00355 template <class ImageIterator1, class Accessor1, 00356 class ImageIterator2, class Accessor2, 00357 class Functor> 00358 void 00359 inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00360 pair<ImageIterator2, Accessor2> img2, 00361 Functor & f) 00362 } 00363 \endcode 00364 00365 <b> Usage:</b> 00366 00367 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 00368 Namespace: vigra 00369 00370 \code 00371 vigra::BImage image1; 00372 vigra::BImage image2; 00373 00374 SomeStatisticsFunctor stats(...); // init functor 00375 00376 vigra::inspectTwoImages(srcImageRange(image1), srcImage(image2), 00377 region_stats); 00378 00379 00380 \endcode 00381 00382 <b> Required Interface:</b> 00383 00384 \code 00385 ImageIterator1 upperleft1, lowerright1; 00386 ImageIterator2 upperleft2; 00387 ImageIterator1::row_iterator ix1 = upperleft1.rowIterator(); 00388 ImageIterator2::row_iterator ix2 = upperleft2.rowIterator(); 00389 00390 Accessor1 accessor1; 00391 Accessor2 accessor2; 00392 00393 Functor functor; 00394 functor(accessor1(ix1), accessor2(ix2)); // return not used 00395 \endcode 00396 00397 */ 00398 template <class ImageIterator1, class Accessor1, 00399 class ImageIterator2, class Accessor2, 00400 class Functor> 00401 void 00402 inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00403 ImageIterator2 upperleft2, Accessor2 a2, 00404 Functor & f) 00405 { 00406 int w = lowerright1.x - upperleft1.x; 00407 00408 for(; upperleft1.y<lowerright1.y; ++upperleft1.y, ++upperleft2.y) 00409 { 00410 inspectTwoLines(upperleft1.rowIterator(), 00411 upperleft1.rowIterator() + w, a1, 00412 upperleft2.rowIterator(), a2, f); 00413 } 00414 } 00415 00416 template <class ImageIterator1, class Accessor1, 00417 class ImageIterator2, class Accessor2, 00418 class Functor> 00419 inline 00420 void 00421 inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00422 pair<ImageIterator2, Accessor2> img2, 00423 Functor & f) 00424 { 00425 inspectTwoImages(img1.first, img1.second, img1.third, 00426 img2.first, img2.second, f); 00427 } 00428 00429 /********************************************************/ 00430 /* */ 00431 /* inspectTwoImagesIf */ 00432 /* */ 00433 /********************************************************/ 00434 00435 /** \brief Apply read-only functor to those pixels of both images where 00436 the mask image is non-zero. 00437 00438 This function can be used to collect statistics for selected regions of a 00439 labeled image, especially in conjunction with 00440 the \ref ArrayOfRegionStatistics functor. The results must be 00441 stored in the functor which serves as a return value. 00442 Accessors are used to access the pixel data. 00443 00444 <b> Declarations:</b> 00445 00446 pass arguments explicitly: 00447 \code 00448 namespace vigra { 00449 template <class ImageIterator1, class Accessor1, 00450 class ImageIterator2, class Accessor2, 00451 class MaskImageIterator, class MaskAccessor, 00452 class Functor> 00453 void 00454 inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00455 ImageIterator2 upperleft2, Accessor2 a2, 00456 MaskImageIterator mupperleft, MaskAccessor mask, 00457 Functor & f) 00458 } 00459 \endcode 00460 00461 00462 use argument objects in conjuction with \ref ArgumentObjectFactories: 00463 \code 00464 namespace vigra { 00465 template <class ImageIterator1, class Accessor1, 00466 class ImageIterator2, class Accessor2, 00467 class MaskImageIterator, class MaskAccessor, 00468 class Functor> 00469 void 00470 inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00471 pair<ImageIterator2, Accessor2> img2, 00472 pair<MaskImageIterator, MaskAccessor> mimg, 00473 Functor & f) 00474 } 00475 \endcode 00476 00477 <b> Usage:</b> 00478 00479 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 00480 Namespace: vigra 00481 00482 \code 00483 vigra::BImage image1; 00484 vigra::BImage image2; 00485 vigra::BImage maskimage; 00486 00487 SomeStatisticsFunctor stats(...); // init functor 00488 00489 vigra::inspectTwoImagesIf(srcImageRange(image1), srcImage(image2), 00490 srcImage(maskimage), region_stats); 00491 00492 \endcode 00493 00494 <b> Required Interface:</b> 00495 00496 \code 00497 ImageIterator1 upperleft1, lowerright1; 00498 ImageIterator2 upperleft2; 00499 MaskImageIterator upperleftm; 00500 ImageIterator1::row_iterator ix1 = upperleft1.rowIterator(); 00501 ImageIterator2::row_iterator ix2 = upperleft2.rowIterator(); 00502 MaskImageIterator::row_iterator mx = mupperleft.rowIterator(); 00503 00504 Accessor1 accessor1; 00505 Accessor2 accessor2; 00506 MaskAccessor mask; 00507 00508 Functor functor; 00509 if(mask(mx)) 00510 functor(accessor1(ix1), accessor2(ix2)); 00511 \endcode 00512 00513 */ 00514 template <class ImageIterator1, class Accessor1, 00515 class ImageIterator2, class Accessor2, 00516 class MaskImageIterator, class MaskAccessor, 00517 class Functor> 00518 void 00519 inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, 00520 ImageIterator2 upperleft2, Accessor2 a2, 00521 MaskImageIterator mupperleft, MaskAccessor mask, 00522 Functor & f) 00523 { 00524 int w = lowerright1.x - upperleft1.x; 00525 00526 for(; upperleft1.y<lowerright1.y; ++upperleft1.y, ++upperleft2.y, ++mupperleft.y) 00527 { 00528 inspectTwoLinesIf(upperleft1.rowIterator(), 00529 upperleft1.rowIterator() + w, a1, 00530 upperleft2.rowIterator(), a2, 00531 mupperleft.rowIterator(), mask, f); 00532 } 00533 } 00534 00535 template <class ImageIterator1, class Accessor1, 00536 class ImageIterator2, class Accessor2, 00537 class MaskImageIterator, class MaskAccessor, 00538 class Functor> 00539 inline 00540 void 00541 inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1, 00542 pair<ImageIterator2, Accessor2> img2, 00543 pair<MaskImageIterator, MaskAccessor> m, 00544 Functor & f) 00545 { 00546 inspectTwoImagesIf(img1.first, img1.second, img1.third, 00547 img2.first, img2.second, 00548 m.first, m.second, 00549 f); 00550 } 00551 00552 //@} 00553 00554 /** \addtogroup InspectFunctor Functors To Inspect Images 00555 Functors which report image statistics 00556 */ 00557 //@{ 00558 00559 /********************************************************/ 00560 /* */ 00561 /* FindMinMax */ 00562 /* */ 00563 /********************************************************/ 00564 00565 /** \brief Find the minimum and maximum pixel value in an image or ROI. 00566 00567 In addition the size of the ROI is calculated. 00568 This Functor can also be used in conjunction with 00569 \ref ArrayOfRegionStatistics to find the extremes of all regions in 00570 a labeled image. 00571 00572 <b> Usage:</b> 00573 00574 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 00575 Namespace: vigra 00576 00577 \code 00578 vigra::BImage img; 00579 00580 vigra::FindMinMax<vigra::BImage::PixelType> minmax; // init functor 00581 00582 vigra::inspectImage(srcImageRange(img), minmax); 00583 00584 cout << "Min: " << minmax.min << " Max: " << minmax.max; 00585 00586 \endcode 00587 00588 <b> Required Interface:</b> 00589 00590 \code 00591 VALUETYPE v1, v2(v1); 00592 00593 v1 < v2; 00594 v1 = v2; 00595 \endcode 00596 00597 */ 00598 template <class VALUETYPE> 00599 class FindMinMax 00600 { 00601 public: 00602 00603 /** the functor's argument type 00604 */ 00605 typedef VALUETYPE argument_type; 00606 00607 /** the functor's result type 00608 */ 00609 typedef VALUETYPE result_type; 00610 00611 /** \deprecated use argument_type 00612 */ 00613 typedef VALUETYPE value_type; 00614 00615 /** init min and max 00616 */ 00617 FindMinMax() 00618 : count(0) 00619 {} 00620 00621 /** (re-)init functor (clear min, max) 00622 */ 00623 void reset() 00624 { 00625 count = 0; 00626 } 00627 00628 /** update min and max 00629 */ 00630 void operator()(argument_type const & v) 00631 { 00632 if(count) 00633 { 00634 if(v < min) min = v; 00635 if(max < v) max = v; 00636 } 00637 else 00638 { 00639 min = v; 00640 max = v; 00641 } 00642 ++count; 00643 } 00644 00645 /** update min and max with components of RGBValue<VALUETYPE> 00646 */ 00647 void operator()(RGBValue<VALUETYPE> const & v) 00648 { 00649 operator()(v.red()); 00650 operator()(v.green()); 00651 operator()(v.blue()); 00652 } 00653 00654 /** merge two statistics 00655 */ 00656 void operator()(FindMinMax const & v) 00657 { 00658 if(v.count) 00659 { 00660 if(count) 00661 { 00662 if(v.min < min) min = v.min; 00663 if((this->max) < v.max) max = v.max; 00664 } 00665 else 00666 { 00667 min = v.min; 00668 max = v.max; 00669 } 00670 } 00671 count += v.count; 00672 } 00673 00674 /** the current min 00675 */ 00676 VALUETYPE min; 00677 00678 /** the current max 00679 */ 00680 VALUETYPE max; 00681 00682 /** the number of values processed so far 00683 */ 00684 unsigned int count; 00685 00686 }; 00687 00688 /********************************************************/ 00689 /* */ 00690 /* FindAverage */ 00691 /* */ 00692 /********************************************************/ 00693 00694 /** \brief Find the average pixel value in an image or ROI. 00695 00696 In addition the size of the ROI is calculated. 00697 This Functor can also be used in conjunction with 00698 \ref ArrayOfRegionStatistics to find the average of all regions in 00699 a labeled image. 00700 00701 <b> Usage:</b> 00702 00703 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 00704 Namespace: vigra 00705 00706 \code 00707 vigra::BImage img; 00708 00709 vigra::FindAverage<vigra::BImage::PixelType> average; // init functor 00710 00711 vigra::inspectImage(srcImageRange(img), average); 00712 00713 cout << "Average: " << average(); 00714 00715 \endcode 00716 00717 <b> Required Interface:</b> 00718 00719 \code 00720 VALUETYPE v1, v2(v1); 00721 00722 v1 < v2; 00723 v1 = v2; 00724 \endcode 00725 00726 */ 00727 template <class VALUETYPE> 00728 class FindAverage 00729 { 00730 public: 00731 00732 /** the functor's argument type 00733 */ 00734 typedef VALUETYPE argument_type; 00735 00736 /** the functor's result type 00737 */ 00738 typedef typename NumericTraits<VALUETYPE>::RealPromote result_type; 00739 00740 /** \deprecated use argument_type and result_type 00741 */ 00742 typedef typename NumericTraits<VALUETYPE>::RealPromote value_type; 00743 00744 /** init average 00745 */ 00746 FindAverage() 00747 : count(0), sum(NumericTraits<result_type>::zero()) 00748 {} 00749 00750 /** (re-)init average 00751 */ 00752 void reset() 00753 { 00754 count = 0; 00755 sum = NumericTraits<result_type>::zero(); 00756 } 00757 00758 /** update average 00759 */ 00760 void operator()(argument_type const & v) 00761 { 00762 sum += v; 00763 ++count; 00764 } 00765 00766 /** merge two statistics 00767 */ 00768 void operator()(FindAverage const & v) 00769 { 00770 sum += v.sum; 00771 count += v.count; 00772 } 00773 00774 /** return current average 00775 */ 00776 result_type average() const 00777 { 00778 return sum / (double)count; 00779 } 00780 00781 /** return current average 00782 */ 00783 result_type operator()() const 00784 { 00785 return sum / (double)count; 00786 } 00787 00788 unsigned int count; 00789 result_type sum; 00790 00791 }; 00792 00793 /********************************************************/ 00794 /* */ 00795 /* FindROISize */ 00796 /* */ 00797 /********************************************************/ 00798 00799 /** \brief Calculate the size of an ROI in an image. 00800 00801 This Functor is often used in conjunction with 00802 \ref ArrayOfRegionStatistics to find the sizes of all regions in 00803 a labeled image. 00804 00805 <b> Usage:</b> 00806 00807 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 00808 Namespace: vigra 00809 00810 \code 00811 vigra::BImage img, mask; 00812 00813 vigra::FindROISize<vigra::BImage::PixelType> roisize; // init functor 00814 00815 vigra::inspectImageIf(srcImageRange(img), srcImage(mask), roisize); 00816 00817 cout << "Size of ROI: " << roisize.count; 00818 00819 \endcode 00820 00821 */ 00822 template <class VALUETYPE> 00823 class FindROISize 00824 { 00825 public: 00826 00827 /** the functor's argument type 00828 */ 00829 typedef VALUETYPE argument_type; 00830 00831 /** the functor's result type 00832 */ 00833 typedef unsigned int result_type; 00834 00835 /** \deprecated use argument_type and result_type 00836 */ 00837 typedef VALUETYPE value_type; 00838 00839 /** init counter to 0 00840 */ 00841 FindROISize() 00842 : count(0) 00843 {} 00844 00845 /** (re-)init ROI size with 0 00846 */ 00847 void reset() 00848 { 00849 count = 0; 00850 } 00851 00852 /** update counter 00853 */ 00854 void operator()(argument_type const &) 00855 { 00856 ++count; 00857 } 00858 00859 /** return current size 00860 */ 00861 result_type operator()() const 00862 { 00863 return count; 00864 } 00865 00866 /** return current size 00867 */ 00868 result_type size() const 00869 { 00870 return count; 00871 } 00872 00873 /** merge two statistics 00874 */ 00875 void operator()(FindROISize const & o) 00876 { 00877 count += o.count; 00878 } 00879 00880 /** the current counter 00881 */ 00882 result_type count; 00883 00884 }; 00885 00886 /********************************************************/ 00887 /* */ 00888 /* FindBoundingRectangle */ 00889 /* */ 00890 /********************************************************/ 00891 00892 /** \brief Calculate the bounding rectangle of an ROI in an image. 00893 00894 As always in VIGRA, <TT>roiRect.lowerRight</TT> is <em> just outside the rectangle</em>. 00895 That is, the last pixel actually in the rectangle is <TT>roiRect.lowerRight - Diff2D(1,1)</TT>. 00896 This Functor is often used in conjunction with 00897 \ref ArrayOfRegionStatistics to find the bounding rectangles 00898 of all regions in a labeled image. 00899 00900 <b> Usage:</b> 00901 00902 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 00903 Namespace: vigra 00904 00905 \code 00906 vigra::BImage img, mask; 00907 ... 00908 00909 vigra::FindBoundingRectangle roiRect; // init functor 00910 00911 // Diff2D is used as the iterator for the source image. This 00912 // simulates an image where each pixel value equals that pixel's 00913 // coordinates. Tha image 'mask' determines the ROI. 00914 vigra::inspectImageIf(srcIterRange(Diff2D(0,0), img.size()), 00915 srcImage(mask), roiRect); 00916 00917 cout << "Upper left of ROI: " << 00918 roiRect.upperLeft.x << ", " << roiRect.upperLeft.y << endl; 00919 cout << "Lower right of ROI: " << 00920 roiRect.lowerRight.x << ", " << roiRect.lowerRight.y << endl; 00921 00922 \endcode 00923 00924 */ 00925 class FindBoundingRectangle 00926 { 00927 public: 00928 00929 /** the functor's argument type 00930 */ 00931 typedef Diff2D argument_type; 00932 00933 /** the functors result type 00934 */ 00935 typedef pair<Diff2D, Diff2D> result_type; 00936 00937 /** \deprecated use argument_type 00938 */ 00939 typedef Diff2D value_type; 00940 00941 /** Upper left of the region as seen so far 00942 */ 00943 Point2D upperLeft; 00944 00945 /** Lower right of the region as seen so far 00946 */ 00947 Point2D lowerRight; 00948 00949 /** are the functors contents valid ? 00950 */ 00951 bool valid; 00952 00953 /** init rectangle to invalid values 00954 */ 00955 FindBoundingRectangle() 00956 : valid(false) 00957 {} 00958 00959 /** (re-)init functor to find other bounds 00960 */ 00961 void reset() 00962 { 00963 valid = false; 00964 } 00965 00966 /** update rectangle by including the coordinate coord 00967 */ 00968 void operator()(argument_type const & coord) 00969 { 00970 if(!valid) 00971 { 00972 upperLeft = Point2D(coord); 00973 lowerRight = Point2D(coord + Diff2D(1,1)); 00974 valid = true; 00975 } 00976 else 00977 { 00978 upperLeft.x = std::min(upperLeft.x, coord.x); 00979 upperLeft.y = std::min(upperLeft.y, coord.y); 00980 lowerRight.x = std::max(lowerRight.x, coord.x + 1); 00981 lowerRight.y = std::max(lowerRight.y, coord.y + 1); 00982 } 00983 } 00984 00985 /** update rectangle by merging it with another rectangle 00986 */ 00987 void operator()(FindBoundingRectangle const & otherRegion) 00988 { 00989 if(!valid) 00990 { 00991 upperLeft = otherRegion.upperLeft; 00992 lowerRight = otherRegion.lowerRight; 00993 valid = otherRegion.valid; 00994 } 00995 else if(otherRegion.valid) 00996 { 00997 upperLeft.x = std::min(upperLeft.x, otherRegion.upperLeft.x); 00998 upperLeft.y = std::min(upperLeft.y, otherRegion.upperLeft.y); 00999 lowerRight.x = std::max(lowerRight.x, otherRegion.lowerRight.x); 01000 lowerRight.y = std::max(lowerRight.y, otherRegion.lowerRight.y); 01001 } 01002 } 01003 01004 /** Get current rectangle. <TT>result_type::first</TT> is the upper 01005 left corner of the rectangle, <TT>result_type::second</TT> 01006 the lower right. 01007 01008 */ 01009 result_type operator()() const 01010 { 01011 return std::make_pair(upperLeft, lowerRight); 01012 } 01013 }; 01014 01015 /********************************************************/ 01016 /* */ 01017 /* LastValueFunctor */ 01018 /* */ 01019 /********************************************************/ 01020 01021 /** \brief Stores and returns the last value it has seen. 01022 01023 This Functor is best used in conjunction with 01024 \ref ArrayOfRegionStatistics to realize a look-up table. 01025 01026 <b> Usage:</b> 01027 01028 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 01029 Namespace: vigra 01030 01031 \code 01032 vigra::BImage img; 01033 01034 vigra::ArrayOfRegionStatistics<LastValueFunctor<unsigned char> > lut(255); 01035 01036 for(int i=0; i<256; ++i) 01037 { 01038 lut[i] = ...; // init look-up table 01039 } 01040 01041 vigra::transformImage(srcImageRange(img), destImage(img), lut); 01042 01043 \endcode 01044 01045 */ 01046 template <class VALUETYPE> 01047 class LastValueFunctor 01048 { 01049 public: 01050 01051 /** the functor's argument type 01052 */ 01053 typedef VALUETYPE argument_type; 01054 01055 /** the functor's result type 01056 */ 01057 typedef VALUETYPE result_type; 01058 01059 /** \deprecated use argument_type and result_type 01060 */ 01061 typedef VALUETYPE value_type; 01062 01063 /** default initialization of value 01064 */ 01065 LastValueFunctor() 01066 {} 01067 01068 /** replace value 01069 */ 01070 void operator=(argument_type const & v) { value = v; } 01071 01072 /** replace value 01073 */ 01074 void operator()(argument_type const & v) { value = v; } 01075 01076 /** return current value 01077 */ 01078 result_type const & operator()() const { return value; } 01079 01080 /** the current value 01081 */ 01082 VALUETYPE value; 01083 01084 }; 01085 01086 /********************************************************/ 01087 /* */ 01088 /* ArrayOfRegionStatistics */ 01089 /* */ 01090 /********************************************************/ 01091 01092 /** \brief Calculate statistics for all regions of a labeled image. 01093 01094 This Functor encapsulates an array of statistics functors, one 01095 for each label, and selects the one to be updated according to the 01096 pixel's label. 01097 01098 <b> Usage:</b> 01099 01100 <b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspectimage.hxx</a>"<br> 01101 Namespace: vigra 01102 01103 \code 01104 vigra::BImage img; 01105 vigra::IImage labels; 01106 int max_label; 01107 ... 01108 01109 // init functor as an array of 'max_label' FindMinMax-Functors 01110 vigra::ArrayOfRegionStatistics<vigra::FindMinMax<vigra::BImage::PixelType> > 01111 minmax(max_label); 01112 01113 vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), minmax); 01114 01115 for(int i=0; i<= max_label; ++i) 01116 { 01117 cout << "Max gray lavel of region " << i << ": " 01118 << minmax.region[i].max << endl; 01119 } 01120 01121 // init functor as an array of 'max_label' FindAverage-Functors 01122 vigra::ArrayOfRegionStatistics<vigra::FindAverage<vigra::BImage::PixelType> > 01123 average(max_label); 01124 01125 vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), average); 01126 01127 // write back the average of each region into the original image 01128 vigra::transformImage(srcImageRange(labels), destImage(img), average); 01129 01130 \endcode 01131 01132 <b> Required Interface:</b> 01133 01134 \code 01135 RegionStatistics region; 01136 RegionStatistics::argument_type a; 01137 RegionStatistics::result_type r; 01138 01139 region(a); // update statistics 01140 r = region(); // return statistics 01141 01142 \endcode 01143 */ 01144 template <class RegionStatistics, class LabelType = int> 01145 class ArrayOfRegionStatistics 01146 { 01147 typedef std::vector<RegionStatistics> RegionArray; 01148 01149 public: 01150 /** argument type of the contained statistics object 01151 becomes first argument of the analyser 01152 */ 01153 typedef typename RegionStatistics::argument_type first_argument_type; 01154 01155 /** label type is used to determine the region to be updated 01156 */ 01157 typedef LabelType second_argument_type; 01158 01159 /** label type is also used to determine the region to be 01160 returned by the 1 argument operator() 01161 */ 01162 typedef LabelType argument_type; 01163 01164 /** result type of the contained statistics object 01165 becomes result type of the analyser 01166 */ 01167 typedef typename RegionStatistics::result_type result_type; 01168 01169 /** the value type of the array: the contained statistics object. 01170 <b>Note:</b> this definition was different in older 01171 VIGRA versions. The old definition was wrong. 01172 */ 01173 typedef RegionStatistics value_type; 01174 01175 /** the array's reference type 01176 */ 01177 typedef RegionStatistics & reference; 01178 01179 /** the array's const reference type 01180 */ 01181 typedef RegionStatistics const & const_reference; 01182 01183 /** type to iterate over the statistics array 01184 */ 01185 typedef typename RegionArray::iterator iterator; 01186 01187 /** type to iterate over a const statistics array 01188 */ 01189 typedef typename RegionArray::const_iterator const_iterator; 01190 01191 /** init array of RegionStatistics with default size 0. 01192 */ 01193 ArrayOfRegionStatistics() 01194 {} 01195 01196 /** init array of RegionStatistics with index domain 01197 0...max_region_label. 01198 */ 01199 ArrayOfRegionStatistics(unsigned int max_region_label) 01200 : regions(max_region_label+1) 01201 {} 01202 01203 /** resize array to new index domain 0...max_region_label. 01204 All bin are re-initialized. 01205 */ 01206 void resize(unsigned int max_region_label) 01207 { 01208 RegionArray newRegions(max_region_label+1); 01209 regions.swap(newRegions); 01210 } 01211 01212 /** reset the contained functors to their initial state. 01213 */ 01214 void reset() 01215 { 01216 RegionArray newRegions(regions.size()); 01217 regions.swap(newRegions); 01218 } 01219 01220 /** update regions statistics for region <TT>label</TT>. The label type 01221 is converted to <TT>unsigned int</TT>. 01222 */ 01223 void operator()(first_argument_type const & v, second_argument_type label) { 01224 regions[static_cast<unsigned int>(label)](v); 01225 } 01226 01227 /** merge second region into first 01228 */ 01229 void merge(argument_type label1, argument_type label2) { 01230 regions[static_cast<unsigned int>(label1)](regions[static_cast<unsigned int>(label2)]); 01231 } 01232 01233 /** ask for maximal index (label) allowed 01234 */ 01235 unsigned int maxRegionLabel() const 01236 { return size() - 1; } 01237 01238 /** ask for array size (i.e. maxRegionLabel() + 1) 01239 */ 01240 unsigned int size() const 01241 { return regions.size(); } 01242 01243 /** access the statistics for a region via its label. The label type 01244 is converted to <TT>unsigned int</TT>. 01245 */ 01246 result_type operator()(argument_type label) const 01247 { return regions[static_cast<unsigned int>(label)](); } 01248 01249 /** read the statistics functor for a region via its label 01250 */ 01251 const_reference operator[](argument_type label) const 01252 { return regions[static_cast<unsigned int>(label)]; } 01253 01254 /** access the statistics functor for a region via its label 01255 */ 01256 reference operator[](argument_type label) 01257 { return regions[static_cast<unsigned int>(label)]; } 01258 01259 /** iterator to the begin of the region array 01260 */ 01261 iterator begin() 01262 { return regions.begin(); } 01263 01264 /** const iterator to the begin of the region array 01265 */ 01266 const_iterator begin() const 01267 { return regions.begin(); } 01268 01269 /** iterator to the end of the region array 01270 */ 01271 iterator end() 01272 { return regions.end(); } 01273 01274 /** const iterator to the end of the region array 01275 */ 01276 const_iterator end() const 01277 { return regions.end(); } 01278 01279 private: 01280 std::vector<RegionStatistics> regions; 01281 }; 01282 01283 01284 //@} 01285 01286 01287 } // namespace vigra 01288 01289 #endif // VIGRA_INSPECTIMAGE_HXX
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|