| colorconversions.hxx | | colorconversions.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.0, Sep 10 2004 ) */ | | /* ( Version 1.3.1, Jan 06 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | /* You may use, modify, and distribute this software according */ | |
| /* to the terms stated in the LICENSE file included in */ | | /* to the terms stated in the LICENSE file included in */ | |
| /* the VIGRA distribution. */ | | /* the VIGRA distribution. */ | |
| /* */ | | /* */ | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | |
| | | | |
| skipping to change at line 29 | | skipping to change at line 29 | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_COLORCONVERSIONS_HXX | | #ifndef VIGRA_COLORCONVERSIONS_HXX | |
| #define VIGRA_COLORCONVERSIONS_HXX | | #define VIGRA_COLORCONVERSIONS_HXX | |
| | | | |
| #include <cmath> | | #include <cmath> | |
| #include "vigra/mathutil.hxx" | | #include "vigra/mathutil.hxx" | |
| #include "vigra/rgbvalue.hxx" | | #include "vigra/rgbvalue.hxx" | |
|
| | | #include "vigra/functortraits.hxx" | |
| | | | |
| /** \page ColorConversions Color Space Conversions | | /** \page ColorConversions Color Space Conversions | |
| | | | |
| Convert between RGB, R'G'B', XYZ, L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ,
and Y'UV color spaces. | | Convert between RGB, R'G'B', XYZ, L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ,
and Y'UV color spaces. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| <UL> | | <UL> | |
| <LI> <b>RGB/R'G'B'</b><br> | | <LI> <b>RGB/R'G'B'</b><br> | |
| | | | |
| skipping to change at line 244 | | skipping to change at line 245 | |
| | | | |
| \f[ | | \f[ | |
| R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad | | R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad | |
| G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad | | G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad | |
| B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45} | | B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45} | |
| \f] | | \f] | |
| | | | |
| By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can
be overridden | | By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can
be overridden | |
| in the constructor. If both source and target colors components are sto
red | | in the constructor. If both source and target colors components are sto
red | |
| as <tt>unsigned char</tt>, a look-up-table will be used to speed up the
transformation. | | as <tt>unsigned char</tt>, a look-up-table will be used to speed up the
transformation. | |
|
| */ | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| | | */ | |
| template <class From, class To = From> | | template <class From, class To = From> | |
| class RGB2RGBPrimeFunctor | | class RGB2RGBPrimeFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the functor's argument type | | /** the functor's argument type | |
| */ | | */ | |
| typedef TinyVector<From, 3> argument_type; | | typedef TinyVector<From, 3> argument_type; | |
| | | | |
| /** the functor's result type | | /** the functor's result type | |
| | | | |
| skipping to change at line 327 | | skipping to change at line 332 | |
| } | | } | |
| } | | } | |
| | | | |
| template <class V> | | template <class V> | |
| RGBValue<unsigned char> operator()(V const & rgb) const | | RGBValue<unsigned char> operator()(V const & rgb) const | |
| { | | { | |
| return RGBValue<unsigned char>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb
[2]]); | | return RGBValue<unsigned char>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb
[2]]); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class From, class To> | |
| | | class FunctorTraits<RGB2RGBPrimeFunctor<From, To> > | |
| | | : public FunctorTraitsBase<RGB2RGBPrimeFunctor<From, To> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw
) RGB. | | /** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw
) RGB. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad | | R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad | |
| G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad | | G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad | |
| B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45} | | B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45} | |
| \f] | | \f] | |
| | | | |
| By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can
be overridden | | By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can
be overridden | |
| in the constructor. If both source and target colors components are sto
red | | in the constructor. If both source and target colors components are sto
red | |
| as <tt>unsigned char</tt>, a look-up-table will be used to speed up the
transformation. | | as <tt>unsigned char</tt>, a look-up-table will be used to speed up the
transformation. | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class From, class To = From> | | template <class From, class To = From> | |
| class RGBPrime2RGBFunctor | | class RGBPrime2RGBFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the functor's argument type | | /** the functor's argument type | |
| */ | | */ | |
| typedef TinyVector<From, 3> argument_type; | | typedef TinyVector<From, 3> argument_type; | |
| | | | |
| | | | |
| skipping to change at line 426 | | skipping to change at line 443 | |
| } | | } | |
| } | | } | |
| | | | |
| template <class V> | | template <class V> | |
| RGBValue<unsigned char> operator()(V const & rgb) const | | RGBValue<unsigned char> operator()(V const & rgb) const | |
| { | | { | |
| return RGBValue<unsigned char>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb
[2]]); | | return RGBValue<unsigned char>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb
[2]]); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class From, class To> | |
| | | class FunctorTraits<RGBPrime2RGBFunctor<From, To> > | |
| | | : public FunctorTraitsBase<RGBPrime2RGBFunctor<From, To> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ. | | /** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| According to ITU-R Recommendation BT.709, the functor realizes the tran
sformation | | According to ITU-R Recommendation BT.709, the functor realizes the tran
sformation | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max}
+ 0.180423\enspace B / B_{max}\\ | | X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max}
+ 0.180423\enspace B / B_{max}\\ | |
| Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max}
+ 0.072169\enspace B / B_{max} \\ | | Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max}
+ 0.072169\enspace B / B_{max} \\ | |
| Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max}
+ 0.950227\enspace B / B_{max} | | Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max}
+ 0.950227\enspace B / B_{max} | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
| | | | |
| By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can
be overridden | | By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can
be overridden | |
| in the constructor. X, Y, and Z are always positive and reach their max
imum for white. | | in the constructor. X, Y, and Z are always positive and reach their max
imum for white. | |
| The white point is obtained by transforming RGB(255, 255, 255). It corr
esponds to the | | The white point is obtained by transforming RGB(255, 255, 255). It corr
esponds to the | |
| D65 illuminant. Y represents the <em>luminance</em> ("brightness") of t
he color. | | D65 illuminant. Y represents the <em>luminance</em> ("brightness") of t
he color. | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGB2XYZFunctor | | class RGB2XYZFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the result's component type | | /** the result's component type | |
| */ | | */ | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| | | | |
| skipping to change at line 499 | | skipping to change at line 528 | |
| result[0] = 0.412453*red + 0.357580*green + 0.180423*blue; | | result[0] = 0.412453*red + 0.357580*green + 0.180423*blue; | |
| result[1] = 0.212671*red + 0.715160*green + 0.072169*blue; | | result[1] = 0.212671*red + 0.715160*green + 0.072169*blue; | |
| result[2] = 0.019334*red + 0.119193*green + 0.950227*blue; | | result[2] = 0.019334*red + 0.119193*green + 0.950227*blue; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| component_type max_; | | component_type max_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGB2XYZFunctor<T> > | |
| | | : public FunctorTraitsBase<RGB2XYZFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tr
i-stimulus XYZ. | | /** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tr
i-stimulus XYZ. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| R'G'B' \Rightarrow RGB \Rightarrow XYZ | | R'G'B' \Rightarrow RGB \Rightarrow XYZ | |
| \f] | | \f] | |
| | | | |
| See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a descript
ion of the two | | See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a descript
ion of the two | |
| steps. | | steps. | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGBPrime2XYZFunctor | | class RGBPrime2XYZFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the result's component type | | /** the result's component type | |
| */ | | */ | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| | | | |
| skipping to change at line 566 | | skipping to change at line 607 | |
| result[0] = 0.412453*red + 0.357580*green + 0.180423*blue; | | result[0] = 0.412453*red + 0.357580*green + 0.180423*blue; | |
| result[1] = 0.212671*red + 0.715160*green + 0.072169*blue; | | result[1] = 0.212671*red + 0.715160*green + 0.072169*blue; | |
| result[2] = 0.019334*red + 0.119193*green + 0.950227*blue; | | result[2] = 0.019334*red + 0.119193*green + 0.950227*blue; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| component_type max_, gamma_; | | component_type max_, gamma_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGBPrime2XYZFunctor<T> > | |
| | | : public FunctorTraitsBase<RGBPrime2XYZFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB. | | /** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| According to ITU-R Recommendation BT.709, the functor realizes the tran
sformation | | According to ITU-R Recommendation BT.709, the functor realizes the tran
sformation | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y -
0.4985363262\enspace Z) \\ | | R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y -
0.4985363262\enspace Z) \\ | |
| G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y +
0.0415559266\enspace Z) \\ | | G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y +
0.0415559266\enspace Z) \\ | |
| B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y +
1.0573110696\enspace Z) | | B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y +
1.0573110696\enspace Z) | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
| | | | |
| By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can
be overridden | | By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can
be overridden | |
| in the constructor. This is the inverse transform of vigra::RGB2XYZFunc
tor. | | in the constructor. This is the inverse transform of vigra::RGB2XYZFunc
tor. | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class XYZ2RGBFunctor | | class XYZ2RGBFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| component_type max_; | | component_type max_; | |
| | | | |
| public: | | public: | |
| /** the functor's argument type. (Actually, the argument type | | /** the functor's argument type. (Actually, the argument type | |
| | | | |
| skipping to change at line 634 | | skipping to change at line 687 | |
| { | | { | |
| component_type red = 3.2404813432*xyz[0] - 1.5371515163*xyz[1] -
0.4985363262*xyz[2]; | | component_type red = 3.2404813432*xyz[0] - 1.5371515163*xyz[1] -
0.4985363262*xyz[2]; | |
| component_type green = -0.9692549500*xyz[0] + 1.8759900015*xyz[1] +
0.0415559266*xyz[2]; | | component_type green = -0.9692549500*xyz[0] + 1.8759900015*xyz[1] +
0.0415559266*xyz[2]; | |
| component_type blue = 0.0556466391*xyz[0] - 0.2040413384*xyz[1] +
1.0573110696*xyz[2]; | | component_type blue = 0.0556466391*xyz[0] - 0.2040413384*xyz[1] +
1.0573110696*xyz[2]; | |
| return value_type(NumericTraits<T>::fromRealPromote(red * max_), | | return value_type(NumericTraits<T>::fromRealPromote(red * max_), | |
| NumericTraits<T>::fromRealPromote(green * max_), | | NumericTraits<T>::fromRealPromote(green * max_), | |
| NumericTraits<T>::fromRealPromote(blue * max_)); | | NumericTraits<T>::fromRealPromote(blue * max_)); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<XYZ2RGBFunctor<T> > | |
| | | : public FunctorTraitsBase<XYZ2RGBFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma cor
rected) R'G'B'. | | /** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma cor
rected) R'G'B'. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| XYZ \Rightarrow RGB \Rightarrow R'G'B' | | XYZ \Rightarrow RGB \Rightarrow R'G'B' | |
| \f] | | \f] | |
| | | | |
| See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a descript
ion of the two | | See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a descript
ion of the two | |
| steps. | | steps. | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class XYZ2RGBPrimeFunctor | | class XYZ2RGBPrimeFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| component_type max_, gamma_; | | component_type max_, gamma_; | |
| | | | |
| public: | | public: | |
| | | | |
| | | | |
| skipping to change at line 700 | | skipping to change at line 765 | |
| { | | { | |
| component_type red = 3.2404813432*xyz[0] - 1.5371515163*xyz[1] -
0.4985363262*xyz[2]; | | component_type red = 3.2404813432*xyz[0] - 1.5371515163*xyz[1] -
0.4985363262*xyz[2]; | |
| component_type green = -0.9692549500*xyz[0] + 1.8759900015*xyz[1] +
0.0415559266*xyz[2]; | | component_type green = -0.9692549500*xyz[0] + 1.8759900015*xyz[1] +
0.0415559266*xyz[2]; | |
| component_type blue = 0.0556466391*xyz[0] - 0.2040413384*xyz[1] +
1.0573110696*xyz[2]; | | component_type blue = 0.0556466391*xyz[0] - 0.2040413384*xyz[1] +
1.0573110696*xyz[2]; | |
| return value_type(NumericTraits<T>::fromRealPromote(detail::gammaCo
rrection(red, gamma_) * max_), | | return value_type(NumericTraits<T>::fromRealPromote(detail::gammaCo
rrection(red, gamma_) * max_), | |
| NumericTraits<T>::fromRealPromote(detail::gammaCo
rrection(green, gamma_) * max_), | | NumericTraits<T>::fromRealPromote(detail::gammaCo
rrection(green, gamma_) * max_), | |
| NumericTraits<T>::fromRealPromote(detail::gammaCo
rrection(blue, gamma_) * max_)); | | NumericTraits<T>::fromRealPromote(detail::gammaCo
rrection(blue, gamma_) * max_)); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<XYZ2RGBPrimeFunctor<T> > | |
| | | : public FunctorTraitsBase<XYZ2RGBPrimeFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CI
E L*u*v*. | | /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CI
E L*u*v*. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \
mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\ | | L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \
mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\ | |
| | | | |
| skipping to change at line 726 | | skipping to change at line 799 | |
| & & \\ | | & & \\ | |
| u^{*} & = & 13 L^{*} (u' - u_n'), \quad v^{*} = 13 L^{*} (v' - v_n'
) | | u^{*} & = & 13 L^{*} (u' - u_n'), \quad v^{*} = 13 L^{*} (v' - v_n'
) | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
| | | | |
| where \f$(X_n, Y_n, Z_n)\f$ is the reference white point, and | | where \f$(X_n, Y_n, Z_n)\f$ is the reference white point, and | |
| \f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ ca
lculated for this | | \f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ ca
lculated for this | |
| point. \f$L^{*}\f$ represents the | | point. \f$L^{*}\f$ represents the | |
| <em>lighness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ c
ode the | | <em>lighness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ c
ode the | |
| chromaticity. | | chromaticity. | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class XYZ2LuvFunctor | | class XYZ2LuvFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the result's component type | | /** the result's component type | |
| */ | | */ | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| | | | |
| skipping to change at line 781 | | skipping to change at line 858 | |
| result[1] = 13.0*L*(uprime - 0.197839); | | result[1] = 13.0*L*(uprime - 0.197839); | |
| result[2] = 13.0*L*(vprime - 0.468342); | | result[2] = 13.0*L*(vprime - 0.468342); | |
| } | | } | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| double gamma_; | | double gamma_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<XYZ2LuvFunctor<T> > | |
| | | : public FunctorTraitsBase<XYZ2LuvFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stim
ulus XYZ. | | /** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stim
ulus XYZ. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::XYZ2LuvFunctor | | The functor realizes the inverse of the transformation described in vig
ra::XYZ2LuvFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class Luv2XYZFunctor | | class Luv2XYZFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the result's component type | | /** the result's component type | |
| */ | | */ | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| | | | |
| skipping to change at line 843 | | skipping to change at line 932 | |
| result[0] = 9.0*uprime*result[1] / 4.0 / vprime; | | result[0] = 9.0*uprime*result[1] / 4.0 / vprime; | |
| result[2] = ((9.0 / vprime - 15.0)*result[1] - result[0])/ 3.0; | | result[2] = ((9.0 / vprime - 15.0)*result[1] - result[0])/ 3.0; | |
| } | | } | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| double gamma_; | | double gamma_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<Luv2XYZFunctor<T> > | |
| | | : public FunctorTraitsBase<Luv2XYZFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CI
E L*a*b*. | | /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CI
E L*a*b*. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \
mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\ | | L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \
mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\ | |
| | | | |
| skipping to change at line 865 | | skipping to change at line 962 | |
| & & \\ | | & & \\ | |
| a^{*} & = & 500 \left[ \left( \frac{X}{X_n} \right)^\frac{1}{3} - \
left( \frac{Y}{Y_n} \right)^\frac{1}{3} \right] \\ | | a^{*} & = & 500 \left[ \left( \frac{X}{X_n} \right)^\frac{1}{3} - \
left( \frac{Y}{Y_n} \right)^\frac{1}{3} \right] \\ | |
| & & \\ | | & & \\ | |
| b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \
left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\ | | b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \
left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\ | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
| | | | |
| where \f$(X_n, Y_n, Z_n)\f$ is the reference white point. \f$L^{*}\f$ r
epresents the | | where \f$(X_n, Y_n, Z_n)\f$ is the reference white point. \f$L^{*}\f$ r
epresents the | |
| <em>lighness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ c
ode the | | <em>lighness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ c
ode the | |
| chromaticity. | | chromaticity. | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class XYZ2LabFunctor | | class XYZ2LabFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the result's component type | | /** the result's component type | |
| */ | | */ | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| | | | |
| skipping to change at line 913 | | skipping to change at line 1014 | |
| result[0] = L; | | result[0] = L; | |
| result[1] = 500.0*(xgamma - ygamma); | | result[1] = 500.0*(xgamma - ygamma); | |
| result[2] = 200.0*(ygamma - zgamma); | | result[2] = 200.0*(ygamma - zgamma); | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| double gamma_; | | double gamma_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<XYZ2LabFunctor<T> > | |
| | | : public FunctorTraitsBase<XYZ2LabFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stim
ulus XYZ. | | /** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stim
ulus XYZ. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::XYZ2LabFunctor | | The functor realizes the inverse of the transformation described in vig
ra::XYZ2LabFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class Lab2XYZFunctor | | class Lab2XYZFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the result's component type | | /** the result's component type | |
| */ | | */ | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| | | | |
| skipping to change at line 969 | | skipping to change at line 1082 | |
| result[0] = X; | | result[0] = X; | |
| result[1] = Y; | | result[1] = Y; | |
| result[2] = Z; | | result[2] = Z; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| double gamma_; | | double gamma_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<Lab2XYZFunctor<T> > | |
| | | : public FunctorTraitsBase<Lab2XYZFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*. | | /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| RGB \Rightarrow XYZ \Rightarrow L^*u^*v^* | | RGB \Rightarrow XYZ \Rightarrow L^*u^*v^* | |
| \f] | | \f] | |
| | | | |
| skipping to change at line 990 | | skipping to change at line 1111 | |
| See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description o
f the two | | See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description o
f the two | |
| steps. The resulting color components will have the following bounds: | | steps. The resulting color components will have the following bounds: | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| 0 \leq & L^* & \leq 100 \\ | | 0 \leq & L^* & \leq 100 \\ | |
| -83.077 \leq & u^* & \leq 175.015 \\ | | -83.077 \leq & u^* & \leq 175.015 \\ | |
| -134.101 \leq & v^* & \leq 107.393 | | -134.101 \leq & v^* & \leq 107.393 | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGB2LuvFunctor | | class RGB2LuvFunctor | |
| { | | { | |
| /* | | /* | |
| L in [0, 100] | | L in [0, 100] | |
| u in [-83.077, 175.015] | | u in [-83.077, 175.015] | |
| v in [-134.101, 107.393] | | v in [-134.101, 107.393] | |
| maximum saturation: 179.04 | | maximum saturation: 179.04 | |
| red = [53.2406, 175.015, 37.7522] | | red = [53.2406, 175.015, 37.7522] | |
| | | | |
| skipping to change at line 1046 | | skipping to change at line 1171 | |
| result_type operator()(V const & rgb) const | | result_type operator()(V const & rgb) const | |
| { | | { | |
| return xyz2luv(rgb2xyz(rgb)); | | return xyz2luv(rgb2xyz(rgb)); | |
| } | | } | |
| | | | |
| private: | | private: | |
| RGB2XYZFunctor<T> rgb2xyz; | | RGB2XYZFunctor<T> rgb2xyz; | |
| XYZ2LuvFunctor<component_type> xyz2luv; | | XYZ2LuvFunctor<component_type> xyz2luv; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGB2LuvFunctor<T> > | |
| | | : public FunctorTraitsBase<RGB2LuvFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*. | | /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| RGB \Rightarrow XYZ \Rightarrow L^*a^*b^* | | RGB \Rightarrow XYZ \Rightarrow L^*a^*b^* | |
| \f] | | \f] | |
| | | | |
| skipping to change at line 1067 | | skipping to change at line 1200 | |
| See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description o
f the two | | See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description o
f the two | |
| steps. The resulting color components will have the following bounds: | | steps. The resulting color components will have the following bounds: | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| 0 \leq & L^* & \leq 100 \\ | | 0 \leq & L^* & \leq 100 \\ | |
| -86.1813 \leq & u^* & \leq 98.2352 \\ | | -86.1813 \leq & u^* & \leq 98.2352 \\ | |
| -107.862 \leq & v^* & \leq 94.4758 | | -107.862 \leq & v^* & \leq 94.4758 | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGB2LabFunctor | | class RGB2LabFunctor | |
| { | | { | |
| /* | | /* | |
| L in [0, 100] | | L in [0, 100] | |
| a in [-86.1813, 98.2352] | | a in [-86.1813, 98.2352] | |
| b in [-107.862, 94.4758] | | b in [-107.862, 94.4758] | |
| maximum saturation: 133.809 | | maximum saturation: 133.809 | |
| red = [53.2406, 80.0942, 67.2015] | | red = [53.2406, 80.0942, 67.2015] | |
| | | | |
| skipping to change at line 1123 | | skipping to change at line 1260 | |
| result_type operator()(V const & rgb) const | | result_type operator()(V const & rgb) const | |
| { | | { | |
| return xyz2lab(rgb2xyz(rgb)); | | return xyz2lab(rgb2xyz(rgb)); | |
| } | | } | |
| | | | |
| private: | | private: | |
| RGB2XYZFunctor<T> rgb2xyz; | | RGB2XYZFunctor<T> rgb2xyz; | |
| XYZ2LabFunctor<component_type> xyz2lab; | | XYZ2LabFunctor<component_type> xyz2lab; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGB2LabFunctor<T> > | |
| | | : public FunctorTraitsBase<RGB2LabFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB. | | /** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::RGB2LuvFunctor | | The functor realizes the inverse of the transformation described in vig
ra::RGB2LuvFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class Luv2RGBFunctor | | class Luv2RGBFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| XYZ2RGBFunctor<T> xyz2rgb; | | XYZ2RGBFunctor<T> xyz2rgb; | |
| Luv2XYZFunctor<component_type> luv2xyz; | | Luv2XYZFunctor<component_type> luv2xyz; | |
| | | | |
| public: | | public: | |
| | | | |
| skipping to change at line 1170 | | skipping to change at line 1319 | |
| | | | |
| /** apply the transformation | | /** apply the transformation | |
| */ | | */ | |
| template <class V> | | template <class V> | |
| result_type operator()(V const & luv) const | | result_type operator()(V const & luv) const | |
| { | | { | |
| return xyz2rgb(luv2xyz(luv)); | | return xyz2rgb(luv2xyz(luv)); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<Luv2RGBFunctor<T> > | |
| | | : public FunctorTraitsBase<Luv2RGBFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB. | | /** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::RGB2LabFunctor | | The functor realizes the inverse of the transformation described in vig
ra::RGB2LabFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class Lab2RGBFunctor | | class Lab2RGBFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| XYZ2RGBFunctor<T> xyz2rgb; | | XYZ2RGBFunctor<T> xyz2rgb; | |
| Lab2XYZFunctor<component_type> lab2xyz; | | Lab2XYZFunctor<component_type> lab2xyz; | |
| | | | |
| public: | | public: | |
| | | | |
| skipping to change at line 1224 | | skipping to change at line 1385 | |
| | | | |
| /** apply the transformation | | /** apply the transformation | |
| */ | | */ | |
| template <class V> | | template <class V> | |
| result_type operator()(V const & lab) const | | result_type operator()(V const & lab) const | |
| { | | { | |
| return xyz2rgb(lab2xyz(lab)); | | return xyz2rgb(lab2xyz(lab)); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<Lab2RGBFunctor<T> > | |
| | | : public FunctorTraitsBase<Lab2RGBFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual unif
orm CIE L*u*v*. | | /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual unif
orm CIE L*u*v*. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^* | | R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^* | |
| \f] | | \f] | |
| | | | |
| skipping to change at line 1245 | | skipping to change at line 1414 | |
| See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2Lu
vFunctor for a description of the three | | See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2Lu
vFunctor for a description of the three | |
| steps. The resulting color components will have the following bounds: | | steps. The resulting color components will have the following bounds: | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| 0 \leq & L^* & \leq 100 \\ | | 0 \leq & L^* & \leq 100 \\ | |
| -83.077 \leq & u^* & \leq 175.015 \\ | | -83.077 \leq & u^* & \leq 175.015 \\ | |
| -134.101 \leq & v^* & \leq 107.393 | | -134.101 \leq & v^* & \leq 107.393 | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGBPrime2LuvFunctor | | class RGBPrime2LuvFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the result's component type | | /** the result's component type | |
| */ | | */ | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| | | | |
| skipping to change at line 1294 | | skipping to change at line 1467 | |
| result_type operator()(V const & rgb) const | | result_type operator()(V const & rgb) const | |
| { | | { | |
| return xyz2luv(rgb2xyz(rgb)); | | return xyz2luv(rgb2xyz(rgb)); | |
| } | | } | |
| | | | |
| private: | | private: | |
| RGBPrime2XYZFunctor<T> rgb2xyz; | | RGBPrime2XYZFunctor<T> rgb2xyz; | |
| XYZ2LuvFunctor<component_type> xyz2luv; | | XYZ2LuvFunctor<component_type> xyz2luv; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGBPrime2LuvFunctor<T> > | |
| | | : public FunctorTraitsBase<RGBPrime2LuvFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual unif
orm CIE L*a*b*. | | /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual unif
orm CIE L*a*b*. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the transformation | | The functor realizes the transformation | |
| | | | |
| \f[ | | \f[ | |
| R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^* | | R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^* | |
| \f] | | \f] | |
| | | | |
| skipping to change at line 1315 | | skipping to change at line 1496 | |
| See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2La
bFunctor for a description of the three | | See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2La
bFunctor for a description of the three | |
| steps. The resulting color components will have the following bounds: | | steps. The resulting color components will have the following bounds: | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| 0 \leq & L^* & \leq 100 \\ | | 0 \leq & L^* & \leq 100 \\ | |
| -86.1813 \leq & u^* & \leq 98.2352 \\ | | -86.1813 \leq & u^* & \leq 98.2352 \\ | |
| -107.862 \leq & v^* & \leq 94.4758 | | -107.862 \leq & v^* & \leq 94.4758 | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGBPrime2LabFunctor | | class RGBPrime2LabFunctor | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the result's component type | | /** the result's component type | |
| */ | | */ | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| | | | |
| skipping to change at line 1364 | | skipping to change at line 1549 | |
| result_type operator()(V const & rgb) const | | result_type operator()(V const & rgb) const | |
| { | | { | |
| return xyz2lab(rgb2xyz(rgb)); | | return xyz2lab(rgb2xyz(rgb)); | |
| } | | } | |
| | | | |
| private: | | private: | |
| RGBPrime2XYZFunctor<T> rgb2xyz; | | RGBPrime2XYZFunctor<T> rgb2xyz; | |
| XYZ2LabFunctor<component_type> xyz2lab; | | XYZ2LabFunctor<component_type> xyz2lab; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGBPrime2LabFunctor<T> > | |
| | | : public FunctorTraitsBase<RGBPrime2LabFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma cor
rected) R'G'B'. | | /** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma cor
rected) R'G'B'. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2LuvFunctor | | The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2LuvFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class Luv2RGBPrimeFunctor | | class Luv2RGBPrimeFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| XYZ2RGBPrimeFunctor<T> xyz2rgb; | | XYZ2RGBPrimeFunctor<T> xyz2rgb; | |
| Luv2XYZFunctor<component_type> luv2xyz; | | Luv2XYZFunctor<component_type> luv2xyz; | |
| | | | |
| public: | | public: | |
| | | | |
| skipping to change at line 1418 | | skipping to change at line 1615 | |
| | | | |
| /** apply the transformation | | /** apply the transformation | |
| */ | | */ | |
| template <class V> | | template <class V> | |
| result_type operator()(V const & luv) const | | result_type operator()(V const & luv) const | |
| { | | { | |
| return xyz2rgb(luv2xyz(luv)); | | return xyz2rgb(luv2xyz(luv)); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<Luv2RGBPrimeFunctor<T> > | |
| | | : public FunctorTraitsBase<Luv2RGBPrimeFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma cor
rected) R'G'B'. | | /** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma cor
rected) R'G'B'. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2LabFunctor | | The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2LabFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class Lab2RGBPrimeFunctor | | class Lab2RGBPrimeFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| XYZ2RGBPrimeFunctor<T> xyz2rgb; | | XYZ2RGBPrimeFunctor<T> xyz2rgb; | |
| Lab2XYZFunctor<component_type> lab2xyz; | | Lab2XYZFunctor<component_type> lab2xyz; | |
| | | | |
| public: | | public: | |
| | | | |
| skipping to change at line 1472 | | skipping to change at line 1681 | |
| | | | |
| /** apply the transformation | | /** apply the transformation | |
| */ | | */ | |
| template <class V> | | template <class V> | |
| result_type operator()(V const & lab) const | | result_type operator()(V const & lab) const | |
| { | | { | |
| return xyz2rgb(lab2xyz(lab)); | | return xyz2rgb(lab2xyz(lab)); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<Lab2RGBPrimeFunctor<T> > | |
| | | : public FunctorTraitsBase<Lab2RGBPrimeFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color di
fference components. | | /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color di
fference components. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| According to ITU-R Recommendation BT.601, the functor realizes the tran
sformation | | According to ITU-R Recommendation BT.601, the functor realizes the tran
sformation | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.
114\enspace B / B_{max}\\ | | Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.
114\enspace B / B_{max}\\ | |
| | | | |
| skipping to change at line 1499 | | skipping to change at line 1716 | |
| Pb and Pr are the blue (B'-Y') and red (R'-Y') color difference compone
nts. | | Pb and Pr are the blue (B'-Y') and red (R'-Y') color difference compone
nts. | |
| The transformation is scaled so that the following bounds apply: | | The transformation is scaled so that the following bounds apply: | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| 0 \leq & Y' & \leq 1 \\ | | 0 \leq & Y' & \leq 1 \\ | |
| -0.5 \leq & Pb & \leq 0.5 \\ | | -0.5 \leq & Pb & \leq 0.5 \\ | |
| -0.5 \leq & Pr & \leq 0.5 | | -0.5 \leq & Pr & \leq 0.5 | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGBPrime2YPrimePbPrFunctor | | class RGBPrime2YPrimePbPrFunctor | |
| { | | { | |
| /* | | /* | |
| Y in [0, 1] | | Y in [0, 1] | |
| Pb in [-0.5, 0.5] | | Pb in [-0.5, 0.5] | |
| Pr in [-0.5, 0.5] | | Pr in [-0.5, 0.5] | |
| maximum saturation: 0.533887 | | maximum saturation: 0.533887 | |
| red = [0.299, -0.168736, 0.5] | | red = [0.299, -0.168736, 0.5] | |
| | | | |
| skipping to change at line 1562 | | skipping to change at line 1783 | |
| result[0] = 0.299*red + 0.587*green + 0.114*blue; | | result[0] = 0.299*red + 0.587*green + 0.114*blue; | |
| result[1] = -0.1687358916*red - 0.3312641084*green + 0.5*blue; | | result[1] = -0.1687358916*red - 0.3312641084*green + 0.5*blue; | |
| result[2] = 0.5*red - 0.4186875892*green - 0.0813124108*blue; | | result[2] = 0.5*red - 0.4186875892*green - 0.0813124108*blue; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| component_type max_; | | component_type max_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGBPrime2YPrimePbPrFunctor<T> > | |
| | | : public FunctorTraitsBase<RGBPrime2YPrimePbPrFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert Y'PbPr color difference components into non-linear (gamm
a corrected) R'G'B'. | | /** \brief Convert Y'PbPr color difference components into non-linear (gamm
a corrected) R'G'B'. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2YPrimePbPrFunctor | | The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2YPrimePbPrFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class YPrimePbPr2RGBPrimeFunctor | | class YPrimePbPr2RGBPrimeFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| component_type max_; | | component_type max_; | |
| | | | |
| public: | | public: | |
| | | | |
| | | | |
| skipping to change at line 1620 | | skipping to change at line 1853 | |
| { | | { | |
| component_type nred = ypbpr[0] + 1.402*ypbpr[2]; | | component_type nred = ypbpr[0] + 1.402*ypbpr[2]; | |
| component_type ngreen = ypbpr[0] - 0.3441362862*ypbpr[1] - 0.714136
2862*ypbpr[2]; | | component_type ngreen = ypbpr[0] - 0.3441362862*ypbpr[1] - 0.714136
2862*ypbpr[2]; | |
| component_type nblue = ypbpr[0] + 1.772*ypbpr[1]; | | component_type nblue = ypbpr[0] + 1.772*ypbpr[1]; | |
| return result_type(NumericTraits<T>::fromRealPromote(nred * max_), | | return result_type(NumericTraits<T>::fromRealPromote(nred * max_), | |
| NumericTraits<T>::fromRealPromote(ngreen * max_)
, | | NumericTraits<T>::fromRealPromote(ngreen * max_)
, | |
| NumericTraits<T>::fromRealPromote(nblue * max_))
; | | NumericTraits<T>::fromRealPromote(nblue * max_))
; | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<YPrimePbPr2RGBPrimeFunctor<T> > | |
| | | : public FunctorTraitsBase<YPrimePbPr2RGBPrimeFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components
. | | /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components
. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| According to the PAL analog videa standard, the functor realizes the tr
ansformation | | According to the PAL analog videa standard, the functor realizes the tr
ansformation | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.
114\enspace B / B_{max}\\ | | Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.
114\enspace B / B_{max}\\ | |
| | | | |
| skipping to change at line 1646 | | skipping to change at line 1887 | |
| in the constructor. Y' represents the <em>luminance</em> ("brightness")
of the color. | | in the constructor. Y' represents the <em>luminance</em> ("brightness")
of the color. | |
| The transformation is scaled so that the following bounds apply: | | The transformation is scaled so that the following bounds apply: | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| 0 \leq & Y' & \leq 1 \\ | | 0 \leq & Y' & \leq 1 \\ | |
| -0.596 \leq & I & \leq 0.596 \\ | | -0.596 \leq & I & \leq 0.596 \\ | |
| -0.523 \leq & Q & \leq 0.523 | | -0.523 \leq & Q & \leq 0.523 | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGBPrime2YPrimeIQFunctor | | class RGBPrime2YPrimeIQFunctor | |
| { | | { | |
| /* | | /* | |
| Y in [0, 1] | | Y in [0, 1] | |
| I in [-0.596, 0.596] | | I in [-0.596, 0.596] | |
| Q in [-0.523, 0.523] | | Q in [-0.523, 0.523] | |
| maximum saturation: 0.632582 | | maximum saturation: 0.632582 | |
| red = [0.299, 0.596, 0.212] | | red = [0.299, 0.596, 0.212] | |
| | | | |
| skipping to change at line 1709 | | skipping to change at line 1954 | |
| result[0] = 0.299*red + 0.587*green + 0.114*blue; | | result[0] = 0.299*red + 0.587*green + 0.114*blue; | |
| result[1] = 0.596*red - 0.274*green - 0.322*blue; | | result[1] = 0.596*red - 0.274*green - 0.322*blue; | |
| result[2] = 0.212*red - 0.523*green + 0.311*blue; | | result[2] = 0.212*red - 0.523*green + 0.311*blue; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| component_type max_; | | component_type max_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGBPrime2YPrimeIQFunctor<T> > | |
| | | : public FunctorTraitsBase<RGBPrime2YPrimeIQFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert Y'IQ color components into non-linear (gamma corrected)
R'G'B'. | | /** \brief Convert Y'IQ color components into non-linear (gamma corrected)
R'G'B'. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2YPrimeIQFunctor | | The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2YPrimeIQFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class YPrimeIQ2RGBPrimeFunctor | | class YPrimeIQ2RGBPrimeFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| component_type max_; | | component_type max_; | |
| | | | |
| public: | | public: | |
| | | | |
| | | | |
| skipping to change at line 1767 | | skipping to change at line 2024 | |
| { | | { | |
| component_type nred = yiq[0] + 0.9548892043*yiq[1] + 0.6221039350
*yiq[2]; | | component_type nred = yiq[0] + 0.9548892043*yiq[1] + 0.6221039350
*yiq[2]; | |
| component_type ngreen = yiq[0] - 0.2713547827*yiq[1] - 0.6475120259
*yiq[2]; | | component_type ngreen = yiq[0] - 0.2713547827*yiq[1] - 0.6475120259
*yiq[2]; | |
| component_type nblue = yiq[0] - 1.1072510054*yiq[1] + 1.7024603738
*yiq[2]; | | component_type nblue = yiq[0] - 1.1072510054*yiq[1] + 1.7024603738
*yiq[2]; | |
| return result_type(NumericTraits<T>::fromRealPromote(nred * max_), | | return result_type(NumericTraits<T>::fromRealPromote(nred * max_), | |
| NumericTraits<T>::fromRealPromote(ngreen * max_)
, | | NumericTraits<T>::fromRealPromote(ngreen * max_)
, | |
| NumericTraits<T>::fromRealPromote(nblue * max_))
; | | NumericTraits<T>::fromRealPromote(nblue * max_))
; | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<YPrimeIQ2RGBPrimeFunctor<T> > | |
| | | : public FunctorTraitsBase<YPrimeIQ2RGBPrimeFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components
. | | /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components
. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| According to the NTSC analog videa standard, the functor realizes the t
ransformation | | According to the NTSC analog videa standard, the functor realizes the t
ransformation | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.
114\enspace B / B_{max}\\ | | Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.
114\enspace B / B_{max}\\ | |
| | | | |
| skipping to change at line 1793 | | skipping to change at line 2058 | |
| in the constructor. Y' represents the <em>luminance</em> ("brightness")
of the color. | | in the constructor. Y' represents the <em>luminance</em> ("brightness")
of the color. | |
| The transformation is scaled so that the following bounds apply: | | The transformation is scaled so that the following bounds apply: | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| 0 \leq & Y' & \leq 1 \\ | | 0 \leq & Y' & \leq 1 \\ | |
| -0.436 \leq & U & \leq 0.436 \\ | | -0.436 \leq & U & \leq 0.436 \\ | |
| -0.615 \leq & V & \leq 0.615 | | -0.615 \leq & V & \leq 0.615 | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGBPrime2YPrimeUVFunctor | | class RGBPrime2YPrimeUVFunctor | |
| { | | { | |
| /* | | /* | |
| Y in [0, 1] | | Y in [0, 1] | |
| U in [-0.436, 0.436] | | U in [-0.436, 0.436] | |
| V in [-0.615, 0.615] | | V in [-0.615, 0.615] | |
| maximum saturation: 0.632324 | | maximum saturation: 0.632324 | |
| red = [0.299, -0.147, 0.615] | | red = [0.299, -0.147, 0.615] | |
| | | | |
| skipping to change at line 1856 | | skipping to change at line 2125 | |
| result[0] = 0.299*red + 0.587*green + 0.114*blue; | | result[0] = 0.299*red + 0.587*green + 0.114*blue; | |
| result[1] = -0.1471376975*red - 0.2888623025*green + 0.436*blue; | | result[1] = -0.1471376975*red - 0.2888623025*green + 0.436*blue; | |
| result[2] = 0.6149122807*red - 0.5149122807*green - 0.100*blue; | | result[2] = 0.6149122807*red - 0.5149122807*green - 0.100*blue; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| component_type max_; | | component_type max_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGBPrime2YPrimeUVFunctor<T> > | |
| | | : public FunctorTraitsBase<RGBPrime2YPrimeUVFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert Y'UV color components into non-linear (gamma corrected)
R'G'B'. | | /** \brief Convert Y'UV color components into non-linear (gamma corrected)
R'G'B'. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2YPrimeUVFunctor | | The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2YPrimeUVFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class YPrimeUV2RGBPrimeFunctor | | class YPrimeUV2RGBPrimeFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| component_type max_; | | component_type max_; | |
| | | | |
| public: | | public: | |
| | | | |
| | | | |
| skipping to change at line 1914 | | skipping to change at line 2195 | |
| { | | { | |
| component_type nred = yuv[0] + 1.140*yuv[2]; | | component_type nred = yuv[0] + 1.140*yuv[2]; | |
| component_type ngreen = yuv[0] - 0.3946517044*yuv[1] - 0.580681431*
yuv[2]; | | component_type ngreen = yuv[0] - 0.3946517044*yuv[1] - 0.580681431*
yuv[2]; | |
| component_type nblue = yuv[0] + 2.0321100920*yuv[1]; | | component_type nblue = yuv[0] + 2.0321100920*yuv[1]; | |
| return result_type(NumericTraits<T>::fromRealPromote(nred * max_), | | return result_type(NumericTraits<T>::fromRealPromote(nred * max_), | |
| NumericTraits<T>::fromRealPromote(ngreen * max_)
, | | NumericTraits<T>::fromRealPromote(ngreen * max_)
, | |
| NumericTraits<T>::fromRealPromote(nblue * max_))
; | | NumericTraits<T>::fromRealPromote(nblue * max_))
; | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<YPrimeUV2RGBPrimeFunctor<T> > | |
| | | : public FunctorTraitsBase<YPrimeUV2RGBPrimeFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color di
fference components. | | /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color di
fference components. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| This functor basically applies the same transformation as vigra::RGBPri
me2YPrimePbPrFunctor | | This functor basically applies the same transformation as vigra::RGBPri
me2YPrimePbPrFunctor | |
| but the color components are scaled so that they can be coded as 8 bit
intergers with | | but the color components are scaled so that they can be coded as 8 bit
intergers with | |
| minimal loss of information: | | minimal loss of information: | |
| | | | |
| \f[ | | \f[ | |
| \begin{array}{rcl} | | \begin{array}{rcl} | |
| 16\leq & Y' & \leq 235 \\ | | 16\leq & Y' & \leq 235 \\ | |
| 16 \leq & Cb & \leq 240 \\ | | 16 \leq & Cb & \leq 240 \\ | |
| 16 \leq & Cr & \leq 240 | | 16 \leq & Cr & \leq 240 | |
| \end{array} | | \end{array} | |
| \f] | | \f] | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class RGBPrime2YPrimeCbCrFunctor | | class RGBPrime2YPrimeCbCrFunctor | |
| { | | { | |
| /* | | /* | |
| Y in [16, 235] | | Y in [16, 235] | |
| Cb in [16, 240] | | Cb in [16, 240] | |
| Cr in [16, 240] | | Cr in [16, 240] | |
| maximum saturation: 119.591 | | maximum saturation: 119.591 | |
| red = [81.481, 90.203, 240] | | red = [81.481, 90.203, 240] | |
| | | | |
| skipping to change at line 1993 | | skipping to change at line 2286 | |
| result[0] = 16.0 + 65.481*red + 128.553*green + 24.966*blue; | | result[0] = 16.0 + 65.481*red + 128.553*green + 24.966*blue; | |
| result[1] = 128.0 - 37.79683972*red - 74.20316028*green + 112.0*blu
e; | | result[1] = 128.0 - 37.79683972*red - 74.20316028*green + 112.0*blu
e; | |
| result[2] = 128.0 + 112.0*red - 93.78601998*green - 18.21398002*blu
e; | | result[2] = 128.0 + 112.0*red - 93.78601998*green - 18.21398002*blu
e; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| private: | | private: | |
| component_type max_; | | component_type max_; | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RGBPrime2YPrimeCbCrFunctor<T> > | |
| | | : public FunctorTraitsBase<RGBPrime2YPrimeCbCrFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /** \brief Convert Y'CbCr color difference components into non-linear (gamm
a corrected) R'G'B'. | | /** \brief Convert Y'CbCr color difference components into non-linear (gamm
a corrected) R'G'B'. | |
| | | | |
| <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | | <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col
orconversions.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2YPrimeCbCrFunctor | | The functor realizes the inverse of the transformation described in vig
ra::RGBPrime2YPrimeCbCrFunctor | |
|
| | | | |
| | | <b> Traits defined:</b> | |
| | | | |
| | | <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| class YPrimeCbCr2RGBPrimeFunctor | | class YPrimeCbCr2RGBPrimeFunctor | |
| { | | { | |
| typedef typename NumericTraits<T>::RealPromote component_type; | | typedef typename NumericTraits<T>::RealPromote component_type; | |
| | | | |
| component_type max_; | | component_type max_; | |
| | | | |
| public: | | public: | |
| | | | |
| | | | |
| skipping to change at line 2055 | | skipping to change at line 2360 | |
| | | | |
| component_type nred = 0.00456621*y + 0.006258928571*cr; | | component_type nred = 0.00456621*y + 0.006258928571*cr; | |
| component_type ngreen = 0.00456621*y - 0.001536322706*cb - 0.003188
108420*cr; | | component_type ngreen = 0.00456621*y - 0.001536322706*cb - 0.003188
108420*cr; | |
| component_type nblue = 0.00456621*y + 0.007910714286*cb; | | component_type nblue = 0.00456621*y + 0.007910714286*cb; | |
| return result_type(NumericTraits<T>::fromRealPromote(nred * max_), | | return result_type(NumericTraits<T>::fromRealPromote(nred * max_), | |
| NumericTraits<T>::fromRealPromote(ngreen * max_)
, | | NumericTraits<T>::fromRealPromote(ngreen * max_)
, | |
| NumericTraits<T>::fromRealPromote(nblue * max_))
; | | NumericTraits<T>::fromRealPromote(nblue * max_))
; | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<YPrimeCbCr2RGBPrimeFunctor<T> > | |
| | | : public FunctorTraitsBase<YPrimeCbCr2RGBPrimeFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isUnaryFunctor; | |
| | | }; | |
| | | | |
| /* | | /* | |
| Polar coordinates of standard colors: | | Polar coordinates of standard colors: | |
| ===================================== | | ===================================== | |
| | | | |
| Lab: black = [320.002, 0, 0] | | Lab: black = [320.002, 0, 0] | |
| Luv: black = [347.827, 0, 0] | | Luv: black = [347.827, 0, 0] | |
| YPbPr: black = [341.352, 0, 0] | | YPbPr: black = [341.352, 0, 0] | |
| YCbCr: black = [341.352, 0, 0] | | YCbCr: black = [341.352, 0, 0] | |
| YIQ: black = [19.5807, 0, 0] | | YIQ: black = [19.5807, 0, 0] | |
| YUV: black = [346.557, 0, 0] | | YUV: black = [346.557, 0, 0] | |
| | | | |
End of changes. 54 change blocks. |
| 2 lines changed or deleted | | 315 lines changed or added | |
|
| cornerdetection.hxx | | cornerdetection.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
|
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2004 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.0, Sep 10 2004 ) */ | | /* ( Version 1.3.1, Jan 06 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | /* You may use, modify, and distribute this software according */ | |
| /* to the terms stated in the LICENSE file included in */ | | /* to the terms stated in the LICENSE file included in */ | |
| /* the VIGRA distribution. */ | | /* the VIGRA distribution. */ | |
| /* */ | | /* */ | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | |
| | | | |
| skipping to change at line 31 | | skipping to change at line 31 | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_CORNERDETECTION_HXX | | #ifndef VIGRA_CORNERDETECTION_HXX | |
| #define VIGRA_CORNERDETECTION_HXX | | #define VIGRA_CORNERDETECTION_HXX | |
| | | | |
| #include <vigra/utilities.hxx> | | #include <vigra/utilities.hxx> | |
| #include <vigra/numerictraits.hxx> | | #include <vigra/numerictraits.hxx> | |
| #include <vigra/stdimage.hxx> | | #include <vigra/stdimage.hxx> | |
| #include <vigra/combineimages.hxx> | | #include <vigra/combineimages.hxx> | |
| #include <vigra/convolution.hxx> | | #include <vigra/convolution.hxx> | |
|
| | | #include <vigra/functortraits.hxx> | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
| template <class SrcType> | | template <class SrcType> | |
| struct CornerResponseFunctor | | struct CornerResponseFunctor | |
| { | | { | |
| typedef typename NumericTraits<SrcType>::RealPromote argument_type; | | typedef typename NumericTraits<SrcType>::RealPromote argument_type; | |
| typedef argument_type result_type; | | typedef argument_type result_type; | |
| | | | |
| result_type operator()(argument_type a1, | | result_type operator()(argument_type a1, | |
| argument_type a2, argument_type a3) const | | argument_type a2, argument_type a3) const | |
| { | | { | |
|
| return (a1*a2 - a3*a3) - 0.04 * (a1 + a2) * (a1 + a2); | | return (a1*a2 - a3*a3) - 0.04 * (a1 + a2) * (a1 + a2); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<CornerResponseFunctor<T> > | |
| | | : public FunctorTraitsBase<CornerResponseFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isTernaryFunctor; | |
| | | }; | |
| | | | |
| template <class SrcType> | | template <class SrcType> | |
| struct FoerstnerCornerFunctor | | struct FoerstnerCornerFunctor | |
| { | | { | |
| typedef typename NumericTraits<SrcType>::RealPromote argument_type; | | typedef typename NumericTraits<SrcType>::RealPromote argument_type; | |
| typedef argument_type result_type; | | typedef argument_type result_type; | |
| | | | |
| result_type operator()(argument_type a1, | | result_type operator()(argument_type a1, | |
| argument_type a2, argument_type a3) const | | argument_type a2, argument_type a3) const | |
| { | | { | |
|
| return (a1*a2 - a3*a3) / (a1 + a2); | | return (a1*a2 - a3*a3) / (a1 + a2); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<FoerstnerCornerFunctor<T> > | |
| | | : public FunctorTraitsBase<FoerstnerCornerFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isTernaryFunctor; | |
| | | }; | |
| | | | |
| template <class SrcType> | | template <class SrcType> | |
| struct RohrCornerFunctor | | struct RohrCornerFunctor | |
| { | | { | |
| typedef typename NumericTraits<SrcType>::RealPromote argument_type; | | typedef typename NumericTraits<SrcType>::RealPromote argument_type; | |
| typedef argument_type result_type; | | typedef argument_type result_type; | |
| | | | |
| result_type operator()(argument_type a1, | | result_type operator()(argument_type a1, | |
| argument_type a2, argument_type a3) const | | argument_type a2, argument_type a3) const | |
| { | | { | |
|
| return (a1*a2 - a3*a3); | | return (a1*a2 - a3*a3); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<RohrCornerFunctor<T> > | |
| | | : public FunctorTraitsBase<RohrCornerFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isTernaryFunctor; | |
| | | }; | |
| | | | |
| template <class SrcType> | | template <class SrcType> | |
| struct BeaudetCornerFunctor | | struct BeaudetCornerFunctor | |
| { | | { | |
| typedef typename NumericTraits<SrcType>::RealPromote argument_type; | | typedef typename NumericTraits<SrcType>::RealPromote argument_type; | |
| typedef argument_type result_type; | | typedef argument_type result_type; | |
| | | | |
| result_type operator()(argument_type a1, | | result_type operator()(argument_type a1, | |
| argument_type a2, argument_type a3) const | | argument_type a2, argument_type a3) const | |
| { | | { | |
|
| return (a3*a3 - a1*a2); | | return (a3*a3 - a1*a2); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template <class T> | |
| | | class FunctorTraits<BeaudetCornerFunctor<T> > | |
| | | : public FunctorTraitsBase<BeaudetCornerFunctor<T> > | |
| | | { | |
| | | public: | |
| | | typedef VigraTrueType isTernaryFunctor; | |
| | | }; | |
| | | | |
| /** \addtogroup CornerDetection Corner Detection | | /** \addtogroup CornerDetection Corner Detection | |
| Measure the 'cornerness' at each pixel. | | Measure the 'cornerness' at each pixel. | |
| Note: The Kitchen-Rosenfeld detector is not implemented because of its | | Note: The Kitchen-Rosenfeld detector is not implemented because of its | |
| inferior performance. The SUSAN detector is missing because it's patent
ed. | | inferior performance. The SUSAN detector is missing because it's patent
ed. | |
| */ | | */ | |
| //@{ | | //@{ | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* cornerResponseFunction */ | | /* cornerResponseFunction */ | |
| | | | |
| skipping to change at line 131 | | skipping to change at line 164 | |
| multiplication with itself, multiplication with doubles and | | multiplication with itself, multiplication with doubles and | |
| \ref NumericTraits "NumericTraits" must | | \ref NumericTraits "NumericTraits" must | |
| be defined. | | be defined. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccesso
r as, | | cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccesso
r as, | |
|
| DestIterator dul, DestAccessor ad, | | DestIterator dul, DestAccessor ad, | |
| double scale) | | double scale) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline | | inline | |
| void cornerResponseFunction( | | void cornerResponseFunction( | |
|
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale) | | double scale) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/
cornerdetection.hxx</a>"<br> | | <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/
cornerdetection.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| vigra::BImage src(w,h), corners(w,h); | | vigra::BImage src(w,h), corners(w,h); | |
| | | | |
| skipping to change at line 207 | | skipping to change at line 240 | |
| u = d * u | | u = d * u | |
| | | | |
| dest_accessor.set(u, dest_upperleft); | | dest_accessor.set(u, dest_upperleft); | |
| \endcode | | \endcode | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as, | | cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as, | |
| DestIterator dul, DestAccessor ad, | | DestIterator dul, DestAccessor ad, | |
|
| double scale) | | double scale) | |
| { | | { | |
| vigra_precondition(scale > 0.0, | | vigra_precondition(scale > 0.0, | |
| "cornerResponseFunction(): Scale must be > 0"); | | "cornerResponseFunction(): Scale must be > 0"); | |
| | | | |
| int w = slr.x - sul.x; | | int w = slr.x - sul.x; | |
| int h = slr.y - sul.y; | | int h = slr.y - sul.y; | |
| | | | |
| if(w <= 0 || h <= 0) return; | | if(w <= 0 || h <= 0) return; | |
| | | | |
| typedef typename | | typedef typename | |
| | | | |
| skipping to change at line 240 | | skipping to change at line 273 | |
| | | | |
| combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), | | combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), | |
| destIter(dul, ad), cf ); | | destIter(dul, ad), cf ); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline | | inline | |
| void cornerResponseFunction( | | void cornerResponseFunction( | |
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
|
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale) | | double scale) | |
| { | | { | |
| cornerResponseFunction(src.first, src.second, src.third, | | cornerResponseFunction(src.first, src.second, src.third, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
|
| scale); | | scale); | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* foerstnerCornerDetector */ | | /* foerstnerCornerDetector */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Find corners in an image (2). | | /** \brief Find corners in an image (2). | |
| | | | |
| | | | |
| skipping to change at line 289 | | skipping to change at line 322 | |
| multiplication, and division with itself, multiplication with doubles a
nd | | multiplication, and division with itself, multiplication with doubles a
nd | |
| \ref NumericTraits "NumericTraits" must | | \ref NumericTraits "NumericTraits" must | |
| be defined. | | be defined. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccess
or as, | | foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccess
or as, | |
|
| DestIterator dul, DestAccessor ad, | | DestIterator dul, DestAccessor ad, | |
| double scale) | | double scale) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline | | inline | |
| void foerstnerCornerDetector( | | void foerstnerCornerDetector( | |
|
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale) | | double scale) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/
cornerdetection.hxx</a>"<br> | | <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/
cornerdetection.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| vigra::BImage src(w,h), corners(w,h); | | vigra::BImage src(w,h), corners(w,h); | |
| | | | |
| skipping to change at line 357 | | skipping to change at line 390 | |
| u = d * u | | u = d * u | |
| | | | |
| dest_accessor.set(u, dest_upperleft); | | dest_accessor.set(u, dest_upperleft); | |
| \endcode | | \endcode | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, | | foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, | |
| DestIterator dul, DestAccessor ad, | | DestIterator dul, DestAccessor ad, | |
|
| double scale) | | double scale) | |
| { | | { | |
| vigra_precondition(scale > 0.0, | | vigra_precondition(scale > 0.0, | |
| "foerstnerCornerDetector(): Scale must be > 0"); | | "foerstnerCornerDetector(): Scale must be > 0"); | |
| | | | |
| int w = slr.x - sul.x; | | int w = slr.x - sul.x; | |
| int h = slr.y - sul.y; | | int h = slr.y - sul.y; | |
| | | | |
| if(w <= 0 || h <= 0) return; | | if(w <= 0 || h <= 0) return; | |
| | | | |
| typedef typename | | typedef typename | |
| | | | |
| skipping to change at line 390 | | skipping to change at line 423 | |
| | | | |
| combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), | | combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), | |
| destIter(dul, ad), cf ); | | destIter(dul, ad), cf ); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline | | inline | |
| void foerstnerCornerDetector( | | void foerstnerCornerDetector( | |
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
|
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale) | | double scale) | |
| { | | { | |
| foerstnerCornerDetector(src.first, src.second, src.third, | | foerstnerCornerDetector(src.first, src.second, src.third, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
|
| scale); | | scale); | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* rohrCornerDetector */ | | /* rohrCornerDetector */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Find corners in an image (3). | | /** \brief Find corners in an image (3). | |
| | | | |
| | | | |
| skipping to change at line 437 | | skipping to change at line 470 | |
| multiplication with itself, multiplication with doubles and | | multiplication with itself, multiplication with doubles and | |
| \ref NumericTraits "NumericTraits" must | | \ref NumericTraits "NumericTraits" must | |
| be defined. | | be defined. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as
, | | rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as
, | |
|
| DestIterator dul, DestAccessor ad, | | DestIterator dul, DestAccessor ad, | |
| double scale) | | double scale) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline | | inline | |
| void rohrCornerDetector( | | void rohrCornerDetector( | |
|
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale) | | double scale) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/
cornerdetection.hxx</a>"<br> | | <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/
cornerdetection.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| vigra::BImage src(w,h), corners(w,h); | | vigra::BImage src(w,h), corners(w,h); | |
| | | | |
| skipping to change at line 504 | | skipping to change at line 537 | |
| u = d * u | | u = d * u | |
| | | | |
| dest_accessor.set(u, dest_upperleft); | | dest_accessor.set(u, dest_upperleft); | |
| \endcode | | \endcode | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, | | rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, | |
| DestIterator dul, DestAccessor ad, | | DestIterator dul, DestAccessor ad, | |
|
| double scale) | | double scale) | |
| { | | { | |
| vigra_precondition(scale > 0.0, | | vigra_precondition(scale > 0.0, | |
| "rohrCornerDetector(): Scale must be > 0"); | | "rohrCornerDetector(): Scale must be > 0"); | |
| | | | |
| int w = slr.x - sul.x; | | int w = slr.x - sul.x; | |
| int h = slr.y - sul.y; | | int h = slr.y - sul.y; | |
| | | | |
| if(w <= 0 || h <= 0) return; | | if(w <= 0 || h <= 0) return; | |
| | | | |
| typedef typename | | typedef typename | |
| | | | |
| skipping to change at line 537 | | skipping to change at line 570 | |
| | | | |
| combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), | | combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), | |
| destIter(dul, ad), cf ); | | destIter(dul, ad), cf ); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline | | inline | |
| void rohrCornerDetector( | | void rohrCornerDetector( | |
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
|
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale) | | double scale) | |
| { | | { | |
| rohrCornerDetector(src.first, src.second, src.third, | | rohrCornerDetector(src.first, src.second, src.third, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
|
| scale); | | scale); | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* beaudetCornerDetector */ | | /* beaudetCornerDetector */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Find corners in an image (4). | | /** \brief Find corners in an image (4). | |
| | | | |
| | | | |
| skipping to change at line 573 | | skipping to change at line 606 | |
| multiplication with itself, multiplication with doubles and | | multiplication with itself, multiplication with doubles and | |
| \ref NumericTraits "NumericTraits" must | | \ref NumericTraits "NumericTraits" must | |
| be defined. | | be defined. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor
as, | | beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor
as, | |
|
| DestIterator dul, DestAccessor ad, | | DestIterator dul, DestAccessor ad, | |
| double scale) | | double scale) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline | | inline | |
| void beaudetCornerDetector( | | void beaudetCornerDetector( | |
|
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale) | | double scale) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/
cornerdetection.hxx</a>"<br> | | <b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/
cornerdetection.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| vigra::BImage src(w,h), corners(w,h); | | vigra::BImage src(w,h), corners(w,h); | |
| | | | |
| skipping to change at line 640 | | skipping to change at line 673 | |
| u = d * u | | u = d * u | |
| | | | |
| dest_accessor.set(u, dest_upperleft); | | dest_accessor.set(u, dest_upperleft); | |
| \endcode | | \endcode | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, | | beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, | |
| DestIterator dul, DestAccessor ad, | | DestIterator dul, DestAccessor ad, | |
|
| double scale) | | double scale) | |
| { | | { | |
| vigra_precondition(scale > 0.0, | | vigra_precondition(scale > 0.0, | |
| "beaudetCornerDetector(): Scale must be > 0"); | | "beaudetCornerDetector(): Scale must be > 0"); | |
| | | | |
| int w = slr.x - sul.x; | | int w = slr.x - sul.x; | |
| int h = slr.y - sul.y; | | int h = slr.y - sul.y; | |
| | | | |
| if(w <= 0 || h <= 0) return; | | if(w <= 0 || h <= 0) return; | |
| | | | |
| typedef typename | | typedef typename | |
| | | | |
| skipping to change at line 673 | | skipping to change at line 706 | |
| | | | |
| combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), | | combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), | |
| destIter(dul, ad), cf ); | | destIter(dul, ad), cf ); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline | | inline | |
| void beaudetCornerDetector( | | void beaudetCornerDetector( | |
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
|
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale) | | double scale) | |
| { | | { | |
| beaudetCornerDetector(src.first, src.second, src.third, | | beaudetCornerDetector(src.first, src.second, src.third, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
|
| scale); | | scale); | |
| } | | } | |
| | | | |
| //@} | | //@} | |
| | | | |
| } // namespace vigra | | } // namespace vigra | |
| | | | |
| #endif // VIGRA_CORNERDETECTION_HXX | | #endif // VIGRA_CORNERDETECTION_HXX | |
| | | | |
End of changes. 39 change blocks. |
| 50 lines changed or deleted | | 83 lines changed or added | |
|
| multi_array.hxx | | multi_array.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 2003 by Gunnar Kedenburg */ | | /* Copyright 2003 by Gunnar Kedenburg */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| | | /* ( Version 1.3.1, Jan 06 2005 ) */ | |
| /* ( Version 1.3.0, Sep 10 2004 ) */ | | /* ( Version 1.3.0, Sep 10 2004 ) */ | |
| /* You may use, modify, and distribute this software according */ | | /* You may use, modify, and distribute this software according */ | |
| /* to the terms stated in the LICENSE file included in */ | | /* to the terms stated in the LICENSE file included in */ | |
| /* the VIGRA distribution. */ | | /* the VIGRA distribution. */ | |
| /* */ | | /* */ | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
| | | | |
| skipping to change at line 53 | | skipping to change at line 54 | |
| /* */ | | /* */ | |
| /* defaultStride */ | | /* defaultStride */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /* generates the stride for a gapless shape. | | /* generates the stride for a gapless shape. | |
| | | | |
| Namespace: vigra::detail | | Namespace: vigra::detail | |
| */ | | */ | |
| template <unsigned int N> | | template <unsigned int N> | |
|
| TinyVector <int, N> defaultStride (const TinyVector <int, N> &shape) | | TinyVector <int, N> defaultStride(const TinyVector <int, N> &shape) | |
| { | | { | |
| TinyVector <int, N> ret; | | TinyVector <int, N> ret; | |
| ret [0] = 1; | | ret [0] = 1; | |
| for (unsigned int i = 1; i < N; ++i) | | for (unsigned int i = 1; i < N; ++i) | |
| ret [i] = ret [i-1] * shape [i-1]; | | ret [i] = ret [i-1] * shape [i-1]; | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* MaybeStrided */ | | /* MaybeStrided */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /* metatag implementing a test for marking MultiArrays that were | | /* metatag implementing a test for marking MultiArrays that were | |
| indexed at the zero'th dimension as strided, and all others as | | indexed at the zero'th dimension as strided, and all others as | |
| unstrided. | | unstrided. | |
| | | | |
| <b>\#include</b> | | <b>\#include</b> | |
|
| "<a href="multi_array_8hxx-source.html">vigra/multi_array.hxx</a>" | | "<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" | |
| | | | |
| Namespace: vigra::detail | | Namespace: vigra::detail | |
| */ | | */ | |
| template <unsigned int N> | | template <unsigned int N> | |
| struct MaybeStrided | | struct MaybeStrided | |
| { | | { | |
| typedef UnstridedArrayTag type; | | typedef UnstridedArrayTag type; | |
| }; | | }; | |
| | | | |
| template <> | | template <> | |
| | | | |
| skipping to change at line 99 | | skipping to change at line 100 | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* MultiIteratorChooser */ | | /* MultiIteratorChooser */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /* metatag implementing a test (by pattern matching) for marking | | /* metatag implementing a test (by pattern matching) for marking | |
| MultiArrays that were indexed at the zero'th dimension as strided. | | MultiArrays that were indexed at the zero'th dimension as strided. | |
| | | | |
| <b>\#include</b> | | <b>\#include</b> | |
|
| "<a href="multi_array_8hxx-source.html">vigra/multi_array.hxx</a>" | | "<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" | |
| | | | |
| Namespace: vigra::detail | | Namespace: vigra::detail | |
| */ | | */ | |
| template <class O> | | template <class O> | |
| struct MultiIteratorChooser | | struct MultiIteratorChooser | |
| { | | { | |
| struct Nil {}; | | struct Nil {}; | |
| | | | |
| template <unsigned int N, class T, class REFERENCE, class POINTER> | | template <unsigned int N, class T, class REFERENCE, class POINTER> | |
| struct Traverser | | struct Traverser | |
| | | | |
| skipping to change at line 124 | | skipping to change at line 125 | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* MultiIteratorChooser <StridedArrayTag> */ | | /* MultiIteratorChooser <StridedArrayTag> */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /* specialization of the MultiIteratorChooser for strided arrays. | | /* specialization of the MultiIteratorChooser for strided arrays. | |
| | | | |
| <b>\#include</b> | | <b>\#include</b> | |
|
| "<a href="multi_array_8hxx-source.html">vigra/multi_array.hxx</a>" | | "<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" | |
| | | | |
| Namespace: vigra::detail | | Namespace: vigra::detail | |
| */ | | */ | |
| template <> | | template <> | |
| struct MultiIteratorChooser <StridedArrayTag> | | struct MultiIteratorChooser <StridedArrayTag> | |
| { | | { | |
| template <unsigned int N, class T, class REFERENCE, class POINTER> | | template <unsigned int N, class T, class REFERENCE, class POINTER> | |
| struct Traverser | | struct Traverser | |
| { | | { | |
| typedef StridedMultiIterator <N, T, REFERENCE, POINTER> type; | | typedef StridedMultiIterator <N, T, REFERENCE, POINTER> type; | |
| | | | |
| skipping to change at line 147 | | skipping to change at line 148 | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* MultiIteratorChooser <UnstridedArrayTag> */ | | /* MultiIteratorChooser <UnstridedArrayTag> */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /* specialization of the MultiIteratorChooser for unstrided arrays. | | /* specialization of the MultiIteratorChooser for unstrided arrays. | |
| | | | |
| <b>\#include</b> | | <b>\#include</b> | |
|
| "<a href="multi_array_8hxx-source.html">vigra/multi_array.hxx</a>" | | "<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" | |
| | | | |
| Namespace: vigra::detail | | Namespace: vigra::detail | |
| */ | | */ | |
| template <> | | template <> | |
| struct MultiIteratorChooser <UnstridedArrayTag> | | struct MultiIteratorChooser <UnstridedArrayTag> | |
| { | | { | |
| template <unsigned int N, class T, class REFERENCE, class POINTER> | | template <unsigned int N, class T, class REFERENCE, class POINTER> | |
| struct Traverser | | struct Traverser | |
| { | | { | |
| typedef MultiIterator <N, T, REFERENCE, POINTER> type; | | typedef MultiIterator <N, T, REFERENCE, POINTER> type; | |
| | | | |
| skipping to change at line 177 | | skipping to change at line 178 | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| // forward declaration | | // forward declaration | |
| template <unsigned int N, class T, class C = UnstridedArrayTag> | | template <unsigned int N, class T, class C = UnstridedArrayTag> | |
| class MultiArrayView; | | class MultiArrayView; | |
| template <unsigned int N, class T, class A = std::allocator<T> > | | template <unsigned int N, class T, class A = std::allocator<T> > | |
| class MultiArray; | | class MultiArray; | |
| | | | |
| /** \brief Base class for, and view to, \ref vigra::MultiArray. | | /** \brief Base class for, and view to, \ref vigra::MultiArray. | |
| | | | |
|
| This class implements the interface of both MultiArray and MultiArrayView. | | This class implements the interface of both MultiArray and | |
| By default, MultiArrayViews are tagged as unstrided. I necessary, strided a | | MultiArrayView. By default, MultiArrayViews are tagged as | |
| rrays are | | unstrided. If necessary, strided arrays are constructed automatically | |
| constructed automatically by calls to a variant of the bind...() function. | | by calls to a variant of the bind...() function. | |
| | | | |
|
| If you want to apply an algorithm requiring an image to a <tt>MultiArrayVie | | If you want to apply an algorithm requiring an image to a | |
| w</tt> | | <tt>MultiArrayView</tt> of appropriate (2-dimensional) shape, you can | |
| if appropriate shape, you can create a \ref vigra::BasicImageView | | create a \ref vigra::BasicImageView that acts as a wrapper with the | |
| that acts as a wrapper with the necessary interface -- see | | necessary interface -- see \ref MultiArrayToImage. | |
| \ref MultiArrayToImage. | | | |
| | | The template parameter are as follows | |
| | | \code | |
| | | N: the array dimension | |
| | | | |
| | | T: the type of the array elements | |
| | | | |
| | | C: a tag determining whether the array's inner dimension is strided | |
| | | or not. An array is unstrided if the array elements occupy consecuti | |
| | | ve | |
| | | memory location, strided if there is an offset in between (e.g. | |
| | | when a view is created that skips every other array element). | |
| | | The compiler can generate faster code for unstrided arrays. | |
| | | Possible values: UnstridedArrayTag (default), StridedArrayTag | |
| | | \endcode | |
| | | | |
| <b>\#include</b> | | <b>\#include</b> | |
|
| "<a href="multi_array_8hxx-source.html">vigra/multi_array.hxx</a>" | | "<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
|
| | | | |
| template <unsigned int N, class T, class C> | | template <unsigned int N, class T, class C> | |
| class MultiArrayView | | class MultiArrayView | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the array's actual dimensionality. | | /** the array's actual dimensionality. | |
| This ensures that MultiArrayView can also be used for | | This ensures that MultiArrayView can also be used for | |
| scalars (that is, when <tt>N == 0</tt>). Calculated as:<br> | | scalars (that is, when <tt>N == 0</tt>). Calculated as:<br> | |
| \code | | \code | |
| actual_dimension = (N==0) ? 1 : N | | actual_dimension = (N==0) ? 1 : N | |
| | | | |
| skipping to change at line 409 | | skipping to change at line 424 | |
| if (shape () != nav) | | if (shape () != nav) | |
| (*this) [nav] = rhs [nav]; | | (*this) [nav] = rhs [nav]; | |
| while (inc_navigator (nav)) | | while (inc_navigator (nav)) | |
| (*this) [nav] = rhs [nav]; | | (*this) [nav] = rhs [nav]; | |
| } | | } | |
| #endif /* #if 0 */ | | #endif /* #if 0 */ | |
| | | | |
| #ifndef NO_OUT_OF_LINE_MEMBER_TEMPLATES | | #ifndef NO_OUT_OF_LINE_MEMBER_TEMPLATES | |
| /** bind the M outmost dimensions to certain indices. | | /** bind the M outmost dimensions to certain indices. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
|
| min { 1, N-M } | | max { 1, N-M } | |
| */ | | */ | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-M, T, C> bindOuter (const TinyVector <int, M> &d) con
st; | | MultiArrayView <N-M, T, C> bindOuter (const TinyVector <int, M> &d) con
st; | |
| | | | |
| /** bind the M innermost dimensions to certain indices. | | /** bind the M innermost dimensions to certain indices. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
|
| min { 1, N-M } | | max { 1, N-M } | |
| */ | | */ | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-M, T, StridedArrayTag> | | MultiArrayView <N-M, T, StridedArrayTag> | |
| bindInner (const TinyVector <int, M> &d) const; | | bindInner (const TinyVector <int, M> &d) const; | |
| | | | |
| /** bind dimension M to index d. | | /** bind dimension M to index d. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
|
| min { 1, N-1 } | | max { 1, N-1 } | |
| */ | | */ | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > | | MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > | |
| bind (int d) const; | | bind (int d) const; | |
| #else | | #else | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-M, T, C> bindOuter (const TinyVector <int, M> &d) con
st | | MultiArrayView <N-M, T, C> bindOuter (const TinyVector <int, M> &d) con
st | |
| { | | { | |
| return bindOuterImpl(*this, d); | | return bindOuterImpl(*this, d); | |
| } | | } | |
| | | | |
| skipping to change at line 453 | | skipping to change at line 468 | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > | | MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > | |
| bind (int d) const | | bind (int d) const | |
| { | | { | |
| return bindImpl<M>(*this, d); | | return bindImpl<M>(*this, d); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| /** bind the outmost dimension to a certain index. | | /** bind the outmost dimension to a certain index. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
|
| min { 1, N-1 } | | max { 1, N-1 } | |
| */ | | */ | |
| MultiArrayView <N-1, T, C> bindOuter (int d) const; | | MultiArrayView <N-1, T, C> bindOuter (int d) const; | |
| | | | |
| /** bind the innermost dimension to a certain index. | | /** bind the innermost dimension to a certain index. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
|
| min { 1, N-1 } | | max { 1, N-1 } | |
| */ | | */ | |
| MultiArrayView <N-1, T, StridedArrayTag> bindInner (int d) const; | | MultiArrayView <N-1, T, StridedArrayTag> bindInner (int d) const; | |
| | | | |
| /** bind dimension m to index d. | | /** bind dimension m to index d. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
|
| min { 1, N-1 } | | max { 1, N-1 } | |
| */ | | */ | |
| MultiArrayView <N-1, T, StridedArrayTag> | | MultiArrayView <N-1, T, StridedArrayTag> | |
| bindAt (int m, int d) const; | | bindAt (int m, int d) const; | |
| | | | |
| /** bind dimension m to index d. | | /** bind dimension m to index d. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
|
| min { 1, N-1 } | | max { 1, N-1 } | |
| */ | | */ | |
| MultiArrayView <N-1, T, StridedArrayTag> | | MultiArrayView <N-1, T, StridedArrayTag> | |
| bindRow (int d) const; | | bindRow (int d) const; | |
| | | | |
| /** bind dimension m to index d. | | /** bind dimension m to index d. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
|
| min { 1, N-1 } | | max { 1, N-1 } | |
| */ | | */ | |
| MultiArrayView <N-1, T, C> | | MultiArrayView <N-1, T, C> | |
| bindColumn (int d) const; | | bindColumn (int d) const; | |
| | | | |
| /** create a rectangular subarray that spans between the | | /** create a rectangular subarray that spans between the | |
| points p and q, where p is in the subarray, q not. | | points p and q, where p is in the subarray, q not. | |
| */ | | */ | |
| MultiArrayView subarray (const difference_type &p, | | MultiArrayView subarray (const difference_type &p, | |
| const difference_type &q) const | | const difference_type &q) const | |
| { | | { | |
| | | | |
| skipping to change at line 517 | | skipping to change at line 532 | |
| (shape, m_stride * s, m_ptr); | | (shape, m_stride * s, m_ptr); | |
| } | | } | |
| | | | |
| /** number of the elements in the array. | | /** number of the elements in the array. | |
| */ | | */ | |
| std::size_t elementCount () const | | std::size_t elementCount () const | |
| { | | { | |
| return m_shape [actual_dimension-1] * m_stride [actual_dimension-1]
; | | return m_shape [actual_dimension-1] * m_stride [actual_dimension-1]
; | |
| } | | } | |
| | | | |
|
| /** return the array's size (same as the shape). | | /** return the array's size. | |
| */ | | */ | |
| const size_type & size () const | | const size_type & size () const | |
| { | | { | |
| return m_shape; | | return m_shape; | |
| } | | } | |
| | | | |
|
| /** return the array's shape. | | /** return the array's shape (same as the <tt>size()</tt>). | |
| */ | | */ | |
| const difference_type & shape () const | | const difference_type & shape () const | |
| { | | { | |
| return m_shape; | | return m_shape; | |
| } | | } | |
| | | | |
|
| /** return the array's shape at a certain dimension. | | /** return the array's size at a certain dimension. | |
| | | */ | |
| | | int size (int n) const | |
| | | { | |
| | | return m_shape [n]; | |
| | | } | |
| | | | |
| | | /** return the array's shape at a certain dimension | |
| | | (same as <tt>size(n)</tt>). | |
| */ | | */ | |
| int shape (int n) const | | int shape (int n) const | |
| { | | { | |
| return m_shape [n]; | | return m_shape [n]; | |
| } | | } | |
| | | | |
| /** return the array's stride for every dimension. | | /** return the array's stride for every dimension. | |
| */ | | */ | |
| const difference_type & stride () const | | const difference_type & stride () const | |
| { | | { | |
| | | | |
| skipping to change at line 855 | | skipping to change at line 878 | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* MultiArray */ | | /* MultiArray */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Main <TT>MultiArray</TT> class containing the memory | | /** \brief Main <TT>MultiArray</TT> class containing the memory | |
| management. | | management. | |
| | | | |
|
| This class inherits the interface of MultiArrayView, and implements | | This class inherits the interface of MultiArrayView, and implements | |
| the memory ownership. | | the memory ownership. | |
| MultiArray's are always unstrided, striding them creates a MultiArrayVi | | MultiArray's are always unstrided, striding them creates a MultiArrayView. | |
| ew. | | | |
| | | | |
|
| <b>\#include</b> | | The template parameters are as follows | |
| "<a href="multi_array_8hxx-source.html">vigra/multi_array.hxx</a>" | | \code | |
| | | N: the array dimension | |
| | | | |
|
| Namespace: vigra | | T: the type of the array elements | |
| | | | |
| | | A: the allocator used for internal storage management | |
| | | (default: std::allocator<T>) | |
| | | \endcode | |
| | | | |
| | | <b>\#include</b> | |
| | | "<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" | |
| | | | |
| | | Namespace: vigra | |
| */ | | */ | |
| template <unsigned int N, class T, class A /* default already declared abov
e */> | | template <unsigned int N, class T, class A /* default already declared abov
e */> | |
| class MultiArray : public MultiArrayView <N, T> | | class MultiArray : public MultiArrayView <N, T> | |
| { | | { | |
| | | | |
| public: | | public: | |
| | | | |
| /** the allocator type used to allocate the memory | | /** the allocator type used to allocate the memory | |
| */ | | */ | |
| typedef A allocator_type; | | typedef A allocator_type; | |
| | | | |
| skipping to change at line 1009 | | skipping to change at line 1042 | |
| with the given value.<br> | | with the given value.<br> | |
| <em>Note:</em> this operation invalidates all dependent objects | | <em>Note:</em> this operation invalidates all dependent objects | |
| (array views and iterators) | | (array views and iterators) | |
| */ | | */ | |
| void reshape (const difference_type &shape, const_reference init); | | void reshape (const difference_type &shape, const_reference init); | |
| | | | |
| /** sequential iterator pointing to the first array element. | | /** sequential iterator pointing to the first array element. | |
| */ | | */ | |
| iterator begin () | | iterator begin () | |
| { | | { | |
|
| return data(); | | return this->data(); | |
| } | | } | |
| | | | |
| /** sequential iterator pointing beyond the last array element. | | /** sequential iterator pointing beyond the last array element. | |
| */ | | */ | |
| iterator end () | | iterator end () | |
| { | | { | |
|
| return data() + elementCount(); | | return this->data() + this->elementCount(); | |
| } | | } | |
| | | | |
| /** sequential const iterator pointing to the first array element. | | /** sequential const iterator pointing to the first array element. | |
| */ | | */ | |
| const_iterator begin () const | | const_iterator begin () const | |
| { | | { | |
|
| return data(); | | return this->data(); | |
| } | | } | |
| | | | |
| /** sequential const iterator pointing beyond the last array elemen
t. | | /** sequential const iterator pointing beyond the last array elemen
t. | |
| */ | | */ | |
| const_iterator end () const | | const_iterator end () const | |
| { | | { | |
|
| return data() + elementCount(); | | return this->data() + this->elementCount(); | |
| } | | } | |
| }; | | }; | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray () | | MultiArray <N, T, A>::MultiArray () | |
| : MultiArrayView <N, T> (difference_type (0), difference_type (0), 0) | | : MultiArrayView <N, T> (difference_type (0), difference_type (0), 0) | |
| {} | | {} | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray (allocator_type const & alloc) | | MultiArray <N, T, A>::MultiArray (allocator_type const & alloc) | |
| : MultiArrayView <N, T> (difference_type (0), difference_type (0), 0), | | : MultiArrayView <N, T> (difference_type (0), difference_type (0), 0), | |
| m_alloc(alloc) | | m_alloc(alloc) | |
| {} | | {} | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray (const difference_type &shape, | | MultiArray <N, T, A>::MultiArray (const difference_type &shape, | |
| allocator_type const & alloc) | | allocator_type const & alloc) | |
|
| : MultiArrayView <N, T> (shape, detail::defaultStride <actual_dimension
> (shape), 0), | | : MultiArrayView <N, T> (shape, detail::defaultStride <MultiArrayView<N
,T>::actual_dimension> (shape), 0), | |
| m_alloc(alloc) | | m_alloc(alloc) | |
| { | | { | |
| if (N == 0) | | if (N == 0) | |
| { | | { | |
|
| m_shape [0] = 1; | | this->m_shape [0] = 1; | |
| m_stride [0] = 0; | | this->m_stride [0] = 0; | |
| } | | } | |
|
| allocate (m_ptr, elementCount (), NumericTraits<T>::zero ()); | | allocate (this->m_ptr, this->elementCount (), NumericTraits<T>::zero ()
); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray (const difference_type &shape, | | MultiArray <N, T, A>::MultiArray (const difference_type &shape, | |
| const_reference init, | | const_reference init, | |
| allocator_type const & alloc) | | allocator_type const & alloc) | |
|
| : MultiArrayView <N, T> (shape, detail::defaultStride <actual_dimension
> (shape), 0), | | : MultiArrayView <N, T> (shape, detail::defaultStride <MultiArrayView<N
,T>::actual_dimension> (shape), 0), | |
| m_alloc(alloc) | | m_alloc(alloc) | |
| { | | { | |
| if (N == 0) | | if (N == 0) | |
| { | | { | |
|
| m_shape [0] = 1; | | this->m_shape [0] = 1; | |
| m_stride [0] = 0; | | this->m_stride [0] = 0; | |
| } | | } | |
|
| allocate (m_ptr, elementCount (), init); | | allocate (this->m_ptr, this->elementCount (), init); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray (const difference_type &shape, | | MultiArray <N, T, A>::MultiArray (const difference_type &shape, | |
| const_pointer init, | | const_pointer init, | |
| allocator_type const & alloc) | | allocator_type const & alloc) | |
|
| : MultiArrayView <N, T> (shape, detail::defaultStride <actual_dimension
> (shape), 0), | | : MultiArrayView <N, T> (shape, detail::defaultStride <MultiArrayView<N
,T>::actual_dimension> (shape), 0), | |
| m_alloc(alloc) | | m_alloc(alloc) | |
| { | | { | |
| if (N == 0) | | if (N == 0) | |
| { | | { | |
|
| m_shape [0] = 1; | | this->m_shape [0] = 1; | |
| m_stride [0] = 0; | | this->m_stride [0] = 0; | |
| } | | } | |
|
| allocate (m_ptr, elementCount (), init); | | allocate (this->m_ptr, this->elementCount (), init); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray (const MultiArray &rhs) | | MultiArray <N, T, A>::MultiArray (const MultiArray &rhs) | |
| : MultiArrayView <N, T> (rhs.m_shape, rhs.m_stride, 0), | | : MultiArrayView <N, T> (rhs.m_shape, rhs.m_stride, 0), | |
| m_alloc (rhs.m_alloc) | | m_alloc (rhs.m_alloc) | |
| { | | { | |
|
| allocate (m_ptr, elementCount (), rhs.data ()); | | allocate (this->m_ptr, this->elementCount (), rhs.data ()); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::~MultiArray () | | MultiArray <N, T, A>::~MultiArray () | |
| { | | { | |
|
| deallocate (m_ptr, elementCount ()); | | deallocate (this->m_ptr, this->elementCount ()); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A> & | | MultiArray <N, T, A> & | |
| MultiArray <N, T, A>::operator= (const MultiArray &rhs) | | MultiArray <N, T, A>::operator= (const MultiArray &rhs) | |
| { | | { | |
| if (this == &rhs) | | if (this == &rhs) | |
| return *this; | | return *this; | |
| pointer new_ptr; | | pointer new_ptr; | |
| allocate (new_ptr, rhs.elementCount (), rhs.data ()); | | allocate (new_ptr, rhs.elementCount (), rhs.data ()); | |
|
| deallocate (m_ptr, elementCount ()); | | deallocate (this->m_ptr, this->elementCount ()); | |
| m_alloc = rhs.m_alloc; | | m_alloc = rhs.m_alloc; | |
|
| m_shape = rhs.m_shape; | | this->m_shape = rhs.m_shape; | |
| m_stride = rhs.m_stride; | | this->m_stride = rhs.m_stride; | |
| m_ptr = new_ptr; | | this->m_ptr = new_ptr; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| void MultiArray <N, T, A>::reshape (const difference_type & new_shape, | | void MultiArray <N, T, A>::reshape (const difference_type & new_shape, | |
| const_reference init) | | const_reference init) | |
| { | | { | |
| if (N== 0) | | if (N== 0) | |
| return; | | return; | |
| | | | |
|
| difference_type new_stride = detail::defaultStride <actual_dimension> ( | | difference_type new_stride = detail::defaultStride <MultiArrayView<N,T> | |
| new_shape); | | ::actual_dimension> (new_shape); | |
| std::size_t new_size = new_shape [actual_dimension-1] * new_stride [act | | std::size_t new_size = new_shape [MultiArrayView<N,T>::actual_dimension | |
| ual_dimension-1]; | | -1] * new_stride [MultiArrayView<N,T>::actual_dimension-1]; | |
| T *new_ptr; | | T *new_ptr; | |
| allocate (new_ptr, new_size, init); | | allocate (new_ptr, new_size, init); | |
|
| deallocate (m_ptr, elementCount ()); | | deallocate (this->m_ptr, this->elementCount ()); | |
| m_ptr = new_ptr; | | this->m_ptr = new_ptr; | |
| m_shape = new_shape; | | this->m_shape = new_shape; | |
| m_stride = new_stride; | | this->m_stride = new_stride; | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| void MultiArray <N, T, A>::allocate (pointer & ptr, std::size_t s, | | void MultiArray <N, T, A>::allocate (pointer & ptr, std::size_t s, | |
| const_reference init) | | const_reference init) | |
| { | | { | |
| ptr = m_alloc.allocate (s); | | ptr = m_alloc.allocate (s); | |
| std::size_t i; | | std::size_t i; | |
| try { | | try { | |
| for (i = 0; i < s; ++i) | | for (i = 0; i < s; ++i) | |
| | | | |
End of changes. 43 change blocks. |
| 64 lines changed or deleted | | 95 lines changed or added | |
|
| multi_iterator.hxx | | multi_iterator.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 2003 by Gunnar Kedenburg */ | | /* Copyright 2003 by Gunnar Kedenburg */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| | | /* ( Version 1.3.1, Jan 06 2005 ) */ | |
| /* ( Version 1.3.0, Sep 10 2004 ) */ | | /* ( Version 1.3.0, Sep 10 2004 ) */ | |
| /* You may use, modify, and distribute this software according */ | | /* You may use, modify, and distribute this software according */ | |
| /* to the terms stated in the LICENSE file included in */ | | /* to the terms stated in the LICENSE file included in */ | |
| /* the VIGRA distribution. */ | | /* the VIGRA distribution. */ | |
| /* */ | | /* */ | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
| | | | |
| skipping to change at line 432 | | skipping to change at line 433 | |
| /* */ | | /* */ | |
| /* MultiIteratorBase */ | | /* MultiIteratorBase */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Enclosing class for \ref vigra::MultiIterator base classes. | | /** \brief Enclosing class for \ref vigra::MultiIterator base classes. | |
| | | | |
| This design is necessary for compilers that do not support partial | | This design is necessary for compilers that do not support partial | |
| specialization (otherwise, MultiIterator could be specialized directly). | | specialization (otherwise, MultiIterator could be specialized directly). | |
| | | | |
|
| <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_ite
rator.hxx</a>" | | <b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/multi_it
erator.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <unsigned int N> | | template <unsigned int N> | |
| class MultiIteratorBase | | class MultiIteratorBase | |
| { | | { | |
| public: | | public: | |
| /** \brief Base class for \ref vigra::MultiIterator. | | /** \brief Base class for \ref vigra::MultiIterator. | |
| | | | |
| This class implements the multi-iterator by means of the enclosed t
emplate | | This class implements the multi-iterator by means of the enclosed t
emplate | |
| class <tt>type</tt>. This design is necessary for compilers that do
not support partial | | class <tt>type</tt>. This design is necessary for compilers that do
not support partial | |
| specialization (otherwise, MultiIterator could be specialized direc
tly). | | specialization (otherwise, MultiIterator could be specialized direc
tly). | |
| | | | |
|
| <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/m
ulti_iterator.hxx</a>" | | <b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/
multi_iterator.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <class T, class REFERENCE, class POINTER> | | template <class T, class REFERENCE, class POINTER> | |
| class type : public MultiIterator <N-1, T, REFERENCE, POINTER> | | class type : public MultiIterator <N-1, T, REFERENCE, POINTER> | |
| { | | { | |
| public: | | public: | |
| /** the type of the parent in the inheritance hierarchy. | | /** the type of the parent in the inheritance hierarchy. | |
| */ | | */ | |
| typedef MultiIterator <N-1, T, REFERENCE, POINTER> base_type; | | typedef MultiIterator <N-1, T, REFERENCE, POINTER> base_type; | |
| | | | |
| skipping to change at line 519 | | skipping to change at line 520 | |
| type (pointer ptr, | | type (pointer ptr, | |
| const difference_type *stride, | | const difference_type *stride, | |
| const difference_type *shape) | | const difference_type *shape) | |
| : base_type (ptr, stride, shape) | | : base_type (ptr, stride, shape) | |
| {} | | {} | |
| | | | |
| /** prefix-increment the iterator in it's current dimension | | /** prefix-increment the iterator in it's current dimension | |
| */ | | */ | |
| void operator++ () | | void operator++ () | |
| { | | { | |
|
| m_ptr += m_stride [level]; | | type::m_ptr += type::m_stride [level]; | |
| } | | } | |
| | | | |
| /** prefix-decrement the iterator in it's current dimension | | /** prefix-decrement the iterator in it's current dimension | |
| */ | | */ | |
| void operator-- () | | void operator-- () | |
| { | | { | |
|
| m_ptr -= m_stride [level]; | | type::m_ptr -= type::m_stride [level]; | |
| } | | } | |
| | | | |
| /** postfix-increment the iterator in it's current dimension | | /** postfix-increment the iterator in it's current dimension | |
| */ | | */ | |
| type operator++ (int) | | type operator++ (int) | |
| { | | { | |
| type ret = *this; | | type ret = *this; | |
| ++(*this); | | ++(*this); | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| skipping to change at line 552 | | skipping to change at line 553 | |
| type ret = *this; | | type ret = *this; | |
| --(*this); | | --(*this); | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| /** increment the iterator in it's current dimension | | /** increment the iterator in it's current dimension | |
| by the given value. | | by the given value. | |
| */ | | */ | |
| type & operator+= (difference_type n) | | type & operator+= (difference_type n) | |
| { | | { | |
|
| m_ptr += n * m_stride [level]; | | type::m_ptr += n * type::m_stride [level]; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** increment the iterator in all dimensions | | /** increment the iterator in all dimensions | |
| by the given offset. | | by the given offset. | |
| */ | | */ | |
| type & operator+= (multi_difference_type const & d) | | type & operator+= (multi_difference_type const & d) | |
| { | | { | |
|
| m_ptr += total_stride(d.begin()); | | type::m_ptr += total_stride(d.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** decrement the iterator in it's current dimension | | /** decrement the iterator in it's current dimension | |
| by the given value. | | by the given value. | |
| */ | | */ | |
| type & operator-= (difference_type n) | | type & operator-= (difference_type n) | |
| { | | { | |
|
| m_ptr -= n * m_stride [level]; | | type::m_ptr -= n * type::m_stride [level]; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** decrement the iterator in all dimensions | | /** decrement the iterator in all dimensions | |
| by the given offset. | | by the given offset. | |
| */ | | */ | |
| type & operator-= (multi_difference_type const & d) | | type & operator-= (multi_difference_type const & d) | |
| { | | { | |
|
| m_ptr -= total_stride(d.begin()); | | type::m_ptr -= total_stride(d.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** difference of two iterators in the current dimension. | | /** difference of two iterators in the current dimension. | |
| The result of this operation is undefined if the iterator | | The result of this operation is undefined if the iterator | |
| doesn't point to element 0 in all dimensions below its curr
ent dimension. | | doesn't point to element 0 in all dimensions below its curr
ent dimension. | |
| */ | | */ | |
| difference_type operator- (type const & d) const | | difference_type operator- (type const & d) const | |
| { | | { | |
|
| return (m_ptr - d.m_ptr) / m_stride[level]; | | return (type::m_ptr - d.m_ptr) / type::m_stride[level]; | |
| } | | } | |
| | | | |
| /* operators *, ->, ==, !=, < inherited */ | | /* operators *, ->, ==, !=, < inherited */ | |
| | | | |
| /** access the array element at the given offset in | | /** access the array element at the given offset in | |
| the current dimension. | | the current dimension. | |
| */ | | */ | |
| reference operator[] (difference_type n) const | | reference operator[] (difference_type n) const | |
| { | | { | |
|
| return m_ptr [n* m_stride [level]]; | | return type::m_ptr [n* type::m_stride [level]]; | |
| } | | } | |
| | | | |
| /** access the array element at the given offset. | | /** access the array element at the given offset. | |
| */ | | */ | |
| reference operator[] (multi_difference_type const & d) const | | reference operator[] (multi_difference_type const & d) const | |
| { | | { | |
|
| return m_ptr [total_stride(d.begin())]; | | return type::m_ptr [total_stride(d.begin())]; | |
| } | | } | |
| | | | |
| /** Return the (N-1)-dimensional multi-iterator that points to | | /** Return the (N-1)-dimensional multi-iterator that points to | |
| the first (N-1)-dimensional subarray of the | | the first (N-1)-dimensional subarray of the | |
| N-dimensional array this iterator is referring to. | | N-dimensional array this iterator is referring to. | |
| The result is only valid if this iterator refers to locatio
n | | The result is only valid if this iterator refers to locatio
n | |
| 0 in <em>all</em> dimensions below its current dimension N, | | 0 in <em>all</em> dimensions below its current dimension N, | |
| otherwise it is undefined. Usage: | | otherwise it is undefined. Usage: | |
| | | | |
| \code | | \code | |
| | | | |
| skipping to change at line 642 | | skipping to change at line 643 | |
| /** Return the (N-1)-dimensional multi-iterator that points bey
ond | | /** Return the (N-1)-dimensional multi-iterator that points bey
ond | |
| the last (N-1)-dimensional subarray of the | | the last (N-1)-dimensional subarray of the | |
| N-dimensional array this iterator is referring to. | | N-dimensional array this iterator is referring to. | |
| The result is only valid if this iterator refers to locatio
n | | The result is only valid if this iterator refers to locatio
n | |
| 0 in <em>all</em> dimensions below its current dimension N, | | 0 in <em>all</em> dimensions below its current dimension N, | |
| otherwise it is undefined. | | otherwise it is undefined. | |
| */ | | */ | |
| next_type end () const | | next_type end () const | |
| { | | { | |
| next_type ret = *this; | | next_type ret = *this; | |
|
| ret += m_shape [level-1]; | | ret += type::m_shape [level-1]; | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| /** Get a 1-dimensional, STL-compatible iterator for the | | /** Get a 1-dimensional, STL-compatible iterator for the | |
| given dimension, pointing to the current element of <TT>thi
s</TT>. | | given dimension, pointing to the current element of <TT>thi
s</TT>. | |
| Usage: | | Usage: | |
| | | | |
| \code | | \code | |
| | | | |
| MultiIterator<3, int> outer = ...; // this iterator | | MultiIterator<3, int> outer = ...; // this iterator | |
| | | | |
| skipping to change at line 666 | | skipping to change at line 667 | |
| for(; i != end; ++i) | | for(; i != end; ++i) | |
| { | | { | |
| // go down the current column starting at the location
of 'outer' | | // go down the current column starting at the location
of 'outer' | |
| } | | } | |
| \endcode | | \endcode | |
| */ | | */ | |
| iterator iteratorForDimension(unsigned int d) const | | iterator iteratorForDimension(unsigned int d) const | |
| { | | { | |
| vigra_precondition(d <= level, | | vigra_precondition(d <= level, | |
| "MultiIterator<N>::iteratorForDimension(d): d < N required"
); | | "MultiIterator<N>::iteratorForDimension(d): d < N required"
); | |
|
| return iterator(m_ptr, &m_stride [d], 0); | | return iterator(type::m_ptr, &type::m_stride [d], 0); | |
| } | | } | |
| | | | |
| protected: | | protected: | |
| | | | |
| difference_type | | difference_type | |
| total_stride(typename multi_difference_type::const_iterator d) cons
t | | total_stride(typename multi_difference_type::const_iterator d) cons
t | |
| { | | { | |
|
| return d[level]*m_stride[level] + base_type::total_stride(d); | | return d[level]*type::m_stride[level] + base_type::total_stride
(d); | |
| } | | } | |
| }; | | }; | |
| }; | | }; | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* MultiIteratorBase <2> */ | | /* MultiIteratorBase <2> */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| | | | |
| skipping to change at line 728 | | skipping to change at line 729 | |
| | | | |
| type (pointer ptr, | | type (pointer ptr, | |
| const difference_type *stride, | | const difference_type *stride, | |
| const difference_type *shape) | | const difference_type *shape) | |
| : base_type (ptr, stride, shape), | | : base_type (ptr, stride, shape), | |
| m_stride (stride), m_shape (shape) | | m_stride (stride), m_shape (shape) | |
| {} | | {} | |
| | | | |
| void operator++ () | | void operator++ () | |
| { | | { | |
|
| m_ptr += m_stride [level]; | | type::m_ptr += m_stride [level]; | |
| } | | } | |
| | | | |
| void operator-- () | | void operator-- () | |
| { | | { | |
|
| m_ptr -= m_stride [level]; | | type::m_ptr -= m_stride [level]; | |
| } | | } | |
| | | | |
| type operator++ (int) | | type operator++ (int) | |
| { | | { | |
| type ret = *this; | | type ret = *this; | |
| ++(*this); | | ++(*this); | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| type operator-- (int) | | type operator-- (int) | |
| { | | { | |
| type ret = *this; | | type ret = *this; | |
| --(*this); | | --(*this); | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| type & operator+= (difference_type n) | | type & operator+= (difference_type n) | |
| { | | { | |
|
| m_ptr += n * m_stride [level]; | | type::m_ptr += n * m_stride [level]; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| type & operator+= (multi_difference_type const & d) | | type & operator+= (multi_difference_type const & d) | |
| { | | { | |
|
| m_ptr += total_stride(d.begin()); | | type::m_ptr += total_stride(d.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| type &operator-= (difference_type n) | | type &operator-= (difference_type n) | |
| { | | { | |
|
| m_ptr -= n * m_stride [level]; | | type::m_ptr -= n * m_stride [level]; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| type & operator-= (multi_difference_type const & d) | | type & operator-= (multi_difference_type const & d) | |
| { | | { | |
|
| m_ptr -= total_stride(d.begin()); | | type::m_ptr -= total_stride(d.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| difference_type operator- (type const & d) const | | difference_type operator- (type const & d) const | |
| { | | { | |
|
| return (m_ptr - d.m_ptr) / m_stride[level]; | | return (type::m_ptr - d.m_ptr) / m_stride[level]; | |
| } | | } | |
| | | | |
| reference operator[] (difference_type n) const | | reference operator[] (difference_type n) const | |
| { | | { | |
|
| return m_ptr [n*m_stride [level]]; | | return type::m_ptr [n*m_stride [level]]; | |
| } | | } | |
| | | | |
| reference operator[] (multi_difference_type const & d) const | | reference operator[] (multi_difference_type const & d) const | |
| { | | { | |
|
| return m_ptr [total_stride(d.begin())]; | | return type::m_ptr [total_stride(d.begin())]; | |
| } | | } | |
| | | | |
| next_type begin () const | | next_type begin () const | |
| { | | { | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| next_type end () const | | next_type end () const | |
| { | | { | |
| next_type ret = *this; | | next_type ret = *this; | |
| ret += m_shape [level-1]; | | ret += m_shape [level-1]; | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| iterator iteratorForDimension(unsigned int d) const | | iterator iteratorForDimension(unsigned int d) const | |
| { | | { | |
| vigra_precondition(d <= level, | | vigra_precondition(d <= level, | |
| "MultiIterator<N>::iteratorForDimension(d): d < N required"
); | | "MultiIterator<N>::iteratorForDimension(d): d < N required"
); | |
|
| return iterator(m_ptr, &m_stride [d], 0); | | return iterator(type::m_ptr, &m_stride [d], 0); | |
| } | | } | |
| | | | |
| protected: | | protected: | |
| | | | |
| difference_type | | difference_type | |
| total_stride(typename multi_difference_type::const_iterator d) cons
t | | total_stride(typename multi_difference_type::const_iterator d) cons
t | |
| { | | { | |
| return d[level]*m_stride[level] + base_type::total_stride(d); | | return d[level]*m_stride[level] + base_type::total_stride(d); | |
| } | | } | |
| }; | | }; | |
| | | | |
| skipping to change at line 986 | | skipping to change at line 987 | |
| /* */ | | /* */ | |
| /* MultiIterator */ | | /* MultiIterator */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief A multi-dimensional hierarchical iterator to be used with | | /** \brief A multi-dimensional hierarchical iterator to be used with | |
| \ref vigra::MultiArrayView if it is not strided. | | \ref vigra::MultiArrayView if it is not strided. | |
| | | | |
| This class wraps the MultiIteratorBase in a template of arity two. | | This class wraps the MultiIteratorBase in a template of arity two. | |
| | | | |
|
| <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_ite
rator.hxx</a>" | | <b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/multi_it
erator.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <unsigned int N, class T, class REFERENCE, class POINTER> | | template <unsigned int N, class T, class REFERENCE, class POINTER> | |
| class MultiIterator | | class MultiIterator | |
| : public MultiIteratorBase <N>::template type <T, REFERENCE, POINTER> | | : public MultiIteratorBase <N>::template type <T, REFERENCE, POINTER> | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the type of the parent in the inheritance hierarchy. | | /** the type of the parent in the inheritance hierarchy. | |
| | | | |
| skipping to change at line 1155 | | skipping to change at line 1156 | |
| /* */ | | /* */ | |
| /* StridedMultiIteratorBase */ | | /* StridedMultiIteratorBase */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Encloses the base class for \ref vigra::StridedMultiIterator. | | /** \brief Encloses the base class for \ref vigra::StridedMultiIterator. | |
| | | | |
| This design is necessary for compilers that do not support partial | | This design is necessary for compilers that do not support partial | |
| specialization (otherwise, StridedMultiIterator could be specialized direct
ly). | | specialization (otherwise, StridedMultiIterator could be specialized direct
ly). | |
| | | | |
|
| <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_ite
rator.hxx</a>" | | <b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/multi_it
erator.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <unsigned int N> | | template <unsigned int N> | |
| class StridedMultiIteratorBase | | class StridedMultiIteratorBase | |
| { | | { | |
| public: | | public: | |
| /** \brief Base class for \ref vigra::StridedMultiIterator. | | /** \brief Base class for \ref vigra::StridedMultiIterator. | |
| | | | |
| This class implements the multi-iterator for strided arrays | | This class implements the multi-iterator for strided arrays | |
| by means of the enclosed template | | by means of the enclosed template | |
| class <tt>type</tt>. This design is necessary for compilers that do
not support partial | | class <tt>type</tt>. This design is necessary for compilers that do
not support partial | |
| specialization (otherwise, MultiIterator could be specialized direc
tly). | | specialization (otherwise, MultiIterator could be specialized direc
tly). | |
| | | | |
|
| <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/m
ulti_iterator.hxx</a>" | | <b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/
multi_iterator.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <class T, class REFERENCE, class POINTER> | | template <class T, class REFERENCE, class POINTER> | |
| class type : public StridedMultiIterator <N-1, T, REFERENCE, POINTER> | | class type : public StridedMultiIterator <N-1, T, REFERENCE, POINTER> | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the type of the parent in the inheritance hierarchy. | | /** the type of the parent in the inheritance hierarchy. | |
| */ | | */ | |
| | | | |
| skipping to change at line 1252 | | skipping to change at line 1253 | |
| type (pointer ptr, | | type (pointer ptr, | |
| const difference_type *stride, | | const difference_type *stride, | |
| const difference_type *shape) | | const difference_type *shape) | |
| : base_type (ptr, stride, shape) | | : base_type (ptr, stride, shape) | |
| {} | | {} | |
| | | | |
| /** prefix-increment the iterator in it's current dimension | | /** prefix-increment the iterator in it's current dimension | |
| */ | | */ | |
| void operator++ () | | void operator++ () | |
| { | | { | |
|
| m_ptr += m_stride [level]; | | type::m_ptr += type::m_stride [level]; | |
| } | | } | |
| | | | |
| /** prefix-decrement the iterator in it's current dimension | | /** prefix-decrement the iterator in it's current dimension | |
| */ | | */ | |
| void operator-- () | | void operator-- () | |
| { | | { | |
|
| m_ptr -= m_stride [level]; | | type::m_ptr -= type::m_stride [level]; | |
| } | | } | |
| | | | |
| /** postfix-increment the iterator in it's current dimension | | /** postfix-increment the iterator in it's current dimension | |
| */ | | */ | |
| type operator++ (int) | | type operator++ (int) | |
| { | | { | |
| type ret = *this; | | type ret = *this; | |
| ++(*this); | | ++(*this); | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| skipping to change at line 1285 | | skipping to change at line 1286 | |
| type ret = *this; | | type ret = *this; | |
| --(*this); | | --(*this); | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| /** increment the iterator in it's current dimension | | /** increment the iterator in it's current dimension | |
| by the given value. | | by the given value. | |
| */ | | */ | |
| type &operator+= (difference_type n) | | type &operator+= (difference_type n) | |
| { | | { | |
|
| m_ptr += n * m_stride [level]; | | type::m_ptr += n * type::m_stride [level]; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** increment the iterator in all dimensions | | /** increment the iterator in all dimensions | |
| by the given offset. | | by the given offset. | |
| */ | | */ | |
| type & operator+= (multi_difference_type const & d) | | type & operator+= (multi_difference_type const & d) | |
| { | | { | |
|
| m_ptr += total_stride(d.begin()); | | type::m_ptr += total_stride(d.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** decrement the iterator in it's current dimension | | /** decrement the iterator in it's current dimension | |
| by the given value. | | by the given value. | |
| */ | | */ | |
| type &operator-= (difference_type n) | | type &operator-= (difference_type n) | |
| { | | { | |
|
| m_ptr -= n * m_stride [level]; | | type::m_ptr -= n * type::m_stride [level]; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** decrement the iterator in all dimensions | | /** decrement the iterator in all dimensions | |
| by the given offset. | | by the given offset. | |
| */ | | */ | |
| type & operator-= (multi_difference_type const & d) | | type & operator-= (multi_difference_type const & d) | |
| { | | { | |
|
| m_ptr -= total_stride(d.begin()); | | type::m_ptr -= total_stride(d.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** difference of two iterators in the current dimension. | | /** difference of two iterators in the current dimension. | |
| The result of this operation is undefined if the iterator | | The result of this operation is undefined if the iterator | |
| doesn't point to element 0 in all dimensions below its curr
ent dimension. | | doesn't point to element 0 in all dimensions below its curr
ent dimension. | |
| */ | | */ | |
| difference_type operator- (type const & d) const | | difference_type operator- (type const & d) const | |
| { | | { | |
|
| return (m_ptr - d.m_ptr) / m_stride[level]; | | return (type::m_ptr - d.m_ptr) / type::m_stride[level]; | |
| } | | } | |
| | | | |
| /* operators *, ->, ==, !=, < inherited */ | | /* operators *, ->, ==, !=, < inherited */ | |
| | | | |
| /** access the array element at the given offset | | /** access the array element at the given offset | |
| in the iterator's current dimension. | | in the iterator's current dimension. | |
| */ | | */ | |
| reference operator[] (difference_type n) const | | reference operator[] (difference_type n) const | |
| { | | { | |
|
| return m_ptr [n* m_stride [level]]; | | return type::m_ptr [n* type::m_stride [level]]; | |
| } | | } | |
| | | | |
| /** access the array element at the given offset. | | /** access the array element at the given offset. | |
| */ | | */ | |
| reference operator[] (multi_difference_type const & d) const | | reference operator[] (multi_difference_type const & d) const | |
| { | | { | |
|
| return m_ptr [total_stride(d.begin())]; | | return type::m_ptr [total_stride(d.begin())]; | |
| } | | } | |
| | | | |
| /** Return the (N-1)-dimensional multi-iterator that points to | | /** Return the (N-1)-dimensional multi-iterator that points to | |
| the first (N-1)-dimensional subarray of the | | the first (N-1)-dimensional subarray of the | |
| N-dimensional array this iterator is referring to. | | N-dimensional array this iterator is referring to. | |
| The result is only valid if this iterator refers to locatio
n | | The result is only valid if this iterator refers to locatio
n | |
| 0 in <em>all</em> dimensions below its current dimension N, | | 0 in <em>all</em> dimensions below its current dimension N, | |
| otherwise it is undefined. Usage: | | otherwise it is undefined. Usage: | |
| | | | |
| \code | | \code | |
| | | | |
| skipping to change at line 1375 | | skipping to change at line 1376 | |
| /** Return the (N-1)-dimensional multi-iterator that points bey
ond | | /** Return the (N-1)-dimensional multi-iterator that points bey
ond | |
| the last (N-1)-dimensional subarray of the | | the last (N-1)-dimensional subarray of the | |
| N-dimensional array this iterator is referring to. | | N-dimensional array this iterator is referring to. | |
| The result is only valid if this iterator refers to locatio
n | | The result is only valid if this iterator refers to locatio
n | |
| 0 in <em>all</em> dimensions below its current dimension N, | | 0 in <em>all</em> dimensions below its current dimension N, | |
| otherwise it is undefined. Usage: | | otherwise it is undefined. Usage: | |
| */ | | */ | |
| next_type end () const | | next_type end () const | |
| { | | { | |
| next_type ret = *this; | | next_type ret = *this; | |
|
| ret += m_shape [level-1]; | | ret += type::m_shape [level-1]; | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| /** Get a 1-dimensional, STL-compatible iterator for the | | /** Get a 1-dimensional, STL-compatible iterator for the | |
| given dimension, pointing to the current element of <TT>thi
s</TT>. | | given dimension, pointing to the current element of <TT>thi
s</TT>. | |
| Usage: | | Usage: | |
| | | | |
| \code | | \code | |
| | | | |
| StridedMultiIterator<3, int> outer = ...; // this iterator | | StridedMultiIterator<3, int> outer = ...; // this iterator | |
| | | | |
| skipping to change at line 1399 | | skipping to change at line 1400 | |
| for(; i != end; ++i) | | for(; i != end; ++i) | |
| { | | { | |
| // go down the current column starting at the location
of 'outer' | | // go down the current column starting at the location
of 'outer' | |
| } | | } | |
| \endcode | | \endcode | |
| */ | | */ | |
| iterator iteratorForDimension(unsigned int d) const | | iterator iteratorForDimension(unsigned int d) const | |
| { | | { | |
| vigra_precondition(d <= N, | | vigra_precondition(d <= N, | |
| "StridedMultiIterator<N>::iteratorForDimension(d): d <= N r
equired"); | | "StridedMultiIterator<N>::iteratorForDimension(d): d <= N r
equired"); | |
|
| return iterator(m_ptr, &m_stride [d], 0); | | return iterator(type::m_ptr, &type::m_stride [d], 0); | |
| } | | } | |
| | | | |
| protected: | | protected: | |
| | | | |
| difference_type | | difference_type | |
| total_stride(typename multi_difference_type::const_iterator d) cons
t | | total_stride(typename multi_difference_type::const_iterator d) cons
t | |
| { | | { | |
|
| return d[level]*m_stride[level] + base_type::total_stride(d); | | return d[level]*type::m_stride[level] + base_type::total_stride
(d); | |
| } | | } | |
| }; | | }; | |
| }; | | }; | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* StridedMultiIteratorBase <2> */ | | /* StridedMultiIteratorBase <2> */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| | | | |
| skipping to change at line 1459 | | skipping to change at line 1460 | |
| | | | |
| type (pointer ptr, | | type (pointer ptr, | |
| const difference_type *stride, | | const difference_type *stride, | |
| const difference_type *shape) | | const difference_type *shape) | |
| : base_type (ptr, stride, shape), | | : base_type (ptr, stride, shape), | |
| m_stride (stride), m_shape (shape) | | m_stride (stride), m_shape (shape) | |
| {} | | {} | |
| | | | |
| void operator++ () | | void operator++ () | |
| { | | { | |
|
| m_ptr += m_stride [level]; | | type::m_ptr += m_stride [level]; | |
| } | | } | |
| | | | |
| void operator-- () | | void operator-- () | |
| { | | { | |
|
| m_ptr -= m_stride [level]; | | type::m_ptr -= m_stride [level]; | |
| } | | } | |
| | | | |
| type operator++ (int) | | type operator++ (int) | |
| { | | { | |
| type ret = *this; | | type ret = *this; | |
| ++(*this); | | ++(*this); | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| type operator-- (int) | | type operator-- (int) | |
| { | | { | |
| type ret = *this; | | type ret = *this; | |
| --(*this); | | --(*this); | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| type &operator+= (int n) | | type &operator+= (int n) | |
| { | | { | |
|
| m_ptr += n * m_stride [level]; | | type::m_ptr += n * m_stride [level]; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| type & operator+= (multi_difference_type const & d) | | type & operator+= (multi_difference_type const & d) | |
| { | | { | |
|
| m_ptr += total_stride(d.begin()); | | type::m_ptr += total_stride(d.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| type &operator-= (difference_type n) | | type &operator-= (difference_type n) | |
| { | | { | |
|
| m_ptr -= n * m_stride [level]; | | type::m_ptr -= n * m_stride [level]; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| type & operator-= (multi_difference_type const & d) | | type & operator-= (multi_difference_type const & d) | |
| { | | { | |
|
| m_ptr -= total_stride(d.begin()); | | type::m_ptr -= total_stride(d.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| reference operator[] (difference_type n) const | | reference operator[] (difference_type n) const | |
| { | | { | |
|
| return m_ptr [n*m_stride [level]]; | | return type::m_ptr [n*m_stride [level]]; | |
| } | | } | |
| | | | |
| difference_type operator- (type const & d) const | | difference_type operator- (type const & d) const | |
| { | | { | |
|
| return (m_ptr - d.m_ptr) / m_stride[level]; | | return (type::m_ptr - d.m_ptr) / m_stride[level]; | |
| } | | } | |
| | | | |
| reference operator[] (multi_difference_type const & d) const | | reference operator[] (multi_difference_type const & d) const | |
| { | | { | |
|
| return m_ptr [total_stride(d.begin())]; | | return type::m_ptr [total_stride(d.begin())]; | |
| } | | } | |
| | | | |
| next_type begin () const | | next_type begin () const | |
| { | | { | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| next_type end () const | | next_type end () const | |
| { | | { | |
| next_type ret = *this; | | next_type ret = *this; | |
| ret += m_shape [level-1]; | | ret += m_shape [level-1]; | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| iterator iteratorForDimension(unsigned int d) const | | iterator iteratorForDimension(unsigned int d) const | |
| { | | { | |
|
| vigra_precondition(d <= N, | | vigra_precondition(d <= type::N, | |
| "StridedMultiIterator<N>::iteratorForDimension(d): d <= N r
equired"); | | "StridedMultiIterator<N>::iteratorForDimension(d): d <= N r
equired"); | |
|
| return iterator(m_ptr, &m_stride [d], 0); | | return iterator(type::m_ptr, &m_stride [d], 0); | |
| } | | } | |
| | | | |
| protected: | | protected: | |
| | | | |
| difference_type | | difference_type | |
| total_stride(typename multi_difference_type::const_iterator d) cons
t | | total_stride(typename multi_difference_type::const_iterator d) cons
t | |
| { | | { | |
| return d[level]*m_stride[level] + base_type::total_stride(d); | | return d[level]*m_stride[level] + base_type::total_stride(d); | |
| } | | } | |
| }; | | }; | |
| | | | |
| skipping to change at line 1718 | | skipping to change at line 1719 | |
| /* */ | | /* */ | |
| /* StridedMultiIterator */ | | /* StridedMultiIterator */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief A multi-dimensional hierarchical iterator to be used with | | /** \brief A multi-dimensional hierarchical iterator to be used with | |
| \ref vigra::MultiArrayView is it is strided. | | \ref vigra::MultiArrayView is it is strided. | |
| | | | |
| This class wraps the StridedMultiIteratorBase in a template of arity two. | | This class wraps the StridedMultiIteratorBase in a template of arity two. | |
| | | | |
|
| <b>\#include</b> "<a href="multi_iterator_8hxx-source.html">vigra/multi_ite
rator.hxx</a>" | | <b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/multi_it
erator.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <unsigned int N, class T, class REFERENCE, class POINTER> | | template <unsigned int N, class T, class REFERENCE, class POINTER> | |
| class StridedMultiIterator | | class StridedMultiIterator | |
| : public StridedMultiIteratorBase <N>::template type <T, REFERENCE, POI
NTER> | | : public StridedMultiIteratorBase <N>::template type <T, REFERENCE, POI
NTER> | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** the type of the parent in the inheritance hierarchy. | | /** the type of the parent in the inheritance hierarchy. | |
| | | | |
End of changes. 52 change blocks. |
| 51 lines changed or deleted | | 52 lines changed or added | |
|
| multi_pointoperators.hxx | | multi_pointoperators.hxx | |
| //-- -*- c++ -*- | | //-- -*- c++ -*- | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
|
| /* Copyright 2003 by Christian-Dennis Rahn */ | | /* Copyright 2003 by Ullrich Koethe */ | |
| /* and Ullrich Koethe */ | | | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.0, Sep 10 2004 ) */ | | /* ( Version 1.3.1, Jan 06 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | /* You may use, modify, and distribute this software according */ | |
| /* to the terms stated in the LICENSE file included in */ | | /* to the terms stated in the LICENSE file included in */ | |
| /* the VIGRA distribution. */ | | /* the VIGRA distribution. */ | |
| /* */ | | /* */ | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | |
| | | | |
| skipping to change at line 46 | | skipping to change at line 45 | |
| namespace vigra | | namespace vigra | |
| { | | { | |
| | | | |
| /** \addtogroup MultiPointoperators Point operators for multi-dimensional a
rrays. | | /** \addtogroup MultiPointoperators Point operators for multi-dimensional a
rrays. | |
| | | | |
| Copy, transform, and inspect arbitrary dimensional arrays which are rep
resented | | Copy, transform, and inspect arbitrary dimensional arrays which are rep
resented | |
| by iterators compatible to \ref MultiIteratorPage. Note that are range
is here | | by iterators compatible to \ref MultiIteratorPage. Note that are range
is here | |
| specified by a pair: an iterator referring to the first point of the ar
ray | | specified by a pair: an iterator referring to the first point of the ar
ray | |
| and a shape object specifying the size of the (rectangular) ROI. | | and a shape object specifying the size of the (rectangular) ROI. | |
| | | | |
|
| <b>\#include</b> "<a href="multi_pointoperators_8hxx-source.html">vigra
/multi_pointoperators.hxx</a>" | | <b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr
a/multi_pointoperators.hxx</a>" | |
| */ | | */ | |
| //@{ | | //@{ | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* initMultiArray */ | | /* initMultiArray */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| template <class Iterator, class Shape, class Accessor, | | template <class Iterator, class Shape, class Accessor, | |
| | | | |
| skipping to change at line 94 | | skipping to change at line 93 | |
| of the \ref vigra::MultiIterator design). | | of the \ref vigra::MultiIterator design). | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class Iterator, class Shape, class Accessor, class VALUET
YPE> | | template <class Iterator, class Shape, class Accessor, class VALUET
YPE> | |
| void | | void | |
| initMultiArray(Iterator s, Shape const & shape, Accessor a, VALUET
YPE v); | | initMultiArray(Iterator s, Shape const & shape, Accessor a, VALUET
YPE v); | |
|
| | | | |
| | | template <class Iterator, class Shape, class Accessor, class FUNCTO | |
| | | R> | |
| | | void | |
| | | initMultiArray(Iterator s, Shape const & shape, Accessor a, FUNCTO | |
| | | R const & f); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class Iterator, class Shape, class Accessor, class VALUET
YPE> | | template <class Iterator, class Shape, class Accessor, class VALUET
YPE> | |
| void | | void | |
| initMultiArray(triple<Iterator, Shape, Accessor> const & s, VALUETY
PE v); | | initMultiArray(triple<Iterator, Shape, Accessor> const & s, VALUETY
PE v); | |
|
| | | | |
| | | template <class Iterator, class Shape, class Accessor, class FUNCTO | |
| | | R> | |
| | | void | |
| | | initMultiArray(triple<Iterator, Shape, Accessor> const & s, FUNCTOR | |
| | | const & f); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
|
| <b>\#include</b> "<a href="multi_pointoperators_8hxx-source.html">vigra
/multi_pointoperators.hxx</a>"br> | | <b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr
a/multi_pointoperators.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| typedef vigra::MultiArray<3, int> Array; | | typedef vigra::MultiArray<3, int> Array; | |
| Array array(Array::size_type(100, 200, 50)); | | Array array(Array::size_type(100, 200, 50)); | |
| | | | |
| // zero the array | | // zero the array | |
| vigra::initMultiArray(destMultiArrayRange(array), 0); | | vigra::initMultiArray(destMultiArrayRange(array), 0); | |
| \endcode | | \endcode | |
| | | | |
| <b> Required Interface:</b> | | <b> Required Interface:</b> | |
| | | | |
|
| | | The function accepts either a value that is copied into every destinati | |
| | | on element: | |
| | | | |
| \code | | \code | |
| MultiIterator begin; | | MultiIterator begin; | |
| | | | |
| Accessor accessor; | | Accessor accessor; | |
| VALUETYPE v; | | VALUETYPE v; | |
| | | | |
| accessor.set(v, begin); | | accessor.set(v, begin); | |
| \endcode | | \endcode | |
| | | | |
|
| | | or a functor that is called (without argument) at every location, | |
| | | and the result is written into the current element. Internally, | |
| | | functors are recognized by the meta function | |
| | | <tt>FunctorTraits<FUNCTOR>::</tt><tt>isInitializer</tt> yielding | |
| | | <tt>VigraTrueType</tt>. | |
| | | Make sure that your functor correctly defines <tt>FunctorTrits</tt> bec | |
| | | ause | |
| | | otherwise the code will not compile. | |
| | | | |
| | | \code | |
| | | MultiIterator begin; | |
| | | Accessor accessor; | |
| | | | |
| | | FUNCTOR f; | |
| | | assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru | |
| | | eType)); | |
| | | | |
| | | accessor.set(f(), begin); | |
| | | \endcode | |
| | | | |
| */ | | */ | |
| template <class Iterator, class Shape, class Accessor, class VALUETYPE> | | template <class Iterator, class Shape, class Accessor, class VALUETYPE> | |
| inline void | | inline void | |
| initMultiArray(Iterator s, Shape const & shape, Accessor a, VALUETYPE v) | | initMultiArray(Iterator s, Shape const & shape, Accessor a, VALUETYPE v) | |
| { | | { | |
| initMultiArrayImpl(s, shape, a, v, MetaInt<Iterator::level>()); | | initMultiArrayImpl(s, shape, a, v, MetaInt<Iterator::level>()); | |
| } | | } | |
| | | | |
| template <class Iterator, class Shape, class Accessor, class VALUETYPE> | | template <class Iterator, class Shape, class Accessor, class VALUETYPE> | |
| inline | | inline | |
| | | | |
| skipping to change at line 153 | | skipping to change at line 179 | |
| initMultiArray(s.first, s.second, s.third, v); | | initMultiArray(s.first, s.second, s.third, v); | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* copyMultiArray */ | | /* copyMultiArray */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor> | | class DestIterator, class DestShape, class DestAccessor> | |
| inline void | | void | |
| copyMultiArrayImpl(SrcIterator s, SrcShape const & shape, SrcAccessor src, | | copyMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src, | |
| DestIterator d, DestAccessor dest, MetaInt<0>) | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | MetaInt<0>) | |
| { | | { | |
|
| copyLine(s, s + shape[0], src, d, dest); | | if(sshape[0] == 1) | |
| | | { | |
| | | initLine(d, d + dshape[0], dest, src(s)); | |
| | | } | |
| | | else | |
| | | { | |
| | | copyLine(s, s + sshape[0], src, d, dest); | |
| | | } | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, int N> | | class DestIterator, class DestShape, class DestAccessor, int N> | |
| void | | void | |
|
| copyMultiArrayImpl(SrcIterator s, SrcShape const & shape, SrcAccessor src, | | copyMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src, | |
| DestIterator d, DestAccessor dest, MetaInt<N>) | | DestIterator d, DestShape const & dshape, DestAccessor d | |
| | | est, MetaInt<N>) | |
| { | | { | |
|
| SrcIterator send = s + shape[N]; | | DestIterator dend = d + dshape[N]; | |
| for(; s != send; ++s, ++d) | | if(sshape[N] == 1) | |
| { | | { | |
|
| copyMultiArrayImpl(s.begin(), shape, src, d.begin(), dest, MetaInt< | | for(; d != dend; ++d) | |
| N-1>()); | | { | |
| | | copyMultiArrayImpl(s.begin(), sshape, src, d.begin(), dshape, d | |
| | | est, MetaInt<N-1>()); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | for(; d != dend; ++s, ++d) | |
| | | { | |
| | | copyMultiArrayImpl(s.begin(), sshape, src, d.begin(), dshape, d | |
| | | est, MetaInt<N-1>()); | |
| | | } | |
| } | | } | |
| } | | } | |
| | | | |
| /** \brief Copy a multi-dimensional array. | | /** \brief Copy a multi-dimensional array. | |
| | | | |
|
| If necessary, type conversion takes place. The arrays must be represent | | This function can be applied in two modes: | |
| ed by | | | |
| iterators compatible with \ref vigra::MultiIterator. | | <DL> | |
| The function uses accessors to access the data elements. Note that the | | <DT><b>Standard Mode:</b> | |
| iterator range | | <DD>If the source and destination arrays have the same size, | |
| must be specified by a shape object, because otherwise we could not con | | the corresponding array elements are simply copied. | |
| trol | | If necessary, type conversion takes place. | |
| the range simultaneously in all dimensions (this is a necessary consequ | | <DT><b>Expanding Mode:</b> | |
| ence | | <DD>If the source array has length 1 along some (or even all) dimen | |
| of the \ref vigra::MultiIterator design). | | sions, | |
| | | the source value at index 0 is used for all destination | |
| | | elements in those dimensions. For example, if we have single row of | |
| | | data | |
| | | (column length is 1), we can copy it into a 2D image of the same wi | |
| | | dth: | |
| | | The given row is automatically repeated for every row of the destin | |
| | | ation image. | |
| | | Again, type conversion os performed if necessary. | |
| | | </DL> | |
| | | | |
| | | The arrays must be represented by | |
| | | iterators compatible with \ref vigra::MultiIterator, and the iteration | |
| | | range | |
| | | is specified by means of shape objects. If only the source shape is giv | |
| | | en | |
| | | the destination array is assumed to have the same shape, and standard m | |
| | | ode | |
| | | is applied. If two shapes are given, the size of corresponding dimensio | |
| | | ns | |
| | | must be either equal (standard copy), or the source length must be 1 | |
| | | (expanding copy). The function uses accessors to access the data elemen | |
| | | ts. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
|
| | | <b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr | |
| | | a/multi_pointoperators.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| copyMultiArray(SrcIterator s, | | copyMultiArray(SrcIterator s, | |
| SrcShape const & shape, SrcAccessor src, | | SrcShape const & shape, SrcAccessor src, | |
| DestIterator d, DestAccessor dest); | | DestIterator d, DestAccessor dest); | |
|
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor> | |
| | | void | |
| | | copyMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor | |
| | | src, | |
| | | DestIterator d, DestShape const & dshape, DestAccess | |
| | | or dest); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| void | | void | |
| copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & s
rc, | | copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & s
rc, | |
| pair<DestIterator, DestAccessor> const & dest); | | pair<DestIterator, DestAccessor> const & dest); | |
|
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor> | |
| | | void | |
| | | copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & s | |
| | | rc, | |
| | | triple<DestIterator, DestShape, DestAccessor> const | |
| | | & dest); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
|
| <b> Usage:</b> | | <b> Usage - Standard Mode:</b> | |
| | | | |
| <b>\#include</b> "<a href="multi_pointoperators_8hxx-source.html">vigra | | | |
| /multi_pointoperators.hxx</a>"br> | | | |
| Namespace: vigra | | | |
| | | | |
| \code | | \code | |
| typedef vigra::MultiArray<3, int> Array; | | typedef vigra::MultiArray<3, int> Array; | |
| Array src(Array::size_type(100, 200, 50)), | | Array src(Array::size_type(100, 200, 50)), | |
| dest(Array::size_type(100, 200, 50)); | | dest(Array::size_type(100, 200, 50)); | |
| ... | | ... | |
| | | | |
| vigra::copyMultiArray(srcMultiArrayRange(src), destMultiArray(dest)); | | vigra::copyMultiArray(srcMultiArrayRange(src), destMultiArray(dest)); | |
| \endcode | | \endcode | |
| | | | |
|
| | | <b> Usage - Expanding Mode:</b> | |
| | | | |
| | | The source array is only 2D (it has depth 1). Thus, the destination | |
| | | will contain 50 identical copies of this image. Note that the destinati | |
| | | on shape | |
| | | must be passed to the algorithm for the expansion to work, so we use | |
| | | <tt>destMultiArrayRange()</tt> rather than <tt>destMultiArray()</tt>. | |
| | | | |
| | | \code | |
| | | typedef vigra::MultiArray<3, int> Array; | |
| | | Array src(Array::size_type(100, 200, 1)), | |
| | | dest(Array::size_type(100, 200, 50)); | |
| | | ... | |
| | | | |
| | | vigra::copyMultiArray(srcMultiArrayRange(src), destMultiArrayRange(dest | |
| | | )); | |
| | | \endcode | |
| | | | |
| <b> Required Interface:</b> | | <b> Required Interface:</b> | |
| | | | |
| \code | | \code | |
| MultiIterator src_begin, dest_begin; | | MultiIterator src_begin, dest_begin; | |
| | | | |
| SrcAccessor src_accessor; | | SrcAccessor src_accessor; | |
| DestAccessor dest_accessor; | | DestAccessor dest_accessor; | |
| | | | |
| dest_accessor.set(src_accessor(src_begin), dest_begin); | | dest_accessor.set(src_accessor(src_begin), dest_begin); | |
| | | | |
| \endcode | | \endcode | |
| | | | |
| */ | | */ | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| copyMultiArray(SrcIterator s, | | copyMultiArray(SrcIterator s, | |
| SrcShape const & shape, SrcAccessor src, | | SrcShape const & shape, SrcAccessor src, | |
| DestIterator d, DestAccessor dest) | | DestIterator d, DestAccessor dest) | |
| { | | { | |
|
| copyMultiArrayImpl(s, shape, src, d, dest, MetaInt<SrcIterator::level>(
)); | | copyMultiArrayImpl(s, shape, src, d, shape, dest, MetaInt<SrcIterator::
level>()); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src, | | copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src, | |
| pair<DestIterator, DestAccessor> const & dest) | | pair<DestIterator, DestAccessor> const & dest) | |
| { | | { | |
| | | | |
| copyMultiArray(src.first, src.second, src.third, dest.first, dest.secon
d); | | copyMultiArray(src.first, src.second, src.third, dest.first, dest.secon
d); | |
| } | | } | |
| | | | |
|
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor> | |
| | | void | |
| | | copyMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor src, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest) | |
| | | { | |
| | | vigra_precondition(sshape.size() == dshape.size(), | |
| | | "copyMultiArray(): dimensionality of source and destination array d | |
| | | iffer"); | |
| | | for(unsigned int i=0; i<sshape.size(); ++i) | |
| | | vigra_precondition(sshape[i] == 1 || sshape[i] == dshape[i], | |
| | | "copyMultiArray(): mismatch between source and destination shap | |
| | | es:\n" | |
| | | "length of each source dimension must either be 1 or equal to t | |
| | | he corresponding " | |
| | | "destination length."); | |
| | | copyMultiArrayImpl(s, sshape, src, d, dshape, dest, MetaInt<SrcIterator | |
| | | ::level>()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor> | |
| | | inline void | |
| | | copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src, | |
| | | triple<DestIterator, DestShape, DestAccessor> const & dest) | |
| | | { | |
| | | | |
| | | copyMultiArray(src.first, src.second, src.third, dest.first, dest.secon | |
| | | d, dest.third); | |
| | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* transformMultiArray */ | | /* transformMultiArray */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, class Functor> | | class DestIterator, class DestShape, class DestAccessor, | |
| inline void | | class Functor> | |
| transformMultiArrayImpl(SrcIterator s, SrcShape const & shape, SrcAccessor | | void | |
| src, | | transformMultiArrayReduceImpl(SrcIterator s, SrcShape const & sshape, SrcAc | |
| DestIterator d, DestAccessor dest, Functor const & f, MetaIn | | cessor src, | |
| t<0>) | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | SrcShape const & reduceShape, | |
| | | Functor const & ff, MetaInt<0>) | |
| { | | { | |
|
| transformLine(s, s + shape[0], src, d, dest, f); | | DestIterator dend = d + dshape[0]; | |
| | | for(; d != dend; ++s.template dim<0>(), ++d) | |
| | | { | |
| | | Functor f = ff; | |
| | | inspectMultiArray(s, reduceShape, src, f); | |
| | | dest.set(f(), d); | |
| | | } | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, class Functor, int N> | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor, int N> | |
| void | | void | |
|
| transformMultiArrayImpl(SrcIterator s, SrcShape const & shape, SrcAccessor | | transformMultiArrayReduceImpl(SrcIterator s, SrcShape const & sshape, SrcAc | |
| src, | | cessor src, | |
| DestIterator d, DestAccessor dest, | | DestIterator d, DestShape const & dshape, DestAccessor d | |
| | | est, | |
| | | SrcShape const & reduceShape, | |
| Functor const & f, MetaInt<N>) | | Functor const & f, MetaInt<N>) | |
| { | | { | |
|
| SrcIterator send = s + shape[N]; | | DestIterator dend = d + dshape[N]; | |
| for(; s != send; ++s, ++d) | | for(; d != dend; ++s.template dim<N>(), ++d) | |
| { | | { | |
|
| transformMultiArrayImpl(s.begin(), shape, src, d.begin(), dest, | | transformMultiArrayReduceImpl(s, sshape, src, d.begin(), dshape, de | |
| f, MetaInt<N-1>()); | | st, | |
| | | reduceShape, f, MetaInt<N-1>()); | |
| } | | } | |
| } | | } | |
| | | | |
|
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | transformMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor | |
| | | src, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f, VigraTrueType) | |
| | | { | |
| | | // reduce mode | |
| | | SrcShape reduceShape = sshape; | |
| | | for(unsigned int i=0; i<dshape.size(); ++i) | |
| | | { | |
| | | vigra_precondition(dshape[i] == 1 || sshape[i] == dshape[i], | |
| | | "transformMultiArray(): mismatch between source and destination | |
| | | shapes:\n" | |
| | | "In 'reduce'-mode, the length of each destination dimension mus | |
| | | t either be 1\n" | |
| | | "or equal to the corresponding source length."); | |
| | | if(dshape[i] != 1) | |
| | | reduceShape[i] = 1; | |
| | | } | |
| | | transformMultiArrayReduceImpl(s, sshape, src, d, dshape, dest, reduceSh | |
| | | ape, | |
| | | f, MetaInt<SrcIterator::level>()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | transformMultiArrayExpandImpl(SrcIterator s, SrcShape const & sshape, SrcAc | |
| | | cessor src, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f, MetaInt<0>) | |
| | | { | |
| | | if(sshape[0] == 1) | |
| | | { | |
| | | initLine(d, d + dshape[0], dest, f(src(s))); | |
| | | } | |
| | | else | |
| | | { | |
| | | transformLine(s, s + sshape[0], src, d, dest, f); | |
| | | } | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor, int N> | |
| | | void | |
| | | transformMultiArrayExpandImpl(SrcIterator s, SrcShape const & sshape, SrcAc | |
| | | cessor src, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor d | |
| | | est, | |
| | | Functor const & f, MetaInt<N>) | |
| | | { | |
| | | DestIterator dend = d + dshape[N]; | |
| | | if(sshape[N] == 1) | |
| | | { | |
| | | for(; d != dend; ++d) | |
| | | { | |
| | | transformMultiArrayExpandImpl(s.begin(), sshape, src, d.begin() | |
| | | , dshape, dest, | |
| | | f, MetaInt<N-1>()); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | for(; d != dend; ++s, ++d) | |
| | | { | |
| | | transformMultiArrayExpandImpl(s.begin(), sshape, src, d.begin() | |
| | | , dshape, dest, | |
| | | f, MetaInt<N-1>()); | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | transformMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor | |
| | | src, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f, VigraFalseType) | |
| | | { | |
| | | // expand mode | |
| | | for(unsigned int i=0; i<sshape.size(); ++i) | |
| | | vigra_precondition(sshape[i] == 1 || sshape[i] == dshape[i], | |
| | | "transformMultiArray(): mismatch between source and destination | |
| | | shapes:\n" | |
| | | "In 'expand'-mode, the length of each source dimension must eit | |
| | | her be 1\n" | |
| | | "or equal to the corresponding destination length."); | |
| | | transformMultiArrayExpandImpl(s, sshape, src, d, dshape, dest, | |
| | | f, MetaInt<SrcIterator::level>()); | |
| | | } | |
| | | | |
| /** \brief Transform a multi-dimensional array with a unary function or fun
ctor. | | /** \brief Transform a multi-dimensional array with a unary function or fun
ctor. | |
| | | | |
|
| The transformation given by the functor is applied to every source | | This function can be applied in three modes: | |
| element and the result written into the corresponding destination eleme | | | |
| nt. | | <DL> | |
| | | <DT><b>Standard Mode:</b> | |
| | | <DD>If the source and destination arrays have the same size, | |
| | | the transformation given by the functor is applied to every source | |
| | | element and the result written into the corresponding destination e | |
| | | lement. | |
| | | Unary functions, unary functors from the STL and the functors speci | |
| | | fically | |
| | | defined in \ref TransformFunctor can be used in standard mode. | |
| | | Creation of new functors is easiest by using \ref FunctorExpression | |
| | | s. | |
| | | <DT><b>Expanding Mode:</b> | |
| | | <DD>If the source array has length 1 along some (or even all) dimen | |
| | | sions, | |
| | | the source value at index 0 is used for all destination | |
| | | elements in those dimensions. In other words, the source index is n | |
| | | ot | |
| | | incremented along these dimensions, but the transformation functor | |
| | | is applied as usual. So, we can expand a small array (e.g. a single | |
| | | row of data, | |
| | | column length is 1), into a larger one (e.g. a 2D image with the sa | |
| | | me width): | |
| | | the given values are simply reused as necessary (e.g. for every row | |
| | | of the | |
| | | destination image). The same functors as in standard mode can be ap | |
| | | plied. | |
| | | <DT><b>Reducing Mode:</b> | |
| | | <DD>If the destination array has length 1 along some (or even all) | |
| | | dimensions, | |
| | | the source values in these dimensions are reduced to single values | |
| | | by means | |
| | | of a suitable functor (e.g. \ref vigra::ReduceFunctor), which suppo | |
| | | rts two | |
| | | function call operators: one | |
| | | with a single argument to collect the values, and without argument | |
| | | to | |
| | | obtain the final (reduced) result. This behavior is a multi-dimensi | |
| | | onal | |
| | | generalization of the C++ standard function <tt>std::accumulate()</ | |
| | | tt>. | |
| | | </DL> | |
| | | | |
| The arrays must be represented by | | The arrays must be represented by | |
|
| iterators compatible with \ref vigra::MultiIterator. | | iterators compatible with \ref vigra::MultiIterator, and the iteration | |
| The function uses accessors to access the pixel data. | | range | |
| Note that the unary functors of the STL can be used in addition to | | is specified by means of shape objects. If only the source shape is giv | |
| the functors specifically defined in \ref TransformFunctor. | | en | |
| Creation of new functors is easiest by using \ref FunctorExpressions. N | | the destination array is assumed to have the same shape, and standard m | |
| ote that the iterator range | | ode | |
| must be specified by a shape object, because otherwise we could not con | | is applied. If two shapes are given, the size of corresponding dimensio | |
| trol | | ns | |
| the range simultaneously in all dimensions (this is a necessary consequ | | must be either equal (standard copy), or the source length must be 1 | |
| ence | | (expand mode), or the destination length must be 1 (reduce mode). Howev | |
| of the \ref vigra::MultiIterator design). | | er, | |
| | | reduction and expansion cannot be executed at the same time, so the lat | |
| | | ter | |
| | | conditions are mutual exclusive, even if they apply to different dimens | |
| | | ions. | |
| | | | |
| | | The function uses accessors to access the data elements. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
|
| | | <b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr | |
| | | a/multi_pointoperators.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class Functor> | | class Functor> | |
| void | | void | |
| transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAcces
sor src, | | transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAcces
sor src, | |
| DestIterator d, DestAccessor dest, Functor cons
t & f); | | DestIterator d, DestAccessor dest, Functor cons
t & f); | |
|
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | transformMultiArray(SrcIterator s, SrcShape const & sshape, SrcAcce | |
| | | ssor src, | |
| | | DestIterator d, DestShape const & dshape, DestA | |
| | | ccessor dest, | |
| | | Functor const & f); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class Functor> | | class Functor> | |
| void | | void | |
| transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> cons
t & src, | | transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> cons
t & src, | |
|
| pair<DestIterator, DestAccessor> const & dest, Funct | | pair<DestIterator, DestAccessor> const & dest, | |
| or const & f); | | Functor const & f); | |
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> cons | |
| | | t & src, | |
| | | triple<DestIterator, DestShape, DestAccessor> c | |
| | | onst & dest, | |
| | | Functor const & f) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
|
| <b> Usage:</b> | | <b> Usage - Standard Mode:</b> | |
| | | | |
|
| <b>\#include</b> "<a href="multi_pointoperators_8hxx-source.html">vigra | | Source and destination array have the same size. | |
| /multi_pointoperators.hxx</a>"br> | | | |
| Namespace: vigra | | | |
| | | | |
| \code | | \code | |
| #include <cmath> // for sqrt() | | #include <cmath> // for sqrt() | |
| | | | |
|
| typedef vigra::MultiArray<3, int> Array; | | typedef vigra::MultiArray<3, float> Array; | |
| Array src(Array::size_type(100, 200, 50)), | | Array src(Array::size_type(100, 200, 50)), | |
| dest(Array::size_type(100, 200, 50)); | | dest(Array::size_type(100, 200, 50)); | |
| ... | | ... | |
| | | | |
| vigra::transformMultiArray(srcMultiArrayRange(src), | | vigra::transformMultiArray(srcMultiArrayRange(src), | |
| destMultiArray(dest), | | destMultiArray(dest), | |
| &std::sqrt ); | | &std::sqrt ); | |
| | | | |
| \endcode | | \endcode | |
| | | | |
|
| | | <b> Usage - Expand Mode:</b> | |
| | | | |
| | | The source array is only 2D (it has depth 1). Thus, the destination | |
| | | will contain 50 identical copies of the transformed source array. | |
| | | Note that the destination shape must be passed to the algorithm for | |
| | | the expansion to work, so we use <tt>destMultiArrayRange()</tt> | |
| | | rather than <tt>destMultiArray()</tt>. | |
| | | | |
| | | \code | |
| | | #include <cmath> // for sqrt() | |
| | | | |
| | | typedef vigra::MultiArray<3, float> Array; | |
| | | Array src(Array::size_type(100, 200, 1)), | |
| | | dest(Array::size_type(100, 200, 50)); | |
| | | ... | |
| | | | |
| | | vigra::transformMultiArray(srcMultiArrayRange(src), | |
| | | destMultiArrayRange(dest), | |
| | | &std::sqrt ); | |
| | | | |
| | | \endcode | |
| | | | |
| | | <b> Usage - Reduce Mode:</b> | |
| | | | |
| | | The destination array is only 1D (it's width and height are 1). | |
| | | Thus, it will contain accumulated data for every slice of the source vo | |
| | | lume | |
| | | (or for every frame, if the source is intepreted as an image sequence). | |
| | | In the example, we use the functor \ref vigra::FindAverage to calculate | |
| | | the average gray value of every slice. Note that the destination shape | |
| | | must also be passed for the reduction to work, so we use | |
| | | <tt>destMultiArrayRange()</tt> rather than <tt>destMultiArray()</tt>. | |
| | | | |
| | | \code | |
| | | typedef vigra::MultiArray<3, float> Array; | |
| | | Array src(Array::size_type(100, 200, 50)), | |
| | | dest(Array::size_type(1, 1, 50)); | |
| | | ... | |
| | | | |
| | | vigra::transformMultiArray(srcMultiArrayRange(src), | |
| | | destMultiArrayRange(dest), | |
| | | vigra::FindAverage<float>() ); | |
| | | | |
| | | \endcode | |
| | | | |
| <b> Required Interface:</b> | | <b> Required Interface:</b> | |
| | | | |
|
| | | In standard and expand mode, the functor must be a model of UnaryFuncti | |
| | | on | |
| | | (i.e. support function call with one argument and a return value | |
| | | <tt>res = functor(arg)</tt>): | |
| | | | |
| \code | | \code | |
| MultiIterator src_begin, src_end, dest_begin; | | MultiIterator src_begin, src_end, dest_begin; | |
| | | | |
| SrcAccessor src_accessor; | | SrcAccessor src_accessor; | |
| DestAccessor dest_accessor; | | DestAccessor dest_accessor; | |
| Functor functor; | | Functor functor; | |
| | | | |
| dest_accessor.set(functor(src_accessor(src_begin)), dest_begin); | | dest_accessor.set(functor(src_accessor(src_begin)), dest_begin); | |
|
| | | \endcode | |
| | | | |
| | | In reduce mode, it must be a model of UnaryAnalyser (i.e. support funct | |
| | | ion call | |
| | | with one argument and no return vakue <tt>functor(arg)</tt>) and Initia | |
| | | lizer | |
| | | (i.e. support function call with no argument, but return value | |
| | | <tt>res = functor()</tt>). Internally, such functors are recognized by | |
| | | the | |
| | | meta functions <tt>FunctorTraits<FUNCTOR>::</tt><tt>isUnaryAnalys | |
| | | er</tt> and | |
| | | <tt>FunctorTraits<FUNCTOR>::</tt><tt>isInitializer</tt> which mus | |
| | | t both yield | |
| | | <tt>VigraTrueType</tt>. Make sure that your functor correctly defines | |
| | | <tt>FunctorTrits</tt> because otherwise reduce mode will not work. In a | |
| | | ddition, | |
| | | the functor must be copy constructible in order to start each reduction | |
| | | with a fresh functor. | |
| | | | |
| | | \code | |
| | | MultiIterator src_begin, src_end, dest_begin; | |
| | | | |
|
| | | SrcAccessor src_accessor; | |
| | | DestAccessor dest_accessor; | |
| | | | |
| | | FUNCTOR initial_functor, functor(initial_functor); | |
| | | assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru | |
| | | eType)); | |
| | | assert(typeid(FunctorTraits<FUNCTOR>::isUnaryAnalyser) == typeid(VigraT | |
| | | rueType)); | |
| | | | |
| | | functor(src_accessor(src_begin)); | |
| | | dest_accessor.set(functor(), dest_begin); | |
| \endcode | | \endcode | |
| | | | |
| */ | | */ | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class Functor> | | class Functor> | |
| inline void | | inline void | |
| transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAccessor src, | | transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAccessor src, | |
| DestIterator d, DestAccessor dest, Functor const & f) | | DestIterator d, DestAccessor dest, Functor const & f) | |
| { | | { | |
|
| transformMultiArrayImpl(s, shape, src, d, dest, f, MetaInt<SrcIterator: | | transformMultiArrayExpandImpl(s, shape, src, d, shape, dest, | |
| :level>()); | | f, MetaInt<SrcIterator::level>()); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcShape, class SrcAccessor, | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class Functor> | | class Functor> | |
| inline void | | inline void | |
| transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src, | | transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src, | |
| pair<DestIterator, DestAccessor> const & dest, Functor const
& f) | | pair<DestIterator, DestAccessor> const & dest, Functor const
& f) | |
| { | | { | |
| | | | |
| transformMultiArray(src.first, src.second, src.third, | | transformMultiArray(src.first, src.second, src.third, | |
| dest.first, dest.second, f); | | dest.first, dest.second, f); | |
| } | | } | |
| | | | |
|
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | transformMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor src | |
| | | , | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f) | |
| | | { | |
| | | vigra_precondition(sshape.size() == dshape.size(), | |
| | | "transformMultiArray(): dimensionality of source and destination ar | |
| | | ray differ"); | |
| | | typedef FunctorTraits<Functor> FT; | |
| | | typedef typename | |
| | | And<typename FT::isInitializer, typename FT::isUnaryAnalyser>::resu | |
| | | lt | |
| | | isAnalyserInitializer; | |
| | | transformMultiArrayImpl(s, sshape, src, d, dshape, dest, | |
| | | f, isAnalyserInitializer()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcShape, class SrcAccessor, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | inline void | |
| | | transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src, | |
| | | triple<DestIterator, DestShape, DestAccessor> const & dest, | |
| | | Functor const & f) | |
| | | { | |
| | | transformMultiArray(src.first, src.second, src.third, | |
| | | dest.first, dest.second, dest.third, f); | |
| | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* combineTwoMultiArrays */ | | /* combineTwoMultiArrays */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| template <class SrcIterator1, class SrcShape, class SrcAccessor1, | | template <class SrcIterator1, class SrcShape, class SrcAccessor1, | |
| class SrcIterator2, class SrcAccessor2, | | class SrcIterator2, class SrcAccessor2, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestShape, class DestAccessor, | |
| class Functor> | | class Functor> | |
|
| inline void | | void | |
| combineTwoMultiArraysImpl(SrcIterator1 s1, SrcShape const & shape, SrcAcces | | combineTwoMultiArraysReduceImpl( | |
| sor1 src1, | | SrcIterator1 s1, SrcShape const & sshape, SrcAccessor1 src1, | |
| SrcIterator2 s2, SrcAccessor2 src2, | | SrcIterator2 s2, SrcAccessor2 src2, | |
|
| DestIterator d, DestAccessor dest, Functor const & f, MetaIn | | DestIterator d, DestShape const & dshape, DestAccessor dest | |
| t<0>) | | , | |
| | | SrcShape const & reduceShape, | |
| | | Functor const & ff, MetaInt<0>) | |
| { | | { | |
|
| combineTwoLines(s1, s1 + shape[0], src1, s2, src2, d, dest, f); | | DestIterator dend = d + dshape[0]; | |
| | | for(; d != dend; ++s1.template dim<0>(), ++s2.template dim<0>(), ++d) | |
| | | { | |
| | | Functor f = ff; | |
| | | inspectTwoMultiArrays(s1, reduceShape, src1, s2, src2, f); | |
| | | dest.set(f(), d); | |
| | | } | |
| } | | } | |
| | | | |
| template <class SrcIterator1, class SrcShape, class SrcAccessor1, | | template <class SrcIterator1, class SrcShape, class SrcAccessor1, | |
| class SrcIterator2, class SrcAccessor2, | | class SrcIterator2, class SrcAccessor2, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestShape, class DestAccessor, | |
| class Functor, int N> | | class Functor, int N> | |
| void | | void | |
|
| combineTwoMultiArraysImpl(SrcIterator1 s1, SrcShape const & shape, SrcAcces | | combineTwoMultiArraysReduceImpl( | |
| sor1 src1, | | SrcIterator1 s1, SrcShape const & sshape, SrcAccessor1 src1, | |
| SrcIterator2 s2, SrcAccessor2 src2, | | SrcIterator2 s2, SrcAccessor2 src2, | |
|
| DestIterator d, DestAccessor dest, | | DestIterator d, DestShape const & dshape, DestAccessor dest | |
| | | , | |
| | | SrcShape const & reduceShape, | |
| Functor const & f, MetaInt<N>) | | Functor const & f, MetaInt<N>) | |
| { | | { | |
|
| SrcIterator1 s1end = s1 + shape[N]; | | DestIterator dend = d + dshape[N]; | |
| for(; s1 != s1end; ++s1, ++s2, ++d) | | for(; d != dend; ++s1.template dim<N>(), ++s2.template dim<N>(), ++d) | |
| { | | { | |
|
| combineTwoMultiArraysImpl(s1.begin(), shape, src1, | | combineTwoMultiArraysReduceImpl(s1, sshape, src1, s2, src2, | |
| s2.begin(), src2, d.begin(), dest, | | d.begin(), dshape, dest, | |
| f, MetaInt<N-1>()); | | reduceShape, f, MetaInt<N-1>()); | |
| | | } | |
| | | } | |
| | | | |
| | | template <class SrcIterator1, class SrcShape1, class SrcAccessor1, | |
| | | class SrcIterator2, class SrcShape2, class SrcAccessor2, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | combineTwoMultiArraysImpl( | |
| | | SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src | |
| | | 1, | |
| | | SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src | |
| | | 2, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f, VigraTrueType) | |
| | | { | |
| | | // reduce mode | |
| | | SrcShape1 reduceShape = sshape1; | |
| | | for(unsigned int i=0; i<dshape.size(); ++i) | |
| | | { | |
| | | vigra_precondition(sshape1[i] == sshape2[i] && | |
| | | (dshape[i] == 1 || sshape1[i] == dshape[i]), | |
| | | "combineTwoMultiArrays(): mismatch between source and destinati | |
| | | on shapes:\n" | |
| | | "In 'reduce'-mode, the two source shapes must be equal, and\n" | |
| | | "the length of each destination dimension must either be 1\n" | |
| | | "or equal to the corresponding source length."); | |
| | | if(dshape[i] != 1) | |
| | | reduceShape[i] = 1; | |
| } | | } | |
|
| | | combineTwoMultiArraysReduceImpl(s1, sshape1, src1, s2, src2, | |
| | | d, dshape, dest, reduceShape, | |
| | | f, MetaInt<SrcIterator1::level>()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator1, class SrcShape1, class SrcAccessor1, | |
| | | class SrcIterator2, class SrcShape2, class SrcAccessor2, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | combineTwoMultiArraysExpandImpl( | |
| | | SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src | |
| | | 1, | |
| | | SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src | |
| | | 2, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f, MetaInt<0>) | |
| | | { | |
| | | DestIterator dend = d + dshape[0]; | |
| | | if(sshape1[0] == 1 && sshape2[0] == 1) | |
| | | { | |
| | | initLine(d, dend, dest, f(src1(s1), src2(s2))); | |
| | | } | |
| | | else if(sshape1[0] == 1) | |
| | | { | |
| | | typename SrcAccessor1::value_type sv1 = src1(s1); | |
| | | for(; d != dend; ++d, ++s2) | |
| | | dest.set(f(sv1, src2(s2)), d); | |
| | | } | |
| | | else if(sshape2[0] == 1) | |
| | | { | |
| | | typename SrcAccessor2::value_type sv2 = src2(s2); | |
| | | for(; d != dend; ++d, ++s1) | |
| | | dest.set(f(src1(s1), sv2), d); | |
| | | } | |
| | | else | |
| | | { | |
| | | combineTwoLines(s1, s1 + sshape1[0], src1, s2, src2, d, dest, f); | |
| | | } | |
| | | } | |
| | | | |
| | | template <class SrcIterator1, class SrcShape1, class SrcAccessor1, | |
| | | class SrcIterator2, class SrcShape2, class SrcAccessor2, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor, int N> | |
| | | void | |
| | | combineTwoMultiArraysExpandImpl( | |
| | | SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src | |
| | | 1, | |
| | | SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src | |
| | | 2, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f, MetaInt<N>) | |
| | | { | |
| | | DestIterator dend = d + dshape[N]; | |
| | | int s1inc = sshape1[N] == 1 | |
| | | ? 0 | |
| | | : 1; | |
| | | int s2inc = sshape2[N] == 1 | |
| | | ? 0 | |
| | | : 1; | |
| | | for(; d != dend; ++d, s1 += s1inc, s2 += s2inc) | |
| | | { | |
| | | combineTwoMultiArraysExpandImpl(s1.begin(), sshape1, src1, | |
| | | s2.begin(), sshape2, src2, | |
| | | d.begin(), dshape, dest, | |
| | | f, MetaInt<N-1>()); | |
| | | } | |
| | | } | |
| | | | |
| | | template <class SrcIterator1, class SrcShape1, class SrcAccessor1, | |
| | | class SrcIterator2, class SrcShape2, class SrcAccessor2, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | combineTwoMultiArraysImpl( | |
| | | SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src | |
| | | 1, | |
| | | SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src | |
| | | 2, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f, VigraFalseType) | |
| | | { | |
| | | // expand mode | |
| | | for(unsigned int i=0; i<sshape1.size(); ++i) | |
| | | vigra_precondition((sshape1[i] == 1 || sshape1[i] == dshape[i]) && | |
| | | (sshape2[i] == 1 || sshape2[i] == dshape[i]), | |
| | | "combineTwoMultiArrays(): mismatch between source and destinati | |
| | | on shapes:\n" | |
| | | "In 'expand'-mode, the length of each source dimension must eit | |
| | | her be 1\n" | |
| | | "or equal to the corresponding destination length."); | |
| | | combineTwoMultiArraysExpandImpl(s1, sshape1, src1, s2, sshape2, src2, | |
| | | d, dshape, dest, | |
| | | f, MetaInt<SrcIterator1::level>()); | |
| } | | } | |
| | | | |
| /** \brief Combine two multi-dimensional arrays into one using a binary fun
ction or functor. | | /** \brief Combine two multi-dimensional arrays into one using a binary fun
ction or functor. | |
| | | | |
|
| The transformation given by the functor is applied to the source | | This function can be applied in three modes: | |
| array elements and the result written into the corresponding destinatio | | | |
| n element. | | <DL> | |
| This is typically used for operations like add and subtract. | | <DT><b>Standard Mode:</b> | |
| | | <DD>If the source and destination arrays have the same size, | |
| | | the transformation given by the functor is applied to every pair of | |
| | | corresponding source elements and the result written into the corre | |
| | | sponding | |
| | | destination element. | |
| | | Binary functions, binary functors from the STL and the functors spe | |
| | | cifically | |
| | | defined in \ref CombineFunctor can be used in standard mode. | |
| | | Creation of new functors is easiest by using \ref FunctorExpression | |
| | | s. | |
| | | <DT><b>Expanding Mode:</b> | |
| | | <DD>If the source arrays have length 1 along some (or even all) dim | |
| | | ensions, | |
| | | the source values at index 0 are used for all destination | |
| | | elements in those dimensions. In other words, the source index is n | |
| | | ot | |
| | | incremented along those dimensions, but the transformation functor | |
| | | is applied as usual. So, we can expand small arrays (e.g. a single | |
| | | row of data, | |
| | | column length is 1), into larger ones (e.g. a 2D image with the sam | |
| | | e width): | |
| | | the given values are simply reused as necessary (e.g. for every row | |
| | | of the | |
| | | destination image). It is not even necessary that the source array | |
| | | shapes | |
| | | are equal. For example, we can combine a small array with one that | |
| | | hase the same size as the destination array. | |
| | | The same functors as in standard mode can be applied. | |
| | | <DT><b>Reducing Mode:</b> | |
| | | <DD>If the destination array has length 1 along some (or even all) | |
| | | dimensions, | |
| | | the source values in these dimensions are reduced to single values | |
| | | by means | |
| | | of a suitable functor which supports two function call operators: o | |
| | | ne | |
| | | with two arguments to collect the values, and one without argument | |
| | | to | |
| | | obtain the final (reduced) result. This behavior is a multi-dimensi | |
| | | onal | |
| | | generalization of the C++ standard function <tt>std::accumulate()</ | |
| | | tt>. | |
| | | </DL> | |
| | | | |
| The arrays must be represented by | | The arrays must be represented by | |
|
| iterators compatible with \ref vigra::MultiIterator. | | iterators compatible with \ref vigra::MultiIterator, and the iteration | |
| The function uses accessors to access the pixel data. | | range | |
| Note that the binary functors of the STL can be used in addition to | | is specified by means of shape objects. If only a single source shape i | |
| the functors specifically defined in \ref CombineFunctor. | | s given | |
| Creation of new functors is easiest by using \ref FunctorExpressions. N | | the destination array is assumed to have the same shape, and standard m | |
| ote that the iterator range | | ode | |
| must be specified by a shape object, because otherwise we could not con | | is applied. If three shapes are given, the size of corresponding dimens | |
| trol | | ions | |
| the range simultaneously in all dimensions (this is a necessary consequ | | must be either equal (standard copy), or the length of this dimension m | |
| ence | | ust | |
| of the \ref vigra::MultiIterator design). | | be 1 in one or both source arrays | |
| | | (expand mode), or the destination length must be 1 (reduce mode). Howev | |
| | | er, | |
| | | reduction and expansion cannot be executed at the same time, so the lat | |
| | | ter | |
| | | conditions are mutual exclusive, even if they apply to different dimens | |
| | | ions. | |
| | | | |
| | | The function uses accessors to access the data elements. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
|
| | | <b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr | |
| | | a/multi_pointoperators.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator1, class SrcShape, class SrcAccessor1, | | template <class SrcIterator1, class SrcShape, class SrcAccessor1, | |
| class SrcIterator2, class SrcAccessor2, | | class SrcIterator2, class SrcAccessor2, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class Functor> | | class Functor> | |
|
| inline void | | void combineTwoMultiArrays( | |
| combineTwoMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcA | | SrcIterator1 s1, SrcShape const & shape, SrcAccessor | |
| ccessor1 src1, | | 1 src1, | |
| SrcIterator2 s2, SrcAccessor2 src2, | | SrcIterator2 s2, SrcAccessor2 src2, | |
| DestIterator d, DestAccessor dest, Functor const & f
); | | DestIterator d, DestAccessor dest, Functor const & f
); | |
|
| | | | |
| | | template <class SrcIterator1, class SrcShape1, class SrcAccessor1, | |
| | | class SrcIterator2, class SrcShape2, class SrcAccessor2, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void combineTwoMultiArrays( | |
| | | SrcIterator1 s1, SrcShape1 const & sshape1, SrcAcces | |
| | | sor1 src1, | |
| | | SrcIterator2 s2, SrcShape2 const & sshape2, SrcAcces | |
| | | sor2 src2, | |
| | | DestIterator d, DestShape const & dshape, DestAccess | |
| | | or dest, | |
| | | Functor const & f); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator1, class SrcShape, class SrcAccessor1, | | template <class SrcIterator1, class SrcShape, class SrcAccessor1, | |
| class SrcIterator2, class SrcAccessor2, | | class SrcIterator2, class SrcAccessor2, | |
| class DestIterator, class DestAccessor, class Functor> | | class DestIterator, class DestAccessor, class Functor> | |
|
| void | | void combineTwoMultiArrays( | |
| combineTwoMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1> | | triple<SrcIterator1, SrcShape, SrcAccessor1> const & | |
| const & src1, | | src1, | |
| pair<SrcIterator2, SrcAccessor2> const & src2, | | pair<SrcIterator2, SrcAccessor2> const & src2, | |
| pair<DestIterator, DestAccessor> const & dest, Funct
or const & f); | | pair<DestIterator, DestAccessor> const & dest, Funct
or const & f); | |
|
| | | | |
| | | template <class SrcIterator1, class SrcShape1, class SrcAccessor1, | |
| | | class SrcIterator2, class SrcShape2, class SrcAccessor2, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void combineTwoMultiArrays( | |
| | | triple<SrcIterator1, SrcShape1, SrcAccessor1> const | |
| | | & src1, | |
| | | triple<SrcIterator2, SrcShape2, SrcAccessor2> const | |
| | | & src2, | |
| | | triple<DestIterator, DestShape, DestAccessor> const | |
| | | & dest, | |
| | | Functor const & f); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
|
| <b> Usage:</b> | | <b> Usage - Standard Mode:</b> | |
| | | | |
|
| <b>\#include</b> "<a href="multi_pointoperators_8hxx-source.html">vigra | | Source and destination arrays have the same size. | |
| /multi_pointoperators.hxx</a>"br> | | | |
| Namespace: vigra | | | |
| | | | |
| \code | | \code | |
|
| #include <functional> // for plus | | #include <functional> // for std::plus | |
| | | | |
| typedef vigra::MultiArray<3, int> Array; | | typedef vigra::MultiArray<3, int> Array; | |
| Array src1(Array::size_type(100, 200, 50)), | | Array src1(Array::size_type(100, 200, 50)), | |
| src2(Array::size_type(100, 200, 50)), | | src2(Array::size_type(100, 200, 50)), | |
| dest(Array::size_type(100, 200, 50)); | | dest(Array::size_type(100, 200, 50)); | |
| ... | | ... | |
| | | | |
| vigra::combineTwoMultiArrays( | | vigra::combineTwoMultiArrays( | |
| srcMultiArrayRange(src1), | | srcMultiArrayRange(src1), | |
| srcMultiArray(src2), | | srcMultiArray(src2), | |
| destMultiArray(dest), | | destMultiArray(dest), | |
|
| std::plus<SrcValueType>()); | | std::plus<int>()); | |
| | | | |
| \endcode | | \endcode | |
| | | | |
|
| Note that <TT>SrcValueType</TT> must be replaced with the appropriate t | | <b> Usage - Expand Mode:</b> | |
| ype (e.g. | | | |
| the promote type of the input images' pixel type, see also | | One source array is only 2D (it has depth 1). This image will be added | |
| \ref NumericPromotionTraits) | | to every slice of the other source array, and the result | |
| | | if written into the corresponding destination slice. Note that the shap | |
| | | es | |
| | | of all arrays must be passed to the algorithm, so we use | |
| | | <tt>srcMultiArrayRange()</tt> and <tt>destMultiArrayRange()</tt> | |
| | | rather than <tt>srcMultiArray()</tt> and <tt>destMultiArray()</tt>. | |
| | | | |
| | | \code | |
| | | #include <functional> // for std::plus | |
| | | | |
| | | typedef vigra::MultiArray<3, int> Array; | |
| | | Array src1(Array::size_type(100, 200, 1)), | |
| | | src2(Array::size_type(100, 200, 50)), | |
| | | dest(Array::size_type(100, 200, 50)); | |
| | | ... | |
| | | | |
| | | vigra::combineTwoMultiArrays( | |
| | | srcMultiArrayRange(src1), | |
| | | srcMultiArray(src2), | |
| | | destMultiArray(dest), | |
| | | std::plus<int>()); | |
| | | | |
| | | \endcode | |
| | | | |
| | | <b> Usage - Reduce Mode:</b> | |
| | | | |
| | | The destination array is only 1D (it's width and height are 1). | |
| | | Thus, it will contain accumulated data for every slice of the source vo | |
| | | lumes | |
| | | (or for every frame, if the sources are intepreted as image sequences). | |
| | | In the example, we use \ref vigra::ReduceFunctor together with a functo | |
| | | r | |
| | | expression (see \ref FunctorExpressions) | |
| | | to calculate the total absolute difference of the gray values in every | |
| | | pair of | |
| | | source slices. Note that the shapes of all arrays must be passed | |
| | | to the algorithm in order for the reduction to work, so we use | |
| | | <tt>srcMultiArrayRange()</tt> and <tt>destMultiArrayRange()</tt> | |
| | | rather than <tt>srcMultiArray()</tt> and <tt>destMultiArray()</tt>. | |
| | | | |
| | | \code | |
| | | #include <vigra/functorexpression.hxx> | |
| | | using namespace vigra::functor; | |
| | | | |
| | | typedef vigra::MultiArray<3, int> Array; | |
| | | Array src1(Array::size_type(100, 200, 50)), | |
| | | src2(Array::size_type(100, 200, 50)), | |
| | | dest(Array::size_type(1, 1, 50)); | |
| | | ... | |
| | | | |
| | | vigra::combineTwoMultiArrays( | |
| | | srcMultiArrayRange(src1), | |
| | | srcMultiArray(src2), | |
| | | destMultiArray(dest), | |
| | | reduceFunctor(Arg1() + abs(Arg2() - Arg3()), 0) ); | |
| | | // Arg1() is the sum accumulated so far, initialzed with 0 | |
| | | | |
| | | \endcode | |
| | | | |
| <b> Required Interface:</b> | | <b> Required Interface:</b> | |
| | | | |
|
| | | In standard and expand mode, the functor must be a model of BinaryFunct | |
| | | ion | |
| | | (i.e. support function call with two arguments and a return value | |
| | | <tt>res = functor(arg1, arg2)</tt>): | |
| | | | |
| \code | | \code | |
| MultiIterator src1_begin, src2_begin, dest_begin; | | MultiIterator src1_begin, src2_begin, dest_begin; | |
| | | | |
| SrcAccessor1 src1_accessor; | | SrcAccessor1 src1_accessor; | |
| SrcAccessor2 src2_accessor; | | SrcAccessor2 src2_accessor; | |
| DestAccessor dest_accessor; | | DestAccessor dest_accessor; | |
| | | | |
| Functor functor; | | Functor functor; | |
| | | | |
| dest_accessor.set( | | dest_accessor.set( | |
| functor(src1_accessor(src1_begin), src2_accessor(src2_begin)), | | functor(src1_accessor(src1_begin), src2_accessor(src2_begin)), | |
| dest_begin); | | dest_begin); | |
| | | | |
| \endcode | | \endcode | |
| | | | |
|
| | | In reduce mode, it must be a model of BinaryAnalyser (i.e. support func | |
| | | tion call | |
| | | with two arguments and no return vakue <tt>functor(arg1, arg2)</tt>) an | |
| | | d Initializer | |
| | | (i.e. support function call with no argument, but return value | |
| | | <tt>res = functor()</tt>). Internally, such functors are recognized by | |
| | | the | |
| | | meta functions <tt>FunctorTraits<FUNCTOR>::</tt><tt>isBinaryAnaly | |
| | | ser</tt> and | |
| | | <tt>FunctorTraits<FUNCTOR>::</tt><tt>isInitializer</tt> which mus | |
| | | t both yield | |
| | | <tt>VigraTrueType</tt>. Make sure that your functor correctly defines | |
| | | <tt>FunctorTrits</tt> because otherwise reduce mode will not work. In a | |
| | | ddition, | |
| | | the functor must be copy constructible in order to start each reduction | |
| | | with a fresh functor. | |
| | | | |
| | | \code | |
| | | MultiIterator src1_begin, src2_begin, dest_begin; | |
| | | | |
| | | SrcAccessor1 src1_accessor; | |
| | | SrcAccessor2 src2_accessor; | |
| | | DestAccessor dest_accessor; | |
| | | | |
| | | FUNCTOR initial_functor, functor(initial_functor); | |
| | | assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru | |
| | | eType)); | |
| | | assert(typeid(FunctorTraits<FUNCTOR>::isBinaryAnalyser) == typeid(Vigra | |
| | | TrueType)); | |
| | | | |
| | | functor(src1_accessor(src1_begin), src2_accessor(src2_begin)); | |
| | | dest_accessor.set(functor(), dest_begin); | |
| | | \endcode | |
| | | | |
| */ | | */ | |
| template <class SrcIterator1, class SrcShape, class SrcAccessor1, | | template <class SrcIterator1, class SrcShape, class SrcAccessor1, | |
| class SrcIterator2, class SrcAccessor2, | | class SrcIterator2, class SrcAccessor2, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class Functor> | | class Functor> | |
| inline void | | inline void | |
| combineTwoMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1
src1, | | combineTwoMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1
src1, | |
| SrcIterator2 s2, SrcAccessor2 src2, | | SrcIterator2 s2, SrcAccessor2 src2, | |
| DestIterator d, DestAccessor dest, Functor const & f) | | DestIterator d, DestAccessor dest, Functor const & f) | |
| { | | { | |
|
| combineTwoMultiArraysImpl(s1, shape, src1, s2, src2, d, dest, f, | | combineTwoMultiArraysExpandImpl(s1, shape, src1, s2, shape, src2, d, sh | |
| MetaInt<SrcIterator1::level>()); | | ape, dest, f, | |
| | | MetaInt<SrcIterator1::level>()); | |
| } | | } | |
| | | | |
| template <class SrcIterator1, class SrcShape, class SrcAccessor1, | | template <class SrcIterator1, class SrcShape, class SrcAccessor1, | |
| class SrcIterator2, class SrcAccessor2, | | class SrcIterator2, class SrcAccessor2, | |
| class DestIterator, class DestAccessor, class Functor> | | class DestIterator, class DestAccessor, class Functor> | |
| inline void | | inline void | |
| combineTwoMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1> const &
src1, | | combineTwoMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1> const &
src1, | |
| pair<SrcIterator2, SrcAccessor2> const & src2, | | pair<SrcIterator2, SrcAccessor2> const & src2, | |
| pair<DestIterator, DestAccessor> const & dest, Functor const
& f) | | pair<DestIterator, DestAccessor> const & dest, Functor const
& f) | |
| { | | { | |
| | | | |
| combineTwoMultiArrays( | | combineTwoMultiArrays( | |
| src1.first, src1.second, src1.third, | | src1.first, src1.second, src1.third, | |
| src2.first, src2.second, dest.first, dest.second, f); | | src2.first, src2.second, dest.first, dest.second, f); | |
| } | | } | |
| | | | |
|
| | | template <class SrcIterator1, class SrcShape1, class SrcAccessor1, | |
| | | class SrcIterator2, class SrcShape2, class SrcAccessor2, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | void | |
| | | combineTwoMultiArrays( | |
| | | SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src | |
| | | 1, | |
| | | SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src | |
| | | 2, | |
| | | DestIterator d, DestShape const & dshape, DestAccessor dest, | |
| | | Functor const & f) | |
| | | { | |
| | | vigra_precondition(sshape1.size() == dshape.size() && sshape2.size() == | |
| | | dshape.size(), | |
| | | "combineTwoMultiArrays(): dimensionality of source and destination | |
| | | arrays differ"); | |
| | | | |
| | | typedef FunctorTraits<Functor> FT; | |
| | | typedef typename | |
| | | And<typename FT::isInitializer, typename FT::isBinaryAnalyser>::res | |
| | | ult | |
| | | isAnalyserInitializer; | |
| | | combineTwoMultiArraysImpl(s1, sshape1, src1, s2, sshape2, src2, d, dsha | |
| | | pe, dest, | |
| | | f, isAnalyserInitializer()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator1, class SrcShape1, class SrcAccessor1, | |
| | | class SrcIterator2, class SrcShape2, class SrcAccessor2, | |
| | | class DestIterator, class DestShape, class DestAccessor, | |
| | | class Functor> | |
| | | inline void | |
| | | combineTwoMultiArrays( | |
| | | triple<SrcIterator1, SrcShape1, SrcAccessor1> const & src1, | |
| | | triple<SrcIterator2, SrcShape2, SrcAccessor2> const & src2, | |
| | | triple<DestIterator, DestShape, DestAccessor> const & dest, | |
| | | Functor const & f) | |
| | | { | |
| | | combineTwoMultiArrays(src1.first, src1.second, src1.third, | |
| | | src2.first, src2.second, src2.third, | |
| | | dest.first, dest.second, dest.third, f); | |
| | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* combineThreeMultiArrays */ | | /* combineThreeMultiArrays */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| template <class SrcIterator1, class SrcShape, class SrcAccessor1, | | template <class SrcIterator1, class SrcShape, class SrcAccessor1, | |
| class SrcIterator2, class SrcAccessor2, | | class SrcIterator2, class SrcAccessor2, | |
| class SrcIterator3, class SrcAccessor3, | | class SrcIterator3, class SrcAccessor3, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| | | | |
| skipping to change at line 573 | | skipping to change at line 1234 | |
| { | | { | |
| SrcIterator1 s1end = s1 + shape[N]; | | SrcIterator1 s1end = s1 + shape[N]; | |
| for(; s1 != s1end; ++s1, ++s2, ++s3, ++d) | | for(; s1 != s1end; ++s1, ++s2, ++s3, ++d) | |
| { | | { | |
| combineThreeMultiArraysImpl(s1.begin(), shape, src1, | | combineThreeMultiArraysImpl(s1.begin(), shape, src1, | |
| s2.begin(), src2, s3.begin(), src3, d.beg
in(), dest, | | s2.begin(), src2, s3.begin(), src3, d.beg
in(), dest, | |
| f, MetaInt<N-1>()); | | f, MetaInt<N-1>()); | |
| } | | } | |
| } | | } | |
| | | | |
|
| /** \brief Combine three multi-dimensional arrays into one using a binary f | | /** \brief Combine three multi-dimensional arrays into one using a | |
| unction or functor. | | ternary function or functor. | |
| | | | |
| Except for the fact that it operates on three input arrays, this functi
on is | | Except for the fact that it operates on three input arrays, this functi
on is | |
| identical to \ref combineTwoMultiArrays(). | | identical to \ref combineTwoMultiArrays(). | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator1, class SrcShape, class SrcAccessor1, | | template <class SrcIterator1, class SrcShape, class SrcAccessor1, | |
| | | | |
| skipping to change at line 614 | | skipping to change at line 1276 | |
| inline void | | inline void | |
| combineThreeMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1
> const & src1, | | combineThreeMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1
> const & src1, | |
| pair<SrcIterator2, SrcAccessor2> const & src2, | | pair<SrcIterator2, SrcAccessor2> const & src2, | |
| pair<SrcIterator3, SrcAccessor3> const & src3, | | pair<SrcIterator3, SrcAccessor3> const & src3, | |
| pair<DestIterator, DestAccessor> const & dest, Funct
or const & f); | | pair<DestIterator, DestAccessor> const & dest, Funct
or const & f); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
|
| <b>\#include</b> "<a href="multi_pointoperators_8hxx-source.html">vigra
/multi_pointoperators.hxx</a>"br> | | <b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr
a/multi_pointoperators.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| #include <functional> // for plus | | #include <functional> // for plus | |
| | | | |
| typedef vigra::MultiArray<3, int> Array; | | typedef vigra::MultiArray<3, int> Array; | |
| Array src1(Array::size_type(100, 200, 50)), | | Array src1(Array::size_type(100, 200, 50)), | |
| src2(Array::size_type(100, 200, 50)), | | src2(Array::size_type(100, 200, 50)), | |
| src3(Array::size_type(100, 200, 50)), | | src3(Array::size_type(100, 200, 50)), | |
| dest(Array::size_type(100, 200, 50)); | | dest(Array::size_type(100, 200, 50)); | |
| | | | |
| skipping to change at line 692 | | skipping to change at line 1354 | |
| void | | void | |
| inspectMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, Functor
& f, MetaInt<N>) | | inspectMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, Functor
& f, MetaInt<N>) | |
| { | | { | |
| Iterator send = s + shape[N]; | | Iterator send = s + shape[N]; | |
| for(; s != send; ++s) | | for(; s != send; ++s) | |
| { | | { | |
| inspectMultiArrayImpl(s.begin(), shape, a, f, MetaInt<N-1>()); | | inspectMultiArrayImpl(s.begin(), shape, a, f, MetaInt<N-1>()); | |
| } | | } | |
| } | | } | |
| | | | |
|
| /** \brief Apply read-only functor to every element of a multi-dimensional
array. | | /** \brief Call an analyzing functor at every element of a multi-dimensiona
l array. | |
| | | | |
| This function can be used to collect statistics of the array etc. | | This function can be used to collect statistics of the array etc. | |
| The results must be stored in the functor, which serves as a return | | The results must be stored in the functor, which serves as a return | |
| value. The arrays must be represented by | | value. The arrays must be represented by | |
| iterators compatible with \ref vigra::MultiIterator. | | iterators compatible with \ref vigra::MultiIterator. | |
| The function uses an accessor to access the pixel data. Note that the i
terator range | | The function uses an accessor to access the pixel data. Note that the i
terator range | |
| must be specified by a shape object, because otherwise we could not con
trol | | must be specified by a shape object, because otherwise we could not con
trol | |
| the range simultaneously in all dimensions (this is a necessary consequ
ence | | the range simultaneously in all dimensions (this is a necessary consequ
ence | |
| of the \ref vigra::MultiIterator design). | | of the \ref vigra::MultiIterator design). | |
| | | | |
| | | | |
| skipping to change at line 725 | | skipping to change at line 1387 | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class Iterator, class Shape, class Accessor, class Functo
r> | | template <class Iterator, class Shape, class Accessor, class Functo
r> | |
| void | | void | |
| inspectMultiArray(triple<Iterator, Shape, Accessor> const & s, Func
tor & f); | | inspectMultiArray(triple<Iterator, Shape, Accessor> const & s, Func
tor & f); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
|
| <b>\#include</b> "<a href="multi_pointoperators_8hxx-source.html">vigra
/multi_pointoperators.hxx</a>"br> | | <b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr
a/multi_pointoperators.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| typedef vigra::MultiArray<3, int> Array; | | typedef vigra::MultiArray<3, int> Array; | |
| Array array(Array::size_type(100, 200, 50)); | | Array array(Array::size_type(100, 200, 50)); | |
| | | | |
| // init functor | | // init functor | |
| vigra::FindMinMax<int> minmax; | | vigra::FindMinMax<int> minmax; | |
| | | | |
| vigra::inspectMultiArray(srcMultiArrayRange(array), minmax); | | vigra::inspectMultiArray(srcMultiArrayRange(array), minmax); | |
| | | | |
| skipping to change at line 800 | | skipping to change at line 1462 | |
| Functor & f, MetaInt<N>) | | Functor & f, MetaInt<N>) | |
| { | | { | |
| Iterator1 s1end = s1 + shape[N]; | | Iterator1 s1end = s1 + shape[N]; | |
| for(; s1 != s1end; ++s1, ++s2) | | for(; s1 != s1end; ++s1, ++s2) | |
| { | | { | |
| inspectTwoMultiArraysImpl(s1.begin(), shape, a1, | | inspectTwoMultiArraysImpl(s1.begin(), shape, a1, | |
| s2.begin(), a2, f, MetaInt<N-1>()); | | s2.begin(), a2, f, MetaInt<N-1>()); | |
| } | | } | |
| } | | } | |
| | | | |
|
| /** \brief Apply read-only functor to every element of a multi-dimensional | | /** \brief Call an analyzing functor at all corresponding elements of | |
| array. | | two multi-dimensional arrays. | |
| | | | |
| This function can be used to collect statistics of the array etc. | | This function can be used to collect statistics of the array etc. | |
| The results must be stored in the functor, which serves as a return | | The results must be stored in the functor, which serves as a return | |
| value. The arrays must be represented by | | value. The arrays must be represented by | |
| iterators compatible with \ref vigra::MultiIterator. | | iterators compatible with \ref vigra::MultiIterator. | |
| The function uses an accessor to access the pixel data. Note that the i
terator range | | The function uses an accessor to access the pixel data. Note that the i
terator range | |
| must be specified by a shape object, because otherwise we could not con
trol | | must be specified by a shape object, because otherwise we could not con
trol | |
| the range simultaneously in all dimensions (this is a necessary consequ
ence | | the range simultaneously in all dimensions (this is a necessary consequ
ence | |
| of the \ref vigra::MultiIterator design). | | of the \ref vigra::MultiIterator design). | |
| | | | |
| | | | |
| skipping to change at line 839 | | skipping to change at line 1502 | |
| class Iterator2, class Accessor2, | | class Iterator2, class Accessor2, | |
| class Functor> | | class Functor> | |
| void | | void | |
| inspectTwoMultiArrays(triple<Iterator1, Shape1, Accessor1> const &
s1, | | inspectTwoMultiArrays(triple<Iterator1, Shape1, Accessor1> const &
s1, | |
| pair<Iterator2, Accessor2> const & s2, Functo
r & f); | | pair<Iterator2, Accessor2> const & s2, Functo
r & f); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
|
| <b>\#include</b> "<a href="multi_pointoperators_8hxx-source.html">vigra
/multi_pointoperators.hxx</a>"br> | | <b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr
a/multi_pointoperators.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| typedef vigra::MultiArray<3, int> Array; | | typedef vigra::MultiArray<3, int> Array; | |
| Array array1(Array::size_type(100, 200, 50)), | | Array array1(Array::size_type(100, 200, 50)), | |
| array2(Array::size_type(100, 200, 50)); | | array2(Array::size_type(100, 200, 50)); | |
| | | | |
| // init functor | | // init functor | |
| SomeStatisticsFunctor stats(..); | | SomeStatisticsFunctor stats(..); | |
| | | | |
| | | | |
End of changes. 75 change blocks. |
| 128 lines changed or deleted | | 917 lines changed or added | |
|
| stdconvolution.hxx | | stdconvolution.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.0, Sep 10 2004 ) */ | | /* ( Version 1.3.1, Jan 06 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | /* You may use, modify, and distribute this software according */ | |
| /* to the terms stated in the LICENSE file included in */ | | /* to the terms stated in the LICENSE file included in */ | |
| /* the VIGRA distribution. */ | | /* the VIGRA distribution. */ | |
| /* */ | | /* */ | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | |
| | | | |
| skipping to change at line 88 | | skipping to change at line 88 | |
| sum += ak(xk) * src_acc(xxs); | | sum += ak(xk) * src_acc(xxs); | |
| ksum += ak(xk); | | ksum += ak(xk); | |
| } | | } | |
| } | | } | |
| | | | |
| // store average in destination pixel | | // store average in destination pixel | |
| dest_acc.set(DestTraits::fromRealPromote((norm / ksum) * sum), xd); | | dest_acc.set(DestTraits::fromRealPromote((norm / ksum) * sum), xd); | |
| | | | |
| } | | } | |
| | | | |
|
| | | #if 0 | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class KernelIterator, class KernelAccessor> | | class KernelIterator, class KernelAccessor> | |
| void internalPixelEvaluationByWrapReflectRepeat(int x, int y, int src_width
, int src_height, SrcIterator xs, | | void internalPixelEvaluationByWrapReflectRepeat(int x, int y, int src_width
, int src_height, SrcIterator xs, | |
| SrcAccessor src_acc, DestIt
erator xd, DestAccessor dest_acc, | | SrcAccessor src_acc, DestIt
erator xd, DestAccessor dest_acc, | |
| KernelIterator ki, Diff2D k
ul, Diff2D klr, KernelAccessor ak, | | KernelIterator ki, Diff2D k
ul, Diff2D klr, KernelAccessor ak, | |
| BorderTreatmentMode border) | | BorderTreatmentMode border) | |
| { | | { | |
| | | | |
| typedef typename | | typedef typename | |
| | | | |
| skipping to change at line 270 | | skipping to change at line 272 | |
| for( ; xx < kernel_width; ++xx, xxs.x += border_increment.third, xk
.x -= way_increment.x ) | | for( ; xx < kernel_width; ++xx, xxs.x += border_increment.third, xk
.x -= way_increment.x ) | |
| { | | { | |
| sum += ak(xk) * src_acc(xxs); | | sum += ak(xk) * src_acc(xxs); | |
| } | | } | |
| } | | } | |
| | | | |
| // store average in destination pixel | | // store average in destination pixel | |
| dest_acc.set(DestTraits::fromRealPromote(sum), xd); | | dest_acc.set(DestTraits::fromRealPromote(sum), xd); | |
| | | | |
| }// end of internalPixelEvaluationByWrapReflectRepeat | | }// end of internalPixelEvaluationByWrapReflectRepeat | |
|
| | | #endif /* #if 0 */ | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class KernelIterator, class KernelAccessor, | |
| | | class SumType> | |
| | | void | |
| | | internalPixelEvaluationByWrapReflectRepeat(SrcIterator xs, SrcAccessor src_ | |
| | | acc, | |
| | | KernelIterator xk, KernelAccessor ak, | |
| | | int left, int right, int kleft, int kright, | |
| | | int borderskipx, int borderinc, SumType & sum) | |
| | | { | |
| | | SrcIterator xxs = xs + left; | |
| | | KernelIterator xxk = xk - left; | |
| | | | |
| | | for(int xx = left; xx <= right; ++xx, ++xxs, --xxk) | |
| | | { | |
| | | sum += ak(xxk) * src_acc(xxs); | |
| | | } | |
| | | | |
| | | xxs = xs + left - borderskipx; | |
| | | xxk = xk - left + 1; | |
| | | for(int xx = left - 1; xx >= -kright; --xx, xxs -= borderinc, ++xxk) | |
| | | { | |
| | | sum += ak(xxk) * src_acc(xxs); | |
| | | } | |
| | | | |
| | | xxs = xs + right + borderskipx; | |
| | | xxk = xk - right - 1; | |
| | | for(int xx = right + 1; xx <= -kleft; ++xx, xxs += borderinc, --xxk) | |
| | | { | |
| | | sum += ak(xxk) * src_acc(xxs); | |
| | | } | |
| | | } | |
| | | | |
| /** \addtogroup StandardConvolution Two-dimensional convolution functions | | /** \addtogroup StandardConvolution Two-dimensional convolution functions | |
| | | | |
| Perform 2D non-separable convolution, with and without ROI mask. | | Perform 2D non-separable convolution, with and without ROI mask. | |
| | | | |
| These generic convolution functions implement | | These generic convolution functions implement | |
| the standard 2D convolution operation for images that fit | | the standard 2D convolution operation for images that fit | |
| into the required interface. Arbitrary ROI's are supported | | into the required interface. Arbitrary ROI's are supported | |
| by the mask version of the algorithm. | | by the mask version of the algorithm. | |
| The functions need a suitable 2D kernel to operate. | | The functions need a suitable 2D kernel to operate. | |
| | | | |
| skipping to change at line 392 | | skipping to change at line 427 | |
| | | | |
| <b> Preconditions:</b> | | <b> Preconditions:</b> | |
| | | | |
| \code | | \code | |
| kul.x <= 0 | | kul.x <= 0 | |
| kul.y <= 0 | | kul.y <= 0 | |
| klr.x >= 0 | | klr.x >= 0 | |
| klr.y >= 0 | | klr.y >= 0 | |
| src_lr.x - src_ul.x >= klr.x + kul.x + 1 | | src_lr.x - src_ul.x >= klr.x + kul.x + 1 | |
| src_lr.y - src_ul.y >= klr.y + kul.y + 1 | | src_lr.y - src_ul.y >= klr.y + kul.y + 1 | |
|
| border == BORDER_TREATMENT_CLIP || border == BORDER_TREATMENT_AVOID | | | |
| \endcode | | \endcode | |
| | | | |
| If border == BORDER_TREATMENT_CLIP: Sum of kernel elements must be | | If border == BORDER_TREATMENT_CLIP: Sum of kernel elements must be | |
| != 0. | | != 0. | |
| | | | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class KernelIterator, class KernelAccessor> | | class KernelIterator, class KernelAccessor> | |
| void convolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_
acc, | | void convolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_
acc, | |
| | | | |
| skipping to change at line 430 | | skipping to change at line 464 | |
| vigra_precondition(kul.x <= 0 && kul.y <= 0, | | vigra_precondition(kul.x <= 0 && kul.y <= 0, | |
| "convolveImage(): coordinates of " | | "convolveImage(): coordinates of " | |
| "kernel's upper left must be <= 0."); | | "kernel's upper left must be <= 0."); | |
| vigra_precondition(klr.x >= 0 && klr.y >= 0, | | vigra_precondition(klr.x >= 0 && klr.y >= 0, | |
| "convolveImage(): coordinates of " | | "convolveImage(): coordinates of " | |
| "kernel's lower right must be >= 0."); | | "kernel's lower right must be >= 0."); | |
| | | | |
| // use traits to determine SumType as to prevent possible overflow | | // use traits to determine SumType as to prevent possible overflow | |
| typedef typename | | typedef typename | |
| NumericTraits<typename SrcAccessor::value_type>::RealPromote SumTyp
e; | | NumericTraits<typename SrcAccessor::value_type>::RealPromote SumTyp
e; | |
|
| | | typedef typename | |
| | | NumericTraits<typename KernelAccessor::value_type>::RealPromote Ker | |
| | | nelSumType; | |
| typedef | | typedef | |
| NumericTraits<typename DestAccessor::value_type> DestTraits; | | NumericTraits<typename DestAccessor::value_type> DestTraits; | |
| | | | |
| // calculate width and height of the image | | // calculate width and height of the image | |
| int w = src_lr.x - src_ul.x; | | int w = src_lr.x - src_ul.x; | |
| int h = src_lr.y - src_ul.y; | | int h = src_lr.y - src_ul.y; | |
| | | | |
| // calculate width and height of the kernel | | // calculate width and height of the kernel | |
| int kernel_width = klr.x - kul.x + 1; | | int kernel_width = klr.x - kul.x + 1; | |
| int kernel_height = klr.y - kul.y + 1; | | int kernel_height = klr.y - kul.y + 1; | |
| | | | |
| vigra_precondition(w >= kernel_width && h >= kernel_height, | | vigra_precondition(w >= kernel_width && h >= kernel_height, | |
| "convolveImage(): kernel larger than image."); | | "convolveImage(): kernel larger than image."); | |
| | | | |
| int x,y; | | int x,y; | |
| | | | |
|
| // The start and endpoints of the image, that will be modified. | | KernelSumType norm = NumericTraits<KernelSumType>::zero(); | |
| // It's ever (0,0) and (w, h) | | if(border == BORDER_TREATMENT_CLIP) | |
| // except by AVOID treatment mode. | | { | |
| int ystart = (border == BORDER_TREATMENT_AVOID) ? klr.y : 0; | | // caluclate the sum of the kernel elements for renormalization | |
| int yend = (border == BORDER_TREATMENT_AVOID) ? h+kul.y : h; | | KernelIterator yk = ki + klr; | |
| int xstart = (border == BORDER_TREATMENT_AVOID) ? klr.x : 0; | | | |
| int xend = (border == BORDER_TREATMENT_AVOID) ? w+kul.x : w; | | | |
| | | | |
|
| // create y iterators (Ausser AVOID bleibt alles bei *_ul) | | //Die Summe der Punkte im Kernel wird ermittelt (= norm) | |
| DestIterator yd = dest_ul + Diff2D(xstart, ystart); | | for(y=0; y<kernel_height; ++y, --yk.y) | |
| SrcIterator ys = src_ul + Diff2D(xstart, ystart); | | { | |
| | | KernelIterator xk = yk; | |
| | | for(x=0; x<kernel_width; ++x, --xk.x) | |
| | | { | |
| | | norm += ak(xk); | |
| | | } | |
| | | } | |
| | | vigra_precondition(norm != NumericTraits<KernelSumType>::zero(), | |
| | | "convolveImage(): Cannot use BORDER_TREATMENT_CLIP with a DC-fr | |
| | | ee kernel"); | |
| | | } | |
| | | | |
|
| // Durchlauf | | // create iterators for the interior part of the image (where the kerne | |
| for(y=ystart; y < yend; ++y, ++ys.y, ++yd.y) | | l always fits into the image) | |
| | | DestIterator yd = dest_ul + Diff2D(klr.x, klr.y); | |
| | | SrcIterator ys = src_ul + Diff2D(klr.x, klr.y); | |
| | | SrcIterator send = src_lr + Diff2D(kul.x, kul.y); | |
| | | | |
| | | // iterate over the interior part | |
| | | for(; ys.y < send.y; ++ys.y, ++yd.y) | |
| { | | { | |
| // create x iterators | | // create x iterators | |
| DestIterator xd(yd); | | DestIterator xd(yd); | |
| SrcIterator xs(ys); | | SrcIterator xs(ys); | |
| | | | |
|
| for(x=xstart; x < xend; ++x, ++xs.x, ++xd.x) | | for(; xs.x < send.x; ++x, ++xs.x, ++xd.x) | |
| { | | { | |
| // init the sum | | // init the sum | |
| SumType sum = NumericTraits<SumType>::zero(); | | SumType sum = NumericTraits<SumType>::zero(); | |
| | | | |
|
| // how much of the kernel fits into the image ? | | SrcIterator yys = xs - klr; | |
| bool nearBorder = false; | | SrcIterator yyend = xs - kul; | |
| | | KernelIterator yk = ki + klr; | |
| nearBorder = (y<klr.y) || (h-y-1<-kul.y) || (x<klr.x) || (w-x-1 | | | |
| <-kul.x); | | | |
| | | | |
|
| if(!nearBorder) | | for(; yys.y <= yyend.y; ++yys.y, --yk.y) | |
| { | | { | |
|
| SrcIterator yys = xs - klr; | | typename SrcIterator::row_iterator xxs = yys.rowIterator(); | |
| KernelIterator yk = ki + klr; | | typename SrcIterator::row_iterator xxe = xxs + kernel_width | |
| | | ; | |
| | | typename KernelIterator::row_iterator xk = yk.rowIterator( | |
| | | ); | |
| | | | |
|
| int xx, yy; | | for(; xxs < xxe; ++xxs, --xk) | |
| for(yy=0; yy<kernel_height; ++yy, ++yys.y, --yk.y) | | | |
| { | | { | |
|
| SrcIterator xxs = yys; | | sum += ak(xk) * src_acc(xxs); | |
| KernelIterator xk = yk; | | | |
| | | | |
| for(xx=0; xx<kernel_width; ++xx, ++xxs.x, --xk.x) | | | |
| { | | | |
| sum += ak(xk) * src_acc(xxs); | | | |
| } | | | |
| } | | } | |
|
| | | } | |
| | | | |
|
| // store average in destination pixel | | // store convolution result in destination pixel | |
| dest_acc.set(DestTraits::fromRealPromote(sum), xd); | | dest_acc.set(DestTraits::fromRealPromote(sum), xd); | |
| | | } | |
| | | } | |
| | | | |
| | | if(border == BORDER_TREATMENT_AVOID) | |
| | | return; // skip processing near the border | |
| | | | |
| | | int interiorskip = w + kul.x - klr.x - 1; | |
| | | int borderskipx; | |
| | | int borderskipy; | |
| | | int borderinc; | |
| | | if(border == BORDER_TREATMENT_REPEAT) | |
| | | { | |
| | | borderskipx = 0; | |
| | | borderskipy = 0; | |
| | | borderinc = 0; | |
| | | } | |
| | | else if(border == BORDER_TREATMENT_REFLECT) | |
| | | { | |
| | | borderskipx = -1; | |
| | | borderskipy = -1; | |
| | | borderinc = -1; | |
| | | } | |
| | | else if(border == BORDER_TREATMENT_WRAP) | |
| | | { | |
| | | borderskipx = -w+1; | |
| | | borderskipy = -h+1; | |
| | | borderinc = 1; | |
| | | } | |
| | | | |
| | | // create iterators for the entire image | |
| | | yd = dest_ul; | |
| | | ys = src_ul; | |
| | | | |
| | | // go over the entire image (but skip the already computed points in th | |
| | | e loop) | |
| | | for(y=0; y < h; ++y, ++ys.y, ++yd.y) | |
| | | { | |
| | | int top = std::max(-klr.y, src_ul.y - ys.y); | |
| | | int bottom = std::min(-kul.y, src_lr.y - ys.y - 1); | |
| | | | |
| | | // create x iterators | |
| | | DestIterator xd(yd); | |
| | | SrcIterator xs(ys); | |
| | | | |
| | | for(x=0; x < w; ++x, ++xs.x, ++xd.x) | |
| | | { | |
| | | // check if we are away from the border | |
| | | if(y >= klr.y && y < h+kul.y && x == klr.x) | |
| | | { | |
| | | // yes => skip the already computed points | |
| | | x += interiorskip; | |
| | | xs.x += interiorskip; | |
| | | xd.x += interiorskip; | |
| | | continue; | |
| | | } | |
| | | if (border == BORDER_TREATMENT_CLIP) | |
| | | { | |
| | | internalPixelEvaluationByClip(x, y, w, h, xs, src_acc, xd, | |
| | | dest_acc, ki, kul, klr, ak, norm); | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| if (border == BORDER_TREATMENT_CLIP) | | int left = std::max(-klr.x, src_ul.x - xs.x); | |
| { | | int right = std::min(-kul.x, src_lr.x - xs.x - 1); | |
| | | | |
| typedef typename | | | |
| NumericTraits<typename KernelAccessor::value_type>: | | | |
| :RealPromote KSumType; | | | |
| KSumType norm = NumericTraits<KSumType>::zero(); | | | |
| | | | |
| int kernel_width = klr.x - kul.x + 1; | | | |
| int kernel_height = klr.y - kul.y + 1; | | | |
| int xx, yy; | | | |
| KernelIterator yk = ki + klr; | | | |
| | | | |
|
| //Die Summe der Punkte im Kernel wird ermittelt (= norm | | // init the sum | |
| ) | | SumType sum = NumericTraits<SumType>::zero(); | |
| for(yy=0; yy<kernel_height; ++yy, --yk.y) | | | |
| { | | | |
| KernelIterator xk = yk; | | | |
| for(xx=0; xx<kernel_width; ++xx, --xk.x) | | | |
| { | | | |
| norm += ak(xk); | | | |
| } | | | |
| } | | | |
| | | | |
|
| internalPixelEvaluationByClip(x, y, w, h, xs, src_acc, | | // create iterators for the part of the kernel that fits in | |
| xd, dest_acc, ki, kul, klr, ak, norm); | | to the image | |
| | | SrcIterator yys = xs + Size2D(0, top); | |
| | | KernelIterator yk = ki - Size2D(0, top); | |
| | | | |
|
| | | int yy; | |
| | | for(yy = top; yy <= bottom; ++yy, ++yys.y, --yk.y) | |
| | | { | |
| | | internalPixelEvaluationByWrapReflectRepeat(yys.rowItera | |
| | | tor(), src_acc, yk.rowIterator(), ak, | |
| | | left, right, kul.x, klr.x, borderskipx, borderinc, | |
| | | sum); | |
| } | | } | |
|
| else | | yys = xs + Size2D(0, top - borderskipy); | |
| | | yk = ki - Size2D(0, top - 1); | |
| | | for(yy = top - 1; yy >= -klr.y; --yy, yys.y -= borderinc, + | |
| | | +yk.y) | |
| { | | { | |
|
| | | internalPixelEvaluationByWrapReflectRepeat(yys.rowItera | |
| | | tor(), src_acc, yk.rowIterator(), ak, | |
| | | left, right, kul.x, klr.x, borderskipx, borderinc, | |
| | | sum); | |
| | | } | |
| | | yys = xs + Size2D(0, bottom + borderskipy); | |
| | | yk = ki - Size2D(0, bottom + 1); | |
| | | for(yy = bottom + 1; yy <= -kul.y; ++yy, yys.y += borderinc | |
| | | , --yk.y) | |
| | | { | |
| | | internalPixelEvaluationByWrapReflectRepeat(yys.rowItera | |
| | | tor(), src_acc, yk.rowIterator(), ak, | |
| | | left, right, kul.x, klr.x, borderskipx, borderinc, | |
| | | sum); | |
| | | } | |
| | | | |
|
| internalPixelEvaluationByWrapReflectRepeat(x, y, w, h, | | // store convolution result in destination pixel | |
| xs, src_acc, xd, dest_acc, ki, kul, klr, ak, border); | | dest_acc.set(DestTraits::fromRealPromote(sum), xd); | |
| | | | |
|
| } | | // internalPixelEvaluationByWrapReflectRepeat(x, y, w, h, xs
, src_acc, xd, dest_acc, ki, kul, klr, ak, border); | |
| } | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class KernelIterator, class KernelAccessor> | | class KernelIterator, class KernelAccessor> | |
| inline | | inline | |
| void convolveImage( | | void convolveImage( | |
| | | | |
| skipping to change at line 549 | | skipping to change at line 652 | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D, | | tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D, | |
| BorderTreatmentMode> kernel) | | BorderTreatmentMode> kernel) | |
| { | | { | |
| convolveImage(src.first, src.second, src.third, | | convolveImage(src.first, src.second, src.third, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
| kernel.first, kernel.second, kernel.third, | | kernel.first, kernel.second, kernel.third, | |
| kernel.fourth, kernel.fifth); | | kernel.fourth, kernel.fifth); | |
| } | | } | |
| | | | |
|
| /** \brief Performs a 2 dimensional convolution of the source image within | | /** \brief Performs a 2-dimensional normalized convolution, i.e. convolutio | |
| the | | n with a mask image. | |
| given ROI mask using the given kernel. | | | |
| | | | |
|
| The ROI is applied as follows: | | This functions computes | |
| Only pixel under the ROI are used in the calculations. Whenever a part | | <a href ="http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/PIROD | |
| of the | | DI1/NormConv/NormConv.html">normalized | |
| kernel lies outside the ROI, the kernel is renormalized to its original | | convolution</a> as defined in | |
| norm (analogous to the CLIP \ref BorderTreatmentMode). An convolution r | | Knutsson, H. and Westin, C-F.: <i>Normalized and differential convoluti | |
| esult is | | on: | |
| calculated whenever at the current kernel position <i>at least one pixe | | Methods for Interpolation and Filtering of incomplete and uncertain dat | |
| l of the | | a</i>. | |
| kernel is within the ROI</i>. I.e., pixels not under the ROI may nevert | | Proc. of the IEEE Conf. on Computer Vision and Pattern Recognition, 199 | |
| heless | | 3, 515-523. | |
| be assigned a value if they are <i>near</i> the ROI. Thus, this algorit | | | |
| hm is also | | The mask image must be binary and encodes which pixels of the original | |
| useful as an interpolator. To get rid of the results outside the ROI ma | | image | |
| sk, a | | are valid. It is used as follows: | |
| subsequent \ref copyImageIf() must be performed. | | Only pixel under the mask are used in the calculations. Whenever a part | |
| | | of the | |
| | | kernel lies outside the mask, it is ignored, and the kernel is renormal | |
| | | ized to its | |
| | | original norm (analogous to the CLIP \ref BorderTreatmentMode). Thus, a | |
| | | useful convolution | |
| | | result is computed whenever <i>at least one valid pixel is within the c | |
| | | urrent window</i> | |
| | | Thus, destination pixels not under the mask still receive a value if th | |
| | | ey are <i>near</i> | |
| | | the mask. Therefore, this algorithm is useful as an interpolator of spa | |
| | | rse input data. | |
| | | If you are only interested in the destination values under the mask, yo | |
| | | u can perform | |
| | | a subsequent \ref copyImageIf(). | |
| | | | |
| The KernelIterator must point to the center of the kernel, and | | The KernelIterator must point to the center of the kernel, and | |
| the kernel's size is given by its upper left (x and y of distance <= 0)
and | | the kernel's size is given by its upper left (x and y of distance <= 0)
and | |
| lower right (distance >= 0) corners. The image must always be larger th
an the | | lower right (distance >= 0) corners. The image must always be larger th
an the | |
| kernel. At those positions where the kernel does not completely fit | | kernel. At those positions where the kernel does not completely fit | |
| into the image, the specified \ref BorderTreatmentMode is | | into the image, the specified \ref BorderTreatmentMode is | |
| applied. Only BORDER_TREATMENT_CLIP and BORDER_TREATMENT_AVOID are curr
ently | | applied. Only BORDER_TREATMENT_CLIP and BORDER_TREATMENT_AVOID are curr
ently | |
| supported. | | supported. | |
| | | | |
| The images's pixel type (SrcAccessor::value_type) must be a | | The images's pixel type (SrcAccessor::value_type) must be a | |
| | | | |
| skipping to change at line 588 | | skipping to change at line 698 | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class MaskIterator, class MaskAccessor, | | class MaskIterator, class MaskAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class KernelIterator, class KernelAccessor> | | class KernelIterator, class KernelAccessor> | |
| void | | void | |
|
| convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAc | | normalizedConvolveImage(SrcIterator src_ul, SrcIterator src_lr, Src | |
| cessor src_acc, | | Accessor src_acc, | |
| MaskIterator mul, MaskAccessor am, | | MaskIterator mul, MaskAccessor am, | |
| DestIterator dest_ul, DestAccessor dest_acc, | | DestIterator dest_ul, DestAccessor dest_acc | |
| KernelIterator ki, KernelAccessor ak, | | , | |
| Diff2D kul, Diff2D klr, BorderTreatmentMode b | | KernelIterator ki, KernelAccessor ak, | |
| order); | | Diff2D kul, Diff2D klr, BorderTreatmentMode | |
| | | border); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class MaskIterator, class MaskAccessor, | | class MaskIterator, class MaskAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class KernelIterator, class KernelAccessor> | | class KernelIterator, class KernelAccessor> | |
| inline | | inline | |
|
| void convolveImageWithMask(triple<SrcIterator, SrcIterator, SrcAcce | | void normalizedConvolveImage(triple<SrcIterator, SrcIterator, SrcAc | |
| ssor> src, | | cessor> src, | |
| pair<MaskIterator, MaskAccessor> mask, | | pair<MaskIterator, MaskAccessor> mask, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| tuple5<KernelIterator, KernelAccessor, D | | tuple5<KernelIterator, KernelAccessor, | |
| iff2D, Diff2D, | | Diff2D, Diff2D, | |
| BorderTreatmentMode> kernel); | | BorderTreatmentMode> kernel); | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="stdconvolution_8hxx-source.html">vigra/stdco
nvolution.hxx</a>"<br> | | <b>\#include</b> "<a href="stdconvolution_8hxx-source.html">vigra/stdco
nvolution.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| vigra::FImage src(w,h), dest(w,h); | | vigra::FImage src(w,h), dest(w,h); | |
| | | | |
| skipping to change at line 630 | | skipping to change at line 740 | |
| ... | | ... | |
| | | | |
| // define 3x3 binomial filter | | // define 3x3 binomial filter | |
| vigra::Kernel2D<float> binom; | | vigra::Kernel2D<float> binom; | |
| | | | |
| binom.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = // upper left and
lower right | | binom.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = // upper left and
lower right | |
| 0.0625, 0.125, 0.0625, | | 0.0625, 0.125, 0.0625, | |
| 0.125, 0.25, 0.125, | | 0.125, 0.25, 0.125, | |
| 0.0625, 0.125, 0.0625; | | 0.0625, 0.125, 0.0625; | |
| | | | |
|
| vigra::convolveImage(srcImageRange(src), maskImage(mask), destImage(des
t), kernel2d(binom)); | | vigra::normalizedConvolveImage(srcImageRange(src), maskImage(mask), des
tImage(dest), kernel2d(binom)); | |
| \endcode | | \endcode | |
| | | | |
| <b> Required Interface:</b> | | <b> Required Interface:</b> | |
| | | | |
| \code | | \code | |
| ImageIterator src_ul, src_lr; | | ImageIterator src_ul, src_lr; | |
| ImageIterator mul; | | ImageIterator mul; | |
| ImageIterator dest_ul; | | ImageIterator dest_ul; | |
| ImageIterator ik; | | ImageIterator ik; | |
| | | | |
| | | | |
| skipping to change at line 685 | | skipping to change at line 795 | |
| \endcode | | \endcode | |
| | | | |
| Sum of kernel elements must be != 0. | | Sum of kernel elements must be != 0. | |
| | | | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class MaskIterator, class MaskAccessor, | | class MaskIterator, class MaskAccessor, | |
| class KernelIterator, class KernelAccessor> | | class KernelIterator, class KernelAccessor> | |
| void | | void | |
|
| convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor s | | normalizedConvolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor | |
| rc_acc, | | src_acc, | |
| MaskIterator mul, MaskAccessor am, | | MaskIterator mul, MaskAccessor am, | |
| DestIterator dest_ul, DestAccessor dest_acc, | | DestIterator dest_ul, DestAccessor dest_acc, | |
| KernelIterator ki, KernelAccessor ak, | | KernelIterator ki, KernelAccessor ak, | |
| Diff2D kul, Diff2D klr, BorderTreatmentMode border) | | Diff2D kul, Diff2D klr, BorderTreatmentMode border) | |
| { | | { | |
| vigra_precondition((border == BORDER_TREATMENT_CLIP || | | vigra_precondition((border == BORDER_TREATMENT_CLIP || | |
| border == BORDER_TREATMENT_AVOID), | | border == BORDER_TREATMENT_AVOID), | |
|
| "convolveImageWithMask(): " | | "normalizedConvolveImage(): " | |
| "Border treatment must be BORDER_TREATMENT_CLIP or B
ORDER_TREATMENT_AVOID."); | | "Border treatment must be BORDER_TREATMENT_CLIP or B
ORDER_TREATMENT_AVOID."); | |
| | | | |
| vigra_precondition(kul.x <= 0 && kul.y <= 0, | | vigra_precondition(kul.x <= 0 && kul.y <= 0, | |
|
| "convolveImageWithMask(): left borders must be <= 0.
"); | | "normalizedConvolveImage(): left borders must be <=
0."); | |
| vigra_precondition(klr.x >= 0 && klr.y >= 0, | | vigra_precondition(klr.x >= 0 && klr.y >= 0, | |
|
| "convolveImageWithMask(): right borders must be >= 0
."); | | "normalizedConvolveImage(): right borders must be >=
0."); | |
| | | | |
| // use traits to determine SumType as to prevent possible overflow | | // use traits to determine SumType as to prevent possible overflow | |
| typedef typename | | typedef typename | |
| NumericTraits<typename SrcAccessor::value_type>::RealPromote SumTyp
e; | | NumericTraits<typename SrcAccessor::value_type>::RealPromote SumTyp
e; | |
| typedef typename | | typedef typename | |
| NumericTraits<typename KernelAccessor::value_type>::RealPromote KSu
mType; | | NumericTraits<typename KernelAccessor::value_type>::RealPromote KSu
mType; | |
| typedef | | typedef | |
| NumericTraits<typename DestAccessor::value_type> DestTraits; | | NumericTraits<typename DestAccessor::value_type> DestTraits; | |
| | | | |
| // calculate width and height of the image | | // calculate width and height of the image | |
| | | | |
| skipping to change at line 766 | | skipping to change at line 876 | |
| | | | |
| bool first = true; | | bool first = true; | |
| // init the sum | | // init the sum | |
| SumType sum; | | SumType sum; | |
| KSumType ksum; | | KSumType ksum; | |
| | | | |
| SrcIterator yys = xs + Diff2D(x0, y0); | | SrcIterator yys = xs + Diff2D(x0, y0); | |
| MaskIterator yym = xm + Diff2D(x0, y0); | | MaskIterator yym = xm + Diff2D(x0, y0); | |
| KernelIterator yk = ki - Diff2D(x0, y0); | | KernelIterator yk = ki - Diff2D(x0, y0); | |
| | | | |
|
| int xx, yy, kernel_width, kernel_height; | | int xx, kernel_width, kernel_height; | |
| kernel_width = x1 - x0 + 1; | | kernel_width = x1 - x0 + 1; | |
| kernel_height = y1 - y0 + 1; | | kernel_height = y1 - y0 + 1; | |
| for(yy=0; yy<kernel_height; ++yy, ++yys.y, --yk.y, ++yym.y) | | for(yy=0; yy<kernel_height; ++yy, ++yys.y, --yk.y, ++yym.y) | |
| { | | { | |
|
| SrcIterator xxs = yys; | | typename SrcIterator::row_iterator xxs = yys.rowIterator(); | |
| MaskIterator xxm = yym; | | typename SrcIterator::row_iterator xxend = xxs + kernel_wid | |
| KernelIterator xk = yk; | | th; | |
| | | typename MaskIterator::row_iterator xxm = yym.rowIterator() | |
| | | ; | |
| | | typename KernelIterator::row_iterator xk = yk.rowIterator( | |
| | | ); | |
| | | | |
|
| for(xx=0; xx<kernel_width; ++xx, ++xxs.x, --xk.x, ++xxm.x) | | for(xx=0; xxs < xxend; ++xxs.x, --xk.x, ++xxm.x) | |
| { | | { | |
| if(!am(xxm)) continue; | | if(!am(xxm)) continue; | |
| | | | |
| if(first) | | if(first) | |
| { | | { | |
| sum = ak(xk) * src_acc(xxs); | | sum = ak(xk) * src_acc(xxs); | |
| ksum = ak(xk); | | ksum = ak(xk); | |
| first = false; | | first = false; | |
| } | | } | |
| else | | else | |
| | | | |
| skipping to change at line 807 | | skipping to change at line 918 | |
| } | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class MaskIterator, class MaskAccessor, | | class MaskIterator, class MaskAccessor, | |
| class KernelIterator, class KernelAccessor> | | class KernelIterator, class KernelAccessor> | |
| inline | | inline | |
|
| | | void normalizedConvolveImage( | |
| | | triple<SrcIterator, SrcIterator, SrcAccessor> sr | |
| | | c, | |
| | | pair<MaskIterator, MaskAccessor> mask, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | tuple5<KernelIterator, KernelAccessor, Diff2D, D | |
| | | iff2D, | |
| | | BorderTreatmentMode> kernel) | |
| | | { | |
| | | normalizedConvolveImage(src.first, src.second, src.third, | |
| | | mask.first, mask.second, | |
| | | dest.first, dest.second, | |
| | | kernel.first, kernel.second, kernel.third, | |
| | | kernel.fourth, kernel.fifth); | |
| | | } | |
| | | | |
| | | /** \brief Deprecated name of 2-dimensional normalized convolution, i.e. co | |
| | | nvolution with a mask image. | |
| | | | |
| | | See \ref normalizedConvolveImage() for documentation. | |
| | | | |
| | | <b> Declarations:</b> | |
| | | | |
| | | pass arguments explicitly: | |
| | | \code | |
| | | namespace vigra { | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class MaskIterator, class MaskAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class KernelIterator, class KernelAccessor> | |
| | | void | |
| | | convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAc | |
| | | cessor src_acc, | |
| | | MaskIterator mul, MaskAccessor am, | |
| | | DestIterator dest_ul, DestAccessor dest_acc, | |
| | | KernelIterator ki, KernelAccessor ak, | |
| | | Diff2D kul, Diff2D klr, BorderTreatmentMode b | |
| | | order); | |
| | | } | |
| | | \endcode | |
| | | | |
| | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| | | \code | |
| | | namespace vigra { | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class MaskIterator, class MaskAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class KernelIterator, class KernelAccessor> | |
| | | inline | |
| | | void convolveImageWithMask(triple<SrcIterator, SrcIterator, SrcAcce | |
| | | ssor> src, | |
| | | pair<MaskIterator, MaskAccessor> mask, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | tuple5<KernelIterator, KernelAccessor, D | |
| | | iff2D, Diff2D, | |
| | | BorderTreatmentMode> kernel); | |
| | | } | |
| | | \endcode | |
| | | */ | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class MaskIterator, class MaskAccessor, | |
| | | class KernelIterator, class KernelAccessor> | |
| | | inline void | |
| | | convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor s | |
| | | rc_acc, | |
| | | MaskIterator mul, MaskAccessor am, | |
| | | DestIterator dest_ul, DestAccessor dest_acc, | |
| | | KernelIterator ki, KernelAccessor ak, | |
| | | Diff2D kul, Diff2D klr, BorderTreatmentMode border) | |
| | | { | |
| | | normalizedConvolveImage(src_ul, src_lr, src_acc, | |
| | | mul, am, | |
| | | dest_ul, dest_acc, | |
| | | ki, ak, kul, klr, border); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class MaskIterator, class MaskAccessor, | |
| | | class KernelIterator, class KernelAccessor> | |
| | | inline | |
| void convolveImageWithMask( | | void convolveImageWithMask( | |
| triple<SrcIterator, SrcIterator, SrcAccessor> sr
c, | | triple<SrcIterator, SrcIterator, SrcAccessor> sr
c, | |
| pair<MaskIterator, MaskAccessor> mask, | | pair<MaskIterator, MaskAccessor> mask, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| tuple5<KernelIterator, KernelAccessor, Diff2D, D
iff2D, | | tuple5<KernelIterator, KernelAccessor, Diff2D, D
iff2D, | |
| BorderTreatmentMode> kernel) | | BorderTreatmentMode> kernel) | |
| { | | { | |
|
| convolveImageWithMask(src.first, src.second, src.third, | | normalizedConvolveImage(src.first, src.second, src.third, | |
| mask.first, mask.second, | | mask.first, mask.second, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
| kernel.first, kernel.second, kernel.third, | | kernel.first, kernel.second, kernel.third, | |
| kernel.fourth, kernel.fifth); | | kernel.fourth, kernel.fifth); | |
| } | | } | |
| | | | |
| //@} | | //@} | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* Kernel2D */ | | /* Kernel2D */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| | | | |
End of changes. 38 change blocks. |
| 114 lines changed or deleted | | 329 lines changed or added | |
|