[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]

details vigra/inspectimage.hxx VIGRA

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)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.2.0 (7 Aug 2003)