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