vigra - vigra/inspectimage.hxx Source File

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

vigra/inspectimage.hxx |

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