VIGRA - vigra/inspectimage.hxx Source File

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