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

vigra/inspectimage.hxx |

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