/************************************************************************/ /* */ /* Copyright 1998-2002 by Ullrich Koethe */ /* Cognitive Systems Group, University of Hamburg, Germany */ /* */ /* This file is part of the VIGRA computer vision library. */ /* The VIGRA Website is */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* Please direct questions, bug reports, and contributions to */ /* koethe@informatik.uni-hamburg.de or */ /* vigra@kogs1.informatik.uni-hamburg.de */ /* */ /* Permission is hereby granted, free of charge, to any person */ /* obtaining a copy of this software and associated documentation */ /* files (the "Software"), to deal in the Software without */ /* restriction, including without limitation the rights to use, */ /* copy, modify, merge, publish, distribute, sublicense, and/or */ /* sell copies of the Software, and to permit persons to whom the */ /* Software is furnished to do so, subject to the following */ /* conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the */ /* Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* OTHER DEALINGS IN THE SOFTWARE. */ /* */ /************************************************************************/ #ifndef VIGRA_INSPECTIMAGE_HXX #define VIGRA_INSPECTIMAGE_HXX #include #include #include "vigra/utilities.hxx" #include "vigra/numerictraits.hxx" #include "vigra/iteratortraits.hxx" #include "vigra/functortraits.hxx" #include "vigra/rgbvalue.hxx" namespace vigra { /** \addtogroup InspectAlgo Algorithms to Inspect Images Apply read-only functor to every pixel */ //@{ /********************************************************/ /* */ /* inspectLine */ /* */ /********************************************************/ template void inspectLine(SrcIterator s, SrcIterator send, SrcAccessor src, Functor & f) { for(; s != send; ++s) f(src(s)); } template void inspectLineIf(SrcIterator s, SrcIterator send, SrcAccessor src, MaskIterator m, MaskAccessor mask, Functor & f) { for(; s != send; ++s, ++m) if(mask(m)) f(src(s)); } template void inspectTwoLines(SrcIterator1 s1, SrcIterator1 s1end, SrcAccessor1 src1, SrcIterator2 s2, SrcAccessor2 src2, Functor & f) { for(; s1 != s1end; ++s1, ++s2) f(src1(s1), src2(s2)); } template void inspectTwoLinesIf(SrcIterator1 s1, SrcIterator1 s1end, SrcAccessor1 src1, SrcIterator2 s2, SrcAccessor2 src2, MaskIterator m, MaskAccessor mask, Functor & f) { for(; s1 != s1end; ++s1, ++s2, ++m) if(mask(m)) f(src1(s1), src2(s2)); } /********************************************************/ /* */ /* inspectImage */ /* */ /********************************************************/ /** \brief Apply read-only functor to every pixel in the image. This function can be used to collect statistics of the image etc. The results must be stored in the functor, which serves as a return value. The function uses an accessor to access the pixel data. Declarations: pass arguments explicitly: \code namespace vigra { template void inspectImage(ImageIterator upperleft, ImageIterator lowerright, Accessor a, Functor & f) } \endcode use argument objects in conjunction with \ref ArgumentObjectFactories: \code namespace vigra { template void inspectImage(triple img, Functor & f) } \endcode Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code // init functor vigra::BImage img; vigra::FindMinMax minmax; vigra::inspectImage(srcImageRange(img), minmax); cout << "Min: " << minmax.min << " Max: " << minmax.max; \endcode Required Interface: \code ConstImageIterator upperleft, lowerright; ConstImageIterator::row_iterator ix = upperleft.rowIterator(); Accessor accessor; Functor functor; functor(accessor(ix)); // return not used \endcode */ template void inspectImage(ImageIterator upperleft, ImageIterator lowerright, Accessor a, Functor & f) { int w = lowerright.x - upperleft.x; for(; upperleft.y inline void inspectImage(triple img, Functor & f) { inspectImage(img.first, img.second, img.third, f); } namespace functor { template class UnaryAnalyser; } template inline void inspectImage(ImageIterator upperleft, ImageIterator lowerright, Accessor a, functor::UnaryAnalyser const & f) { inspectImage(upperleft, lowerright, a, const_cast &>(f)); } template inline void inspectImage(triple img, functor::UnaryAnalyser const & f) { inspectImage(img.first, img.second, img.third, const_cast &>(f)); } /********************************************************/ /* */ /* inspectImageIf */ /* */ /********************************************************/ /** \brief Apply read-only functor to every pixel in the ROI. This function can be used to collect statistics of the roi etc. The functor is called whenever the return value of the mask's accessor is not zero. The results must be stored in the functor, which serves as a return value. Accessors are used to access the pixel and mask data. Declarations: pass arguments explicitly: \code namespace vigra { template void inspectImageIf(ImageIterator upperleft, ImageIterator lowerright, MaskImageIterator mask_upperleft, MaskAccessor ma, Functor & f) } \endcode use argument objects in conjunction with \ref ArgumentObjectFactories: \code namespace vigra { template void inspectImageIf(triple img, pair mask, Functor & f) } \endcode Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage img(100, 100); vigra::BImage mask(100, 100); // init functor vigra::FindMinMax minmax(); vigra::inspectImageIf(srcImageRange(img), maskImage(mask), minmax); cout << "Min: " << minmax.min << " Max: " << minmax.max; \endcode Required Interface: \code ConstImageIterator upperleft, lowerright; MaskImageIterator mask_upperleft; ConstImageIterator::row_iterator ix = upperleft.rowIterator(); MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator(); Accessor accessor; MaskAccessor mask_accessor; Functor functor; if(mask_accessor(mx)) functor(accessor(ix)); \endcode */ template void inspectImageIf(ImageIterator upperleft, ImageIterator lowerright, Accessor a, MaskImageIterator mask_upperleft, MaskAccessor ma, Functor & f) { int w = lowerright.x - upperleft.x; for(; upperleft.y inline void inspectImageIf(triple img, pair mask, Functor & f) { inspectImageIf(img.first, img.second, img.third, mask.first, mask.second, f); } /********************************************************/ /* */ /* inspectTwoImages */ /* */ /********************************************************/ /** \brief Apply read-only functor to every pixel of both images. This function can be used to collect statistics for each region of a labeled image, especially in conjunction with the \ref ArrayOfRegionStatistics functor. The results must be stored in the functor which serves as a return value. Accessors are used to access the pixel data. Declarations: pass arguments explicitly: \code namespace vigra { template void inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, ImageIterator2 upperleft2, Accessor2 a2, Functor & f) } \endcode use argument objects in conjunction with \ref ArgumentObjectFactories: \code namespace vigra { template void inspectTwoImages(triple img1, pair img2, Functor & f) } \endcode Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage image1; vigra::BImage image2; SomeStatisticsFunctor stats(...); // init functor vigra::inspectTwoImages(srcImageRange(image1), srcImage(image2), stats); \endcode Required Interface: \code ImageIterator1 upperleft1, lowerright1; ImageIterator2 upperleft2; ImageIterator1::row_iterator ix1 = upperleft1.rowIterator(); ImageIterator2::row_iterator ix2 = upperleft2.rowIterator(); Accessor1 accessor1; Accessor2 accessor2; Functor functor; functor(accessor1(ix1), accessor2(ix2)); // return not used \endcode */ template void inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, ImageIterator2 upperleft2, Accessor2 a2, Functor & f) { int w = lowerright1.x - upperleft1.x; for(; upperleft1.y inline void inspectTwoImages(triple img1, pair img2, Functor & f) { inspectTwoImages(img1.first, img1.second, img1.third, img2.first, img2.second, f); } /********************************************************/ /* */ /* inspectTwoImagesIf */ /* */ /********************************************************/ /** \brief Apply read-only functor to those pixels of both images where the mask image is non-zero. This function can be used to collect statistics for selected regions of a labeled image, especially in conjunction with the \ref ArrayOfRegionStatistics functor. The results must be stored in the functor which serves as a return value. Accessors are used to access the pixel data. Declarations: pass arguments explicitly: \code namespace vigra { template void inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, ImageIterator2 upperleft2, Accessor2 a2, MaskImageIterator mupperleft, MaskAccessor mask, Functor & f) } \endcode use argument objects in conjunction with \ref ArgumentObjectFactories: \code namespace vigra { template void inspectTwoImagesIf(triple img1, pair img2, pair mimg, Functor & f) } \endcode Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage image1; vigra::BImage image2; vigra::BImage maskimage; SomeStatisticsFunctor stats(...); // init functor vigra::inspectTwoImagesIf(srcImageRange(image1), srcImage(image2), srcImage(maskimage), region_stats); \endcode Required Interface: \code ImageIterator1 upperleft1, lowerright1; ImageIterator2 upperleft2; MaskImageIterator upperleftm; ImageIterator1::row_iterator ix1 = upperleft1.rowIterator(); ImageIterator2::row_iterator ix2 = upperleft2.rowIterator(); MaskImageIterator::row_iterator mx = mupperleft.rowIterator(); Accessor1 accessor1; Accessor2 accessor2; MaskAccessor mask; Functor functor; if(mask(mx)) functor(accessor1(ix1), accessor2(ix2)); \endcode */ template void inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1, ImageIterator2 upperleft2, Accessor2 a2, MaskImageIterator mupperleft, MaskAccessor mask, Functor & f) { int w = lowerright1.x - upperleft1.x; for(; upperleft1.y inline void inspectTwoImagesIf(triple img1, pair img2, pair m, Functor & f) { inspectTwoImagesIf(img1.first, img1.second, img1.third, img2.first, img2.second, m.first, m.second, f); } //@} /** \addtogroup InspectFunctor Functors To Inspect Images Functors which report image statistics */ //@{ /********************************************************/ /* */ /* FindMinMax */ /* */ /********************************************************/ /** \brief Find the minimum and maximum pixel value in an image or ROI. In addition the size of the ROI is calculated. These functors can also be used in conjunction with \ref ArrayOfRegionStatistics to find the extremes of all regions in a labeled image. Traits defined: FunctorTraits::isUnaryAnalyser is true (VigraTrueType) Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage img; vigra::FindMinMax minmax; // init functor vigra::inspectImage(srcImageRange(img), minmax); cout << "Min: " << minmax.min << " Max: " << minmax.max; \endcode Required Interface: \code VALUETYPE v1, v2(v1); v1 < v2; v1 = v2; \endcode */ template class FindMinMax { public: /** the functor's argument type */ typedef VALUETYPE argument_type; /** the functor's result type */ typedef VALUETYPE result_type; /** \deprecated use argument_type */ typedef VALUETYPE value_type; /** init min and max */ FindMinMax() : count(0) {} /** (re-)init functor (clear min, max) */ void reset() { count = 0; } /** update min and max */ void operator()(argument_type const & v) { if(count) { if(v < min) min = v; if(max < v) max = v; } else { min = v; max = v; } ++count; } /** update min and max with components of RGBValue */ void operator()(RGBValue const & v) { operator()(v.red()); operator()(v.green()); operator()(v.blue()); } /** merge two statistics */ void operator()(FindMinMax const & v) { if(v.count) { if(count) { if(v.min < min) min = v.min; if((this->max) < v.max) max = v.max; } else { min = v.min; max = v.max; } } count += v.count; } /** the current min */ VALUETYPE min; /** the current max */ VALUETYPE max; /** the number of values processed so far */ unsigned int count; }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isUnaryAnalyser; }; /********************************************************/ /* */ /* FindAverage */ /* */ /********************************************************/ /** \brief Find the average pixel value in an image or ROI. In addition the size of the ROI is calculated. This Functor can also be used in conjunction with \ref ArrayOfRegionStatistics to find the average of all regions in a labeled image. Traits defined: FunctorTraits::isUnaryAnalyser and FunctorTraits::isInitializer are true (VigraTrueType) Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage img; vigra::FindAverage average; // init functor vigra::inspectImage(srcImageRange(img), average); cout << "Average: " << average(); \endcode Required Interface: \code VALUETYPE v1, v2(v1); v1 < v2; v1 = v2; \endcode */ template class FindAverage { public: /** the functor's argument type */ typedef VALUETYPE argument_type; /** the functor's result type */ typedef typename NumericTraits::RealPromote result_type; /** \deprecated use argument_type and result_type */ typedef typename NumericTraits::RealPromote value_type; /** init average */ FindAverage() : count(0), sum(NumericTraits::zero()) {} /** (re-)init average */ void reset() { count = 0; sum = NumericTraits::zero(); } /** update average */ void operator()(argument_type const & v) { sum += v; ++count; } /** merge two statistics */ void operator()(FindAverage const & v) { sum += v.sum; count += v.count; } /** return current average */ result_type average() const { return sum / (double)count; } /** return current average */ result_type operator()() const { return sum / (double)count; } unsigned int count; result_type sum; }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isInitializer; typedef VigraTrueType isUnaryAnalyser; }; /********************************************************/ /* */ /* FindROISize */ /* */ /********************************************************/ /** \brief Calculate the size of an ROI in an image. This Functor is often used in conjunction with \ref ArrayOfRegionStatistics to find the sizes of all regions in a labeled image. Traits defined: FunctorTraits::isUnaryAnalyser and FunctorTraits::isInitializer are true (VigraTrueType) Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage img, mask; vigra::FindROISize roisize; // init functor vigra::inspectImageIf(srcImageRange(img), srcImage(mask), roisize); cout << "Size of ROI: " << roisize.count; \endcode */ template class FindROISize { public: /** the functor's argument type */ typedef VALUETYPE argument_type; /** the functor's result type */ typedef unsigned int result_type; /** \deprecated use argument_type and result_type */ typedef VALUETYPE value_type; /** init counter to 0 */ FindROISize() : count(0) {} /** (re-)init ROI size with 0 */ void reset() { count = 0; } /** update counter */ void operator()(argument_type const &) { ++count; } /** return current size */ result_type operator()() const { return count; } /** return current size */ result_type size() const { return count; } /** merge two statistics */ void operator()(FindROISize const & o) { count += o.count; } /** the current counter */ result_type count; }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isInitializer; typedef VigraTrueType isUnaryAnalyser; }; /********************************************************/ /* */ /* FindBoundingRectangle */ /* */ /********************************************************/ /** \brief Calculate the bounding rectangle of an ROI in an image. As always in VIGRA, roiRect.lowerRight is just outside the rectangle. That is, the last pixel actually in the rectangle is roiRect.lowerRight - Diff2D(1,1). This Functor is often used in conjunction with \ref ArrayOfRegionStatistics to find the bounding rectangles of all regions in a labeled image. Traits defined: FunctorTraits::isUnaryAnalyser and FunctorTraits::isInitializer are true (VigraTrueType) Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage img, mask; ... vigra::FindBoundingRectangle roiRect; // init functor // Diff2D is used as the iterator for the source image. This // simulates an image where each pixel value equals that pixel's // coordinates. Tha image 'mask' determines the ROI. vigra::inspectImageIf(srcIterRange(Diff2D(0,0), img.size()), srcImage(mask), roiRect); cout << "Upper left of ROI: " << roiRect.upperLeft.x << ", " << roiRect.upperLeft.y << endl; cout << "Lower right of ROI: " << roiRect.lowerRight.x << ", " << roiRect.lowerRight.y << endl; \endcode */ class FindBoundingRectangle { public: /** the functor's argument type */ typedef Diff2D argument_type; /** the functors result type */ typedef Rect2D result_type; /** \deprecated use argument_type */ typedef Diff2D value_type; /** Upper left of the region as seen so far */ Point2D upperLeft; /** Lower right of the region as seen so far */ Point2D lowerRight; /** are the functors contents valid ? */ bool valid; /** init rectangle to invalid values */ FindBoundingRectangle() : valid(false) {} /** (re-)init functor to find other bounds */ void reset() { valid = false; } /** update rectangle by including the coordinate coord */ void operator()(argument_type const & coord) { if(!valid) { upperLeft = Point2D(coord); lowerRight = Point2D(coord + Diff2D(1,1)); valid = true; } else { upperLeft.x = std::min(upperLeft.x, coord.x); upperLeft.y = std::min(upperLeft.y, coord.y); lowerRight.x = std::max(lowerRight.x, coord.x + 1); lowerRight.y = std::max(lowerRight.y, coord.y + 1); } } /** update rectangle by merging it with another rectangle */ void operator()(FindBoundingRectangle const & otherRegion) { if(!valid) { upperLeft = otherRegion.upperLeft; lowerRight = otherRegion.lowerRight; valid = otherRegion.valid; } else if(otherRegion.valid) { upperLeft.x = std::min(upperLeft.x, otherRegion.upperLeft.x); upperLeft.y = std::min(upperLeft.y, otherRegion.upperLeft.y); lowerRight.x = std::max(lowerRight.x, otherRegion.lowerRight.x); lowerRight.y = std::max(lowerRight.y, otherRegion.lowerRight.y); } } /** Get size of current rectangle. */ Size2D size() const { return lowerRight - upperLeft; } /** Get current rectangle. result_type::first is the upper left corner of the rectangle, result_type::second the lower right. */ result_type operator()() const { return result_type(upperLeft, lowerRight); } }; template <> class FunctorTraits : public FunctorTraitsBase { public: typedef VigraTrueType isInitializer; typedef VigraTrueType isUnaryAnalyser; }; /********************************************************/ /* */ /* LastValueFunctor */ /* */ /********************************************************/ /** \brief Stores and returns the last value it has seen. This Functor is best used in conjunction with \ref ArrayOfRegionStatistics to realize a look-up table. Traits defined: FunctorTraits::isUnaryAnalyser and FunctorTraits::isInitializer are true (VigraTrueType) Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage img; vigra::ArrayOfRegionStatistics > lut(255); for(int i=0; i<256; ++i) { lut[i] = ...; // init look-up table } vigra::transformImage(srcImageRange(img), destImage(img), lut); \endcode */ template class LastValueFunctor { public: /** the functor's argument type */ typedef VALUETYPE argument_type; /** the functor's result type */ typedef VALUETYPE result_type; /** \deprecated use argument_type and result_type */ typedef VALUETYPE value_type; /** default initialization of value */ LastValueFunctor() {} /** replace value */ void operator=(argument_type const & v) { value = v; } /** reset to initia÷ value */ void reset() { value = VALUETYPE(); } /** replace value */ void operator()(argument_type const & v) { value = v; } /** return current value */ result_type const & operator()() const { return value; } /** the current value */ VALUETYPE value; }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isInitializer; typedef VigraTrueType isUnaryAnalyser; }; /********************************************************/ /* */ /* ReduceFunctor */ /* */ /********************************************************/ /** \brief Apply a functor to reduce the dimensionality of an array. This functor can be used to emulate the reduce standard function of functional programming using std::for_each() or inspectImage() and similar functions. This functor is initialized with a functor encoding the expression to be applied, and an accumulator storing the current state of the reduction. For each element of the array, the embedded functor is called with the accumulator and the current element(s) of the array. The result of the reduction is available by calling reduceFunctor(). Traits defined: FunctorTraits::isUnaryAnalyser, FunctorTraits::isBinaryAnalyser and FunctorTraits::isInitializer are true (VigraTrueType) Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage img; ... // fill the image // create a functor to sum the elements of the image vigra::ReduceFunctor, int> sumElements(std::plus, 0); vigra::inspectImage(srcImageRange(img), sumElements); cout << "The sum of the elements " << sumElements() << endl; \endcode Required Interface: \code FUNCTOR f; VALUETYPE accumulator, current1, current2; f(accumulator, current1); // for inspectImage() f(accumulator, current1, current2); // for inspectTwoImages() \endcode */ template class ReduceFunctor { FUNCTOR f_; VALUETYPE start_, accumulator_; public: /** the functor's argument type when used as a unary inspector. (This is not strictly correct since the argument type is actuall a template parameter.) */ typedef VALUETYPE argument_type; /** the functor's first argument type when used as a binary inspector. (This is not strictly correct since the argument type is actuall a template parameter.) */ typedef VALUETYPE first_argument_type; /** the functor's second argument type when used as a binary inspector. (This is not strictly correct since the argument type is actuall a template parameter.) */ typedef VALUETYPE second_argument_type; /** the functor's result type */ typedef VALUETYPE result_type; /** create with the given functor and initial value \a initial for the accumulator. */ ReduceFunctor(FUNCTOR const & f, VALUETYPE const & initial) : f_(f), start_(initial), accumulator_(initial) {} /** Reset accumulator to the initial value. */ void reset() { accumulator_ = start_; } /** Use binary functor to connect given value with the accumulator. The accumulator is used as the first argument, the value \a v as the second. */ template void operator()(T const & v) { accumulator_ = f_(accumulator_, v); } /** Use ternary functor to connect given values with accumulator. The accumulator is used as the first argument, the values \a v1 ans \a v2 as the second and third. */ template void operator()(T1 const & v1, T2 const & v2) { accumulator_ = f_(accumulator_, v1, v2); } /** return current value */ result_type const & operator()() const { return accumulator_; } }; template ReduceFunctor reduceFunctor(FUNCTOR const & f, VALUETYPE const & initial) { return ReduceFunctor(f, initial); } template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isInitializer; typedef VigraTrueType isUnaryAnalyser; typedef VigraTrueType isBinaryAnalyser; }; /********************************************************/ /* */ /* ArrayOfRegionStatistics */ /* */ /********************************************************/ /** \brief Calculate statistics for all regions of a labeled image. This Functor encapsulates an array of statistics functors, one for each label, and selects the one to be updated according to the pixel's label. Traits defined: FunctorTraits::isBinaryAnalyser and FunctorTraits::isUnaryFunctor are true (VigraTrueType) Usage: \#include "vigra/inspectimage.hxx"
Namespace: vigra \code vigra::BImage img; vigra::IImage labels; int max_label; ... // init functor as an array of 'max_label' FindMinMax-Functors vigra::ArrayOfRegionStatistics > minmax(max_label); vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), minmax); for(int i=0; i<= max_label; ++i) { cout << "Max gray lavel of region " << i << ": " << minmax.region[i].max << endl; } // init functor as an array of 'max_label' FindAverage-Functors vigra::ArrayOfRegionStatistics > average(max_label); vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), average); // write back the average of each region into the original image vigra::transformImage(srcImageRange(labels), destImage(img), average); \endcode Required Interface: \code RegionStatistics region; RegionStatistics::argument_type a; RegionStatistics::result_type r; region(a); // update statistics r = region(); // return statistics \endcode */ template class ArrayOfRegionStatistics { typedef std::vector RegionArray; public: /** argument type of the contained statistics object becomes first argument of the analyser */ typedef typename RegionStatistics::argument_type first_argument_type; /** label type is used to determine the region to be updated */ typedef LabelType second_argument_type; /** label type is also used to determine the region to be returned by the 1 argument operator() */ typedef LabelType argument_type; /** result type of the contained statistics object becomes result type of the analyser */ typedef typename RegionStatistics::result_type result_type; /** the value type of the array: the contained statistics object. Note: this definition was different in older VIGRA versions. The old definition was wrong. */ typedef RegionStatistics value_type; /** the array's reference type */ typedef RegionStatistics & reference; /** the array's const reference type */ typedef RegionStatistics const & const_reference; /** type to iterate over the statistics array */ typedef typename RegionArray::iterator iterator; /** type to iterate over a const statistics array */ typedef typename RegionArray::const_iterator const_iterator; /** init array of RegionStatistics with default size 0. */ ArrayOfRegionStatistics() {} /** init array of RegionStatistics with index domain 0...max_region_label. */ ArrayOfRegionStatistics(unsigned int max_region_label) : regions(max_region_label+1) {} /** resize array to new index domain 0...max_region_label. All bin are re-initialized. */ void resize(unsigned int max_region_label) { RegionArray newRegions(max_region_label+1); regions.swap(newRegions); } /** reset the contained functors to their initial state. */ void reset() { RegionArray newRegions(regions.size()); regions.swap(newRegions); } /** update regions statistics for region label. The label type is converted to unsigned int. */ void operator()(first_argument_type const & v, second_argument_type label) { regions[static_cast(label)](v); } /** merge second region into first */ void merge(argument_type label1, argument_type label2) { regions[static_cast(label1)](regions[static_cast(label2)]); } /** ask for maximal index (label) allowed */ unsigned int maxRegionLabel() const { return size() - 1; } /** ask for array size (i.e. maxRegionLabel() + 1) */ unsigned int size() const { return regions.size(); } /** access the statistics for a region via its label. The label type is converted to unsigned int. */ result_type operator()(argument_type label) const { return regions[static_cast(label)](); } /** read the statistics functor for a region via its label */ const_reference operator[](argument_type label) const { return regions[static_cast(label)]; } /** access the statistics functor for a region via its label */ reference operator[](argument_type label) { return regions[static_cast(label)]; } /** iterator to the begin of the region array */ iterator begin() { return regions.begin(); } /** const iterator to the begin of the region array */ const_iterator begin() const { return regions.begin(); } /** iterator to the end of the region array */ iterator end() { return regions.end(); } /** const iterator to the end of the region array */ const_iterator end() const { return regions.end(); } private: std::vector regions; }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isBinaryAnalyser; }; //@} } // namespace vigra #endif // VIGRA_INSPECTIMAGE_HXX