VIGRA - VIGRA: vigra/inspectimage.hxx Source File

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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python VIGRA 1.6.0 (13 Aug 2008)