[ 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)