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

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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.7.0 (Thu Aug 25 2011)