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