/************************************************************************/ /* */ /* Copyright 1998-2002 by Ullrich Koethe */ /* Cognitive Systems Group, University of Hamburg, Germany */ /* */ /* This file is part of the VIGRA computer vision library. */ /* The VIGRA Website is */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* Please direct questions, bug reports, and contributions to */ /* koethe@informatik.uni-hamburg.de or */ /* vigra@kogs1.informatik.uni-hamburg.de */ /* */ /* Permission is hereby granted, free of charge, to any person */ /* obtaining a copy of this software and associated documentation */ /* files (the "Software"), to deal in the Software without */ /* restriction, including without limitation the rights to use, */ /* copy, modify, merge, publish, distribute, sublicense, and/or */ /* sell copies of the Software, and to permit persons to whom the */ /* Software is furnished to do so, subject to the following */ /* conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the */ /* Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* OTHER DEALINGS IN THE SOFTWARE. */ /* */ /************************************************************************/ #ifndef VIGRA_TRANSFORMIMAGE_HXX #define VIGRA_TRANSFORMIMAGE_HXX #include "vigra/utilities.hxx" #include "vigra/numerictraits.hxx" #include "vigra/iteratortraits.hxx" #include "vigra/rgbvalue.hxx" #include "vigra/functortraits.hxx" namespace vigra { /** \addtogroup TransformAlgo Algorithms to Transform Images Apply functor to calculate a pixelwise transformation of one image @{ */ /********************************************************/ /* */ /* transformLine */ /* */ /********************************************************/ template void transformLine(SrcIterator s, SrcIterator send, SrcAccessor src, DestIterator d, DestAccessor dest, Functor const & f) { for(; s != send; ++s, ++d) dest.set(f(src(s)), d); } template void transformLineIf(SrcIterator s, SrcIterator send, SrcAccessor src, MaskIterator m, MaskAccessor mask, DestIterator d, DestAccessor dest, Functor const & f) { for(; s != send; ++s, ++d, ++m) if(mask(m)) dest.set(f(src(s)), d); } /********************************************************/ /* */ /* transformImage */ /* */ /********************************************************/ /** \brief Apply unary point transformation to each pixel. The transformation given by the functor is applied to every source pixel and the result written into the corresponding destination pixel. The function uses accessors to access the pixel data. Note that the unary functors of the STL can be used in addition to the functors specifically defined in \ref TransformFunctor. Creation of new functors is easiest by using \ref FunctorExpressions. Declarations: pass arguments explicitly: \code namespace vigra { template void transformImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestAccessor da, Functor const & f) } \endcode use argument objects in conjunction with \ref ArgumentObjectFactories: \code namespace vigra { template void transformImage(triple src, pair dest, Functor const & f) } \endcode Usage: \#include "vigra/transformimage.hxx"
Namespace: vigra \code #include // for sqrt() vigra::transformImage(srcImageRange(src), destImage(dest), (double(*)(double))&std::sqrt ); \endcode Required Interface: \code SrcImageIterator src_upperleft, src_lowerright; DestImageIterator dest_upperleft; SrcImageIterator::row_iterator sx = src_upperleft.rowIterator(); DestImageIterator::row_iterator dx = dest_upperleft.rowIterator(); SrcAccessor src_accessor; DestAccessor dest_accessor; Functor functor; dest_accessor.set(functor(src_accessor(sx)), dx); \endcode */ template void transformImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestAccessor da, Functor const & f) { int w = src_lowerright.x - src_upperleft.x; for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y) { transformLine(src_upperleft.rowIterator(), src_upperleft.rowIterator() + w, sa, dest_upperleft.rowIterator(), da, f); } } template inline void transformImage(triple src, pair dest, Functor const & f) { transformImage(src.first, src.second, src.third, dest.first, dest.second, f); } /********************************************************/ /* */ /* transformImageIf */ /* */ /********************************************************/ /** \brief Apply unary point transformation to each pixel within the ROI (i.e., where the mask is non-zero). The transformation given by the functor is applied to every source pixel in the ROI (i.e. when the return vlaue of the mask's accessor is not zero) and the result is written into the corresponding destination pixel. The function uses accessors to access the pixel data. Note that the unary functors of the STL can be used in addition to the functors specifically defined in \ref TransformFunctor. Creation of new functors is easiest by using \ref FunctorExpressions. Declarations: pass arguments explicitly: \code namespace vigra { template void transformImageIf(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, MaskImageIterator mask_upperleft, MaskAccessor ma, DestImageIterator dest_upperleft, DestAccessor da, Functor const & f) } \endcode use argument objects in conjunction with \ref ArgumentObjectFactories: \code namespace vigra { template void transformImageIf(triple src, pair mask, pair dest, Functor const & f) } \endcode Usage: \#include "vigra/transformimage.hxx"
Namespace: vigra \code #include // for sqrt() vigra::transformImageIf(srcImageRange(src), maskImage(mask), destImage(dest), (double(*)(double))&std::sqrt ); \endcode Required Interface: \code SrcImageIterator src_upperleft, src_lowerright; DestImageIterator dest_upperleft; MaskImageIterator mask_upperleft; SrcImageIterator::row_iterator sx = src_upperleft.rowIterator(); MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator(); DestImageIterator::row_iterator dx = dest_upperleft.rowIterator(); SrcAccessor src_accessor; DestAccessor dest_accessor; MaskAccessor mask_accessor; Functor functor; if(mask_accessor(mx)) dest_accessor.set(functor(src_accessor(sx)), dx); \endcode */ template void transformImageIf(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, MaskImageIterator mask_upperleft, MaskAccessor ma, DestImageIterator dest_upperleft, DestAccessor da, Functor const & f) { int w = src_lowerright.x - src_upperleft.x; for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++mask_upperleft.y, ++dest_upperleft.y) { transformLineIf(src_upperleft.rowIterator(), src_upperleft.rowIterator() + w, sa, mask_upperleft.rowIterator(), ma, dest_upperleft.rowIterator(), da, f); } } template inline void transformImageIf(triple src, pair mask, pair dest, Functor const & f) { transformImageIf(src.first, src.second, src.third, mask.first, mask.second, dest.first, dest.second, f); } /********************************************************/ /* */ /* gradientBasedTransform */ /* */ /********************************************************/ /** \brief Calculate a function of the image gradient. The gradient and the function represented by Functor f are calculated in one go: for each location, the symmetric difference in x- and y-directions (asymmetric difference at the image borders) are passed to the given functor, and the result is written the destination image. Functors to be used with this function include \ref MagnitudeFunctor and \ref RGBGradientMagnitudeFunctor. Declarations: pass arguments explicitly: \code namespace vigra { template void gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa, DestImageIterator destul, DestAccessor da, Functor const & f) } \endcode use argument objects in conjunction with \ref ArgumentObjectFactories: \code namespace vigra { template void gradientBasedTransform(triple src, pair dest, Functor const & const & f) } \endcode Usage: \#include "vigra/transformimage.hxx" \code vigra::FImage src(w,h), magnitude(w,h); ... gradientBasedTransform(srcImageRange(src), destImage(magnitude), vigra::MagnitudeFunctor()); \endcode Required Interface: \code SrcImageIterator is, isend; DestImageIterator id; SrcAccessor src_accessor; DestAccessor dest_accessor; typename NumericTraits::RealPromote diffx, diffy; diffx = src_accessor(is, Diff2D(-1,0)) - src_accessor(is, Diff2D(1,0)); diffy = src_accessor(is, Diff2D(0,-1)) - src_accessor(is, Diff2D(0,1)); Functor f; dest_accessor.set(f(diffx, diffy), id); \endcode */ template void gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa, DestImageIterator destul, DestAccessor da, Functor const & grad) { int w = srclr.x - srcul.x; int h = srclr.y - srcul.y; int x,y; SrcImageIterator sy = srcul; DestImageIterator dy = destul; static const Diff2D left(-1,0); static const Diff2D right(1,0); static const Diff2D top(0,-1); static const Diff2D bottom(0,1); typename NumericTraits::RealPromote diffx, diffy; SrcImageIterator sx = sy; DestImageIterator dx = dy; diffx = sa(sx) - sa(sx, right); diffy = sa(sx) - sa(sx, bottom); da.set(grad(diffx, diffy), dx); for(x=2, ++sx.x, ++dx.x; x inline void gradientBasedTransform(triple src, pair dest, Functor const & grad) { gradientBasedTransform(src.first, src.second, src.third, dest.first, dest.second, grad); } /** @} */ /** \addtogroup TransformFunctor Functors to Transform Images Note that the unary functors of the STL can also be used in connection with \ref transformImage(). */ //@{ template class LinearIntensityTransform { public: /* the functors argument type (actually, since operator() is a template, much more types are possible) */ typedef DestValueType argument_type; /* the functors result type */ typedef DestValueType result_type; /* \deprecated use argument_type and result_type */ typedef DestValueType value_type; /* type of the offset (used in internal calculations to prevent overflows and minimize round-off errors). */ typedef typename NumericTraits::RealPromote argument_promote; /* type of the scale factor */ typedef Multiplier scalar_multiplier_type; /* init scale and offset */ LinearIntensityTransform(scalar_multiplier_type scale, argument_promote offset) : scale_(scale), offset_(offset) {} /* calculate transform */ template result_type operator()(SrcValueType const & s) const { return NumericTraits::fromRealPromote(scale_ * (s + offset_)); } private: scalar_multiplier_type scale_; argument_promote offset_; }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isUnaryFunctor; }; template class ScalarIntensityTransform { public: /* the functors argument type (actually, since operator() is a template, much more types are possible) */ typedef DestValueType argument_type; /* the functors result type */ typedef DestValueType result_type; /* \deprecated use argument_type and result_type */ typedef DestValueType value_type; /* type of the scale factor */ typedef Multiplier scalar_multiplier_type; /* init scale */ ScalarIntensityTransform(scalar_multiplier_type scale) : scale_(scale) {} /* calculate transform */ template result_type operator()(SrcValueType const & s) const { return NumericTraits::fromRealPromote(scale_ * s); } private: scalar_multiplier_type scale_; }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isUnaryFunctor; }; /********************************************************/ /* */ /* linearIntensityTransform */ /* */ /********************************************************/ /** \brief Apply a linear transform to the source pixel values Factory function for a functor that linearly transforms the source pixel values. The functor applies the transform 'destvalue = scale * (srcvalue + offset)' to every pixel. This can, for example, be used to transform images into the visible range 0...255 or to invert an image. If you leave out the second parameter / offset, you will get an optimized version of the functor which only scales by the given factor, however you have to make the template parameter (pixel type) explicit then. Traits defined: FunctorTraits::isUnaryFunctor is true (VigraTrueType) Declaration: \code namespace vigra { template LinearIntensityTransform linearIntensityTransform(Multiplier scale, DestValueType offset); template ScalarIntensityTransform linearIntensityTransform(Multiplier scale); } \endcode Usage: \#include "vigra/transformimage.hxx"
Namespace: vigra \code vigra::IImage src(width, height); vigra::BImage dest(width, height); ... vigra::FindMinMax minmax; // functor to find range vigra::inspectImage(srcImageRange(src), minmax); // find original range // transform to range 0...255 vigra::transformImage(srcImageRange(src), destImage(dest), linearIntensityTransform( 255.0 / (minmax.max - minmax.min), // scaling - minmax.min)); // offset \endcode The one-parameter version can be used like this: \code // scale from 0..255 to 0..1.0 FImage dest(src.size()); vigra::transformImage(srcImageRange(src), destImage(dest), linearIntensityTransform(1.0 / 255)); \endcode Required Interface: The source and destination value types must be models of \ref LinearSpace in both cases. */ template LinearIntensityTransform linearIntensityTransform(Multiplier scale, DestValueType offset) { return LinearIntensityTransform(scale, offset); } template ScalarIntensityTransform linearIntensityTransform(Multiplier scale) { return ScalarIntensityTransform(scale); } /********************************************************/ /* */ /* linearRangeMapping */ /* */ /********************************************************/ /** \brief Map a source intensity range linearly to a destination range. Factory function for a functor that linearly transforms the source pixel values. The functor applies the transform 'destvalue = scale * (srcvalue + offset)' to every pixel, where scale = (dest_max - dest_min) / (src_max - src_min) and offset = dest_min / scale - src_min. As a result, the pixel values src_max, src_min in the source image are mapped onto dest_max, dest_min respectively. This works for scalar as well as vector pixel types. Declaration: \code namespace vigra { template LinearIntensityTransform::RealPromote> linearRangeMapping(SrcValueType src_min, SrcValueType src_max, DestValueType dest_min, DestValueType dest_max ); } \endcode Usage: \#include "vigra/transformimage.hxx"
Namespace: vigra \code vigra::IImage src(width, height); vigra::BImage dest(width, height); ... vigra::FindMinMax minmax; // functor to find range vigra::inspectImage(srcImageRange(src), minmax); // find original range // transform to range 0...255 vigra::transformImage(srcImageRange(src), destImage(dest), linearRangeTransform( minmax.min, minmax.max, // src range (unsigned char)0, (unsigned char)255) // dest range ); \endcode Required Interface: The source and destination value types must be models of \ref LinearSpace in both cases. */ template LinearIntensityTransform::RealPromote> linearRangeMapping(SrcValueType src_min, SrcValueType src_max, DestValueType dest_min, DestValueType dest_max ) { return linearRangeMapping(src_min, src_max, dest_min, dest_max, typename NumericTraits::isScalar()); } template LinearIntensityTransform::RealPromote> linearRangeMapping( SrcValueType src_min, SrcValueType src_max, DestValueType dest_min, DestValueType dest_max, VigraTrueType /* isScalar */ ) { typedef typename NumericTraits::RealPromote Multiplier; Multiplier diff = src_max - src_min; Multiplier scale = diff == NumericTraits::zero() ? NumericTraits::one() : (dest_max - dest_min) / diff; return LinearIntensityTransform( scale, dest_min / scale - src_min ); } template LinearIntensityTransform::RealPromote> linearRangeMapping( SrcValueType src_min, SrcValueType src_max, DestValueType dest_min, DestValueType dest_max, VigraFalseType /* isScalar */ ) { typedef typename NumericTraits::RealPromote Multiplier; typedef typename Multiplier::value_type MComponent; Multiplier scale(dest_max), offset(dest_max); for(unsigned int i=0; i::zero() ? NumericTraits::one() : (dest_max[i] - dest_min[i]) / diff; offset[i] = dest_min[i] / scale[i] - src_min[i]; } return LinearIntensityTransform(scale, offset); } /********************************************************/ /* */ /* Threshold */ /* */ /********************************************************/ /** \brief Threshold an image. If a source pixel is above or equal the lower and below or equal the higher threshold (i.e. within the closed interval [lower, heigher]) the destination pixel is set to 'yesresult', otherwise to 'noresult'. Traits defined: FunctorTraits::isUnaryFunctor is true (VigraTrueType) Usage: \#include "vigra/transformimage.hxx"
Namespace: vigra \code vigra::BImage src(width, height), dest(width, height); ... vigra::transformImage(src.upperLeft(), src.lowerRight(), src.accessor(), dest.upperLeft(), dest.accessor(), vigra::Threshold< vigra::BImage::PixelType, vigra::BImage::PixelType>(10, 100, 0, 255)); \endcode Required Interface: \code SrcValueType src; DestValueType dest, yesresult, noresult; dest = ((src < lower) || (higher < src)) ? noresult : yesresult; \endcode */ template class Threshold { public: /** the functor's argument type */ typedef SrcValueType argument_type; /** the functor's result type */ typedef DestValueType result_type; /** init thresholds and return values */ Threshold(argument_type lower, argument_type higher, result_type noresult, result_type yesresult) : lower_(lower), higher_(higher), yesresult_(yesresult), noresult_(noresult) {} /** calculate transform */ result_type operator()(argument_type s) const { return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_; } private: argument_type lower_, higher_; result_type yesresult_, noresult_; }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isUnaryFunctor; }; /********************************************************/ /* */ /* BrightnessContrastFunctor */ /* */ /********************************************************/ /** \brief Adjust brightness and contrast of an image. This functor applies a gamma correction to each pixel in order to modify the brightness of the image. To the result of the gamma correction, another transform is applied that modifies the contrast. The brightness and contrast parameters must be positive. Values greater than 1 will increase image brightness and contrast, values smaller than 1 decrease them. A value = 1 will have no effect. For \ref RGBValue "RGBValue's", the transforms are applied component-wise. The pixel values are assumed to lie between the given minimum and maximum values. In case of RGB, this is again understood component-wise. In case of unsigned char, min and max default to 0 and 255 respectively. Precisely, the following transform is applied to each PixelValue: \f[ \begin{array}{rcl} V_1 & = & \frac{PixelValue - min}{max - min} \\ V_2 & = & V_1^\frac{1}{brightness} \\ V_3 & = & 2 V_2 - 1 \\ V_4 & = & \left\lbrace \begin{array}{l} V_3^\frac{1}{contrast} \mbox{\rm \quad if } V_3 \ge 0 \\ - (-V_3)^\frac{1}{contrast} \mbox{\rm \quad otherwise} \end{array} \right. \\ Result & = & \frac{V_4 + 1}{2} (max - min) + min \end{array} \f] If the PixelType is unsigned char, a look-up-table is used for faster computation. Traits defined: FunctorTraits::isUnaryFunctor is true (VigraTrueType) Usage: \#include "vigra/transformimage.hxx"
Namespace: vigra \code vigra::BImage bimage(width, height); double brightness, contrast; ... vigra::transformImage(srcImageRange(bimage), destImage(bimage), vigra::BrightnessContrastFunctor(brightness, contrast)); vigra::FImage fimage(width, height); ... vigra::FindMinmax minmax; vigra::inspectImage(srcImageRange(fimage), minmax); vigra::transformImage(srcImageRange(fimage), destImage(fimage), vigra::BrightnessContrastFunctor(brightness, contrast, minmax.min, minmax.max)); \endcode Required Interface: Scalar types: must be a linear algebra (+, - *, NumericTraits), strict weakly ordered (<), and pow() must be defined. RGB values: the component type must meet the above requirements. */ template class BrightnessContrastFunctor { typedef typename NumericTraits::RealPromote promote_type; public: /** the functor's argument type */ typedef PixelType argument_type; /** the functor's result type */ typedef PixelType result_type; /** \deprecated use argument_type and result_type */ typedef PixelType value_type; /** Init functor for argument range [min, max]. brightness and contrast values > 1 will increase brightness and contrast, < 1 will decrease them, and == 1 means no change. */ BrightnessContrastFunctor(promote_type brightness, promote_type contrast, argument_type const & min, argument_type const & max) : b_(1.0/brightness), c_(1.0/contrast), min_(min), diff_(max - min), zero_(NumericTraits::zero()), one_(NumericTraits::one()) {} /** Calculate modified gray or color value */ result_type operator()(argument_type const & v) const { promote_type v1 = (v - min_) / diff_; promote_type brighter = VIGRA_CSTD::pow(v1, b_); promote_type v2 = 2.0 * brighter - one_; promote_type contrasted = (v2 < zero_) ? -VIGRA_CSTD::pow(-v2, c_) : VIGRA_CSTD::pow(v2, c_); return result_type(0.5 * diff_ * (contrasted + one_) + min_); } private: promote_type b_, c_; argument_type min_; promote_type diff_, zero_, one_; }; template <> class BrightnessContrastFunctor { typedef NumericTraits::RealPromote promote_type; unsigned char lut[256]; public: typedef unsigned char value_type; BrightnessContrastFunctor(promote_type brightness, promote_type contrast, value_type const & min = 0, value_type const & max = 255) { BrightnessContrastFunctor f(brightness, contrast, min, max); for(int i = min; i <= max; ++i) { lut[i] = static_cast(f(i)+0.5); } } value_type operator()(value_type const & v) const { return lut[v]; } }; #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION template class BrightnessContrastFunctor > { typedef typename NumericTraits::RealPromote promote_type; BrightnessContrastFunctor red, green, blue; public: typedef RGBValue value_type; BrightnessContrastFunctor(promote_type brightness, promote_type contrast, value_type const & min, value_type const & max) : red(brightness, contrast, min.red(), max.red()), green(brightness, contrast, min.green(), max.green()), blue(brightness, contrast, min.blue(), max.blue()) {} value_type operator()(value_type const & v) const { return value_type(red(v.red()), green(v.green()), blue(v.blue())); } }; #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION template <> class BrightnessContrastFunctor > { typedef NumericTraits::RealPromote promote_type; BrightnessContrastFunctor red, green, blue; public: typedef RGBValue value_type; BrightnessContrastFunctor(promote_type brightness, promote_type contrast, value_type const & min, value_type const & max) : red(brightness, contrast, min.red(), max.red()), green(brightness, contrast, min.green(), max.green()), blue(brightness, contrast, min.blue(), max.blue()) {} value_type operator()(value_type const & v) const { return value_type(red(v.red()), green(v.green()), blue(v.blue())); } }; template <> class BrightnessContrastFunctor > { typedef NumericTraits::RealPromote promote_type; BrightnessContrastFunctor red, green, blue; public: typedef RGBValue value_type; BrightnessContrastFunctor(promote_type brightness, promote_type contrast, value_type const & min, value_type const & max) : red(brightness, contrast, min.red(), max.red()), green(brightness, contrast, min.green(), max.green()), blue(brightness, contrast, min.blue(), max.blue()) {} value_type operator()(value_type const & v) const { return value_type(red(v.red()), green(v.green()), blue(v.blue())); } }; template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isUnaryFunctor; }; #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION template <> class BrightnessContrastFunctor > { typedef NumericTraits::RealPromote promote_type; BrightnessContrastFunctor red, green, blue; public: typedef RGBValue value_type; BrightnessContrastFunctor(promote_type brightness, promote_type contrast, value_type const & min = value_type(0,0,0), value_type const & max = value_type(255, 255, 255)) : red(brightness, contrast, min.red(), max.red()), green(brightness, contrast, min.green(), max.green()), blue(brightness, contrast, min.blue(), max.blue()) {} value_type operator()(value_type const & v) const { return value_type(red(v.red()), green(v.green()), blue(v.blue())); } }; /********************************************************/ /* */ /* VectorNormFunctor */ /* */ /********************************************************/ /** \brief A functor for computing the vector norm Calculate the magnitude or norm from a given vector-valued entity. The vector type will typically be some sort of ref vigra::TinyVector. If the vector is represented by a pair of scalar-valued images, use \ref vigra::MagnitudeFunctor instead. At least, the vector type is required to have a function 'result = dot(v,v)'. Traits defined: FunctorTraits::isUnaryFunctor is true (VigraTrueType) Usage: \#include "vigra/transformimage.hxx"
Namespace: vigra \code typedef vigra::TinyVector Vector; vigra::BasicImage grad(width, height); vigra::FImage magn(width,height); ... vigra::transformImage(srcImageRange(grad), destImage(magn), VectorNormFunctor() ); \endcode \see vigra::TinyVector, dot(), vigra::MagnitudeFunctor */ template class VectorNormFunctor { public: /** the functor's argument type */ typedef ValueType argument_type; /** the functor's result type */ typedef typename NumericTraits::RealPromote result_type; /** calculate transform 'sqrt(v1*v1 + v2*v2 + ...)'. */ result_type operator()( const argument_type &a ) const { return VIGRA_CSTD::sqrt( dot(a,a) ); } }; //-- class VectorNormFunctor template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isUnaryFunctor; }; /** \brief A functor for computing the squared vector norm Calculate the squared magnitude or norm from a given vector-valued entity. The vector type will typically be some sort of TinyVector. At least, the vector type is required to have a function 'result = dot(v,v)'. For an example of its usage see VectorNormFunctor Traits defined: FunctorTraits::isUnaryFunctor is true (VigraTrueType) \see TinyVector, dot() */ template class VectorNormSqFunctor { public: /** the functor's argument type */ typedef ValueType argument_type; /** the functor's result type */ typedef typename NumericTraits::RealPromote result_type; /** calculate transform 'v1*v1 + v2*v2 + ...'. */ result_type operator()( const argument_type &a ) const { return dot(a,a); } }; //-- class VectorNormSqFunctor template class FunctorTraits > : public FunctorTraitsBase > { public: typedef VigraTrueType isUnaryFunctor; }; //@} } // namespace vigra #endif // VIGRA_TRANSFORMIMAGE_HXX