VIGRA - vigra/transformimage.hxx Source File

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

| vigra/transformimage.hxx |
--- | --- | ---

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
    00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    ( Version 1.5.0, Dec 07 2006 )                                    */
    00008 /*    The VIGRA Website is                                              */
    00009 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
    00010 /*    Please direct questions, bug reports, and contributions to        */
    00011 /*        koethe@informatik.uni-hamburg.de          or                  */
    00012 /*        vigra@kogs1.informatik.uni-hamburg.de                         */
    00013 /*                                                                      */
    00014 /*    Permission is hereby granted, free of charge, to any person       */
    00015 /*    obtaining a copy of this software and associated documentation    */
    00016 /*    files (the "Software"), to deal in the Software without           */
    00017 /*    restriction, including without limitation the rights to use,      */
    00018 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00019 /*    sell copies of the Software, and to permit persons to whom the    */
    00020 /*    Software is furnished to do so, subject to the following          */
    00021 /*    conditions:                                                       */
    00022 /*                                                                      */
    00023 /*    The above copyright notice and this permission notice shall be    */
    00024 /*    included in all copies or substantial portions of the             */
    00025 /*    Software.                                                         */
    00026 /*                                                                      */
    00027 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00028 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00029 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00030 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00031 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00032 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00033 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00034 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00035 /*                                                                      */
    00036 /************************************************************************/
    00037
    00038
    00039 #ifndef VIGRA_TRANSFORMIMAGE_HXX
    00040 #define VIGRA_TRANSFORMIMAGE_HXX
    00041
    00042 #include "utilities.hxx"
    00043 #include "numerictraits.hxx"
    00044 #include "iteratortraits.hxx"
    00045 #include "rgbvalue.hxx"
    00046 #include "functortraits.hxx"
    00047
    00048 namespace vigra {
    00049
    00050 /** \addtogroup TransformAlgo Algorithms to Transform Images
    00051     Apply functor to calculate a pixelwise transformation of one image
    00052
    00053     @{
    00054 */
    00055
    00056 /********************************************************/
    00057 /*                                                      */
    00058 /*                      transformLine                   */
    00059 /*                                                      */
    00060 /********************************************************/
    00061
    00062 template <class SrcIterator, class SrcAccessor,
    00063           class DestIterator, class DestAccessor, class Functor>
    00064 void
    00065 transformLine(SrcIterator s,
    00066               SrcIterator send, SrcAccessor src,
    00067               DestIterator d, DestAccessor dest,
    00068               Functor const & f)
    00069 {
    00070     for(; s != send; ++s, ++d)
    00071         dest.set(f(src(s)), d);
    00072 }
    00073
    00074 template <class SrcIterator, class SrcAccessor,
    00075           class MaskIterator, class MaskAccessor,
    00076           class DestIterator, class DestAccessor,
    00077           class Functor>
    00078 void
    00079 transformLineIf(SrcIterator s,
    00080                 SrcIterator send, SrcAccessor src,
    00081                 MaskIterator m, MaskAccessor mask,
    00082                 DestIterator d, DestAccessor dest,
    00083                 Functor const & f)
    00084 {
    00085     for(; s != send; ++s, ++d, ++m)
    00086         if(mask(m))
    00087             dest.set(f(src(s)), d);
    00088 }
    00089
    00090 /********************************************************/
    00091 /*                                                      */
    00092 /*                      transformImage                  */
    00093 /*                                                      */
    00094 /********************************************************/
    00095
    00096 /** \brief Apply unary point transformation to each pixel.
    00097
    00098     The transformation given by the functor is applied to every source
    00099     pixel and the result written into the corresponding destination pixel.
    00100     The function uses accessors to access the pixel data.
    00101     Note that the unary functors of the STL can be used in addition to
    00102     the functors specifically defined in \ref TransformFunctor.
    00103     Creation of new functors is easiest by using \ref FunctorExpressions.
    00104
    00105     <b> Declarations:</b>
    00106
    00107     pass arguments explicitly:
    00108     \code
    00109     namespace vigra {
    00110         template <class SrcImageIterator, class SrcAccessor,
    00111               class DestImageIterator, class DestAccessor, class Functor>
    00112         void
    00113         transformImage(SrcImageIterator src_upperleft,
    00114                SrcImageIterator src_lowerright, SrcAccessor sa,
    00115                DestImageIterator dest_upperleft, DestAccessor da,
    00116                Functor const & f)
    00117     }
    00118     \endcode
    00119
    00120
    00121     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00122     \code
    00123     namespace vigra {
    00124         template <class SrcImageIterator, class SrcAccessor,
    00125               class DestImageIterator, class DestAccessor, class Functor>
    00126         void
    00127         transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00128                pair<DestImageIterator, DestAccessor> dest,
    00129                Functor const & f)
    00130     }
    00131     \endcode
    00132
    00133     <b> Usage:</b>
    00134
    00135     <b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>"<br>
    00136     Namespace: vigra
    00137
    00138     \code
    00139
    00140     #include <cmath>         // for sqrt()
    00141
    00142     vigra::transformImage(srcImageRange(src),
    00143                           destImage(dest),
    00144                           (double(*)(double))&std::sqrt );
    00145
    00146     \endcode
    00147
    00148     <b> Required Interface:</b>
    00149
    00150     \code
    00151     SrcImageIterator src_upperleft, src_lowerright;
    00152     DestImageIterator      dest_upperleft;
    00153     SrcImageIterator::row_iterator sx = src_upperleft.rowIterator();
    00154     DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
    00155
    00156     SrcAccessor src_accessor;
    00157     DestAccessor dest_accessor;
    00158
    00159     Functor functor;
    00160
    00161     dest_accessor.set(functor(src_accessor(sx)), dx);
    00162
    00163     \endcode
    00164
    00165 */
    00166 template <class SrcImageIterator, class SrcAccessor,
    00167           class DestImageIterator, class DestAccessor, class Functor>
    00168 void
    00169 transformImage(SrcImageIterator src_upperleft,
    00170                SrcImageIterator src_lowerright, SrcAccessor sa,
    00171                DestImageIterator dest_upperleft, DestAccessor da,
    00172                Functor const & f)
    00173 {
    00174     int w = src_lowerright.x - src_upperleft.x;
    00175
    00176     for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y)
    00177     {
    00178         transformLine(src_upperleft.rowIterator(),
    00179                       src_upperleft.rowIterator() + w, sa,
    00180                       dest_upperleft.rowIterator(), da, f);
    00181     }
    00182 }
    00183
    00184 template <class SrcImageIterator, class SrcAccessor,
    00185       class DestImageIterator, class DestAccessor, class Functor>
    00186 inline
    00187 void
    00188 transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00189                pair<DestImageIterator, DestAccessor> dest,
    00190                Functor const & f)
    00191 {
    00192     transformImage(src.first, src.second, src.third,
    00193                    dest.first, dest.second, f);
    00194 }
    00195
    00196 /********************************************************/
    00197 /*                                                      */
    00198 /*                   transformImageIf                   */
    00199 /*                                                      */
    00200 /********************************************************/
    00201
    00202 /** \brief Apply unary point transformation to each pixel within the ROI
    00203     (i.e., where the mask is non-zero).
    00204
    00205     The transformation given by the functor is applied to every source
    00206     pixel in the ROI (i.e. when the return vlaue of the mask's accessor
    00207     is not zero)
    00208     and the result is written into the corresponding destination pixel.
    00209     The function uses accessors to access the pixel data.
    00210     Note that the unary functors of the STL can be used in addition to
    00211     the functors specifically defined in \ref TransformFunctor.
    00212     Creation of new functors is easiest by using \ref FunctorExpressions.
    00213
    00214     <b> Declarations:</b>
    00215
    00216     pass arguments explicitly:
    00217     \code
    00218     namespace vigra {
    00219         template <class SrcImageIterator, class SrcAccessor,
    00220               class MaskImageIterator, class MaskAccessor,
    00221               class DestImageIterator, clas DestAccessor,
    00222               class Functor>
    00223         void
    00224         transformImageIf(SrcImageIterator src_upperleft,
    00225             SrcImageIterator src_lowerright, SrcAccessor sa,
    00226             MaskImageIterator mask_upperleft, MaskAccessor ma,
    00227             DestImageIterator dest_upperleft, DestAccessor da,
    00228             Functor const & f)
    00229     }
    00230     \endcode
    00231
    00232
    00233     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00234     \code
    00235     namespace vigra {
    00236         template <class SrcImageIterator, class SrcAccessor,
    00237               class MaskImageIterator, class MaskAccessor,
    00238               class DestImageIterator, clas DestAccessor,
    00239               class Functor>
    00240         void
    00241         transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00242                  pair<MaskImageIterator, MaskAccessor> mask,
    00243                  pair<DestImageIterator, DestAccessor> dest,
    00244                  Functor const & f)
    00245     }
    00246     \endcode
    00247
    00248     <b> Usage:</b>
    00249
    00250         <b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>"<br>
    00251         Namespace: vigra
    00252
    00253     \code
    00254     #include <cmath>         // for sqrt()
    00255
    00256     vigra::transformImageIf(srcImageRange(src),
    00257                             maskImage(mask),
    00258                             destImage(dest),
    00259                             (double(*)(double))&std::sqrt );
    00260
    00261     \endcode
    00262
    00263     <b> Required Interface:</b>
    00264
    00265     \code
    00266     SrcImageIterator src_upperleft, src_lowerright;
    00267     DestImageIterator  dest_upperleft;
    00268     MaskImageIterator mask_upperleft;
    00269     SrcImageIterator::row_iterator sx = src_upperleft.rowIterator();
    00270     MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
    00271     DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
    00272
    00273     SrcAccessor src_accessor;
    00274     DestAccessor dest_accessor;
    00275     MaskAccessor mask_accessor;
    00276     Functor functor;
    00277
    00278     if(mask_accessor(mx))
    00279        dest_accessor.set(functor(src_accessor(sx)), dx);
    00280
    00281     \endcode
    00282
    00283 */
    00284 template <class SrcImageIterator, class SrcAccessor,
    00285           class MaskImageIterator, class MaskAccessor,
    00286           class DestImageIterator, class DestAccessor,
    00287           class Functor>
    00288 void
    00289 transformImageIf(SrcImageIterator src_upperleft,
    00290                  SrcImageIterator src_lowerright, SrcAccessor sa,
    00291                  MaskImageIterator mask_upperleft, MaskAccessor ma,
    00292                  DestImageIterator dest_upperleft, DestAccessor da,
    00293                  Functor const & f)
    00294 {
    00295     int w = src_lowerright.x - src_upperleft.x;
    00296
    00297     for(; src_upperleft.y < src_lowerright.y;
    00298              ++src_upperleft.y, ++mask_upperleft.y, ++dest_upperleft.y)
    00299     {
    00300         transformLineIf(src_upperleft.rowIterator(),
    00301                         src_upperleft.rowIterator() + w, sa,
    00302                         mask_upperleft.rowIterator(), ma,
    00303                         dest_upperleft.rowIterator(), da, f);
    00304     }
    00305 }
    00306
    00307 template <class SrcImageIterator, class SrcAccessor,
    00308           class MaskImageIterator, class MaskAccessor,
    00309           class DestImageIterator, class DestAccessor,
    00310           class Functor>
    00311 inline
    00312 void
    00313 transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00314                  pair<MaskImageIterator, MaskAccessor> mask,
    00315                  pair<DestImageIterator, DestAccessor> dest,
    00316                  Functor const & f)
    00317 {
    00318     transformImageIf(src.first, src.second, src.third,
    00319                      mask.first, mask.second,
    00320                      dest.first, dest.second, f);
    00321 }
    00322
    00323 /********************************************************/
    00324 /*                                                      */
    00325 /*               gradientBasedTransform                 */
    00326 /*                                                      */
    00327 /********************************************************/
    00328
    00329 /** \brief Calculate a function of the image gradient.
    00330
    00331     The gradient and the function represented by <TT>Functor f</TT>
    00332     are calculated in one go: for each location, the symmetric
    00333     difference in x- and y-directions (asymmetric difference at the
    00334     image borders) are passed to the given functor, and the result is
    00335     written the destination image. Functors to be used with this
    00336     function include \ref MagnitudeFunctor and \ref
    00337     RGBGradientMagnitudeFunctor.
    00338
    00339     <b> Declarations:</b>
    00340
    00341     pass arguments explicitly:
    00342     \code
    00343     namespace vigra {
    00344         template <class SrcImageIterator, class SrcAccessor,
    00345                   class DestImageIterator, class DestAccessor, class Functor>
    00346         void
    00347         gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa,
    00348                       DestImageIterator destul, DestAccessor da, Functor const & f)
    00349     }
    00350     \endcode
    00351
    00352
    00353     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00354     \code
    00355     namespace vigra {
    00356         template <class SrcImageIterator, class SrcAccessor,
    00357                   class DestImageIterator, class DestAccessor, class Functor>
    00358         void
    00359         gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00360                        pair<DestImageIterator, DestAccessor> dest, Functor const & const & f)
    00361     }
    00362     \endcode
    00363
    00364     <b> Usage:</b>
    00365
    00366     <b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>"
    00367
    00368
    00369     \code
    00370     vigra::FImage src(w,h), magnitude(w,h);
    00371     ...
    00372
    00373     gradientBasedTransform(srcImageRange(src), destImage(magnitude),
    00374                                 vigra::MagnitudeFunctor<float>());
    00375     \endcode
    00376
    00377     <b> Required Interface:</b>
    00378
    00379     \code
    00380     SrcImageIterator is, isend;
    00381     DestImageIterator id;
    00382
    00383     SrcAccessor src_accessor;
    00384     DestAccessor dest_accessor;
    00385
    00386     typename NumericTraits<typename SrcAccessor::value_type>::RealPromote
    00387         diffx, diffy;
    00388
    00389     diffx = src_accessor(is, Diff2D(-1,0)) - src_accessor(is, Diff2D(1,0));
    00390     diffy = src_accessor(is, Diff2D(0,-1)) - src_accessor(is, Diff2D(0,1));
    00391
    00392     Functor f;
    00393
    00394     dest_accessor.set(f(diffx, diffy), id);
    00395
    00396     \endcode
    00397
    00398 */
    00399
    00400 template <class SrcImageIterator, class SrcAccessor,
    00401           class DestImageIterator, class DestAccessor, class Functor>
    00402 void
    00403 gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa,
    00404                        DestImageIterator destul, DestAccessor da, Functor const & grad)
    00405 {
    00406     int w = srclr.x - srcul.x;
    00407     int h = srclr.y - srcul.y;
    00408     int x,y;
    00409
    00410     SrcImageIterator sy = srcul;
    00411     DestImageIterator dy = destul;
    00412
    00413     static const Diff2D left(-1,0);
    00414     static const Diff2D right(1,0);
    00415     static const Diff2D top(0,-1);
    00416     static const Diff2D bottom(0,1);
    00417
    00418     typename NumericTraits<typename SrcAccessor::value_type>::RealPromote
    00419              diffx, diffy;
    00420
    00421     SrcImageIterator sx = sy;
    00422     DestImageIterator dx = dy;
    00423
    00424     diffx = sa(sx) - sa(sx, right);
    00425     diffy = sa(sx) - sa(sx, bottom);
    00426     da.set(grad(diffx, diffy), dx);
    00427
    00428     for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
    00429     {
    00430         diffx = (sa(sx, left) - sa(sx, right)) / 2.0;
    00431         diffy = sa(sx) - sa(sx, bottom);
    00432         da.set(grad(diffx, diffy), dx);
    00433     }
    00434
    00435     diffx = sa(sx, left) - sa(sx);
    00436     diffy = sa(sx) - sa(sx, bottom);
    00437     da.set(grad(diffx, diffy), dx);
    00438
    00439     ++sy.y;
    00440     ++dy.y;
    00441
    00442     for(y=2; y<h; ++y, ++sy.y, ++dy.y)
    00443     {
    00444         sx = sy;
    00445         dx = dy;
    00446
    00447         diffx = sa(sx) - sa(sx, right);
    00448         diffy = (sa(sx, top) - sa(sx, bottom)) / 2.0;
    00449         da.set(grad(diffx, diffy), dx);
    00450
    00451         for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
    00452         {
    00453             diffx = (sa(sx, left) - sa(sx, right)) / 2.0;
    00454             diffy = (sa(sx, top) - sa(sx, bottom)) / 2.0;
    00455             da.set(grad(diffx, diffy), dx);
    00456         }
    00457
    00458         diffx = sa(sx, left) - sa(sx);
    00459         diffy = (sa(sx, top) - sa(sx, bottom)) / 2.0;
    00460         da.set(grad(diffx, diffy), dx);
    00461     }
    00462
    00463     sx = sy;
    00464     dx = dy;
    00465
    00466     diffx = sa(sx) - sa(sx, right);
    00467     diffy = sa(sx, top) - sa(sx);
    00468     da.set(grad(diffx, diffy), dx);
    00469
    00470     for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
    00471     {
    00472         diffx = (sa(sx, left) - sa(sx, right)) / 2.0;
    00473         diffy = sa(sx, top) - sa(sx);
    00474         da.set(grad(diffx, diffy), dx);
    00475     }
    00476
    00477     diffx = sa(sx, left) - sa(sx);
    00478     diffy = sa(sx, top) - sa(sx);
    00479     da.set(grad(diffx, diffy), dx);
    00480 }
    00481
    00482 template <class SrcImageIterator, class SrcAccessor,
    00483           class DestImageIterator, class DestAccessor, class Functor>
    00484 inline
    00485 void
    00486 gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00487                        pair<DestImageIterator, DestAccessor> dest, Functor const & grad)
    00488 {
    00489     gradientBasedTransform(src.first, src.second, src.third,
    00490                            dest.first, dest.second, grad);
    00491 }
    00492
    00493 /** @} */
    00494 /** \addtogroup TransformFunctor Functors to Transform Images
    00495
    00496     Note that the unary functors of the STL can also be used in
    00497     connection with \ref transformImage().
    00498 */
    00499 //@{
    00500
    00501 template <class DestValueType, class Multiplier = double>
    00502 class LinearIntensityTransform
    00503 {
    00504   public:
    00505         /* the functors argument type (actually, since
    00506            <tt>operator()</tt> is a template, much more types are possible)
    00507         */
    00508     typedef DestValueType argument_type;
    00509
    00510         /* the functors result type
    00511         */
    00512     typedef DestValueType result_type;
    00513
    00514         /* \deprecated use argument_type and result_type
    00515         */
    00516     typedef DestValueType value_type;
    00517
    00518         /* type of the offset (used in internal calculations to prevent
    00519             overflows and minimize round-off errors).
    00520         */
    00521     typedef typename
    00522             NumericTraits<DestValueType>::RealPromote argument_promote;
    00523
    00524         /* type of the scale factor
    00525         */
    00526     typedef Multiplier scalar_multiplier_type;
    00527
    00528         /* init scale and offset
    00529         */
    00530     LinearIntensityTransform(scalar_multiplier_type scale, argument_promote offset)
    00531     : scale_(scale), offset_(offset)
    00532     {}
    00533
    00534         /* calculate transform
    00535         */
    00536     template <class SrcValueType>
    00537     result_type operator()(SrcValueType const & s) const
    00538     {
    00539         return NumericTraits<result_type>::fromRealPromote(scale_ * (s + offset_));
    00540     }
    00541
    00542   private:
    00543
    00544     scalar_multiplier_type scale_;
    00545     argument_promote offset_;
    00546 };
    00547
    00548 template <class DestValueType, class Multiplier>
    00549 class FunctorTraits<LinearIntensityTransform<DestValueType, Multiplier> >
    00550 : public FunctorTraitsBase<LinearIntensityTransform<DestValueType, Multiplier> >
    00551 {
    00552   public:
    00553     typedef VigraTrueType isUnaryFunctor;
    00554 };
    00555
    00556 template <class DestValueType, class Multiplier = double>
    00557 class ScalarIntensityTransform
    00558 {
    00559   public:
    00560         /* the functors argument type (actually, since
    00561            <tt>operator()</tt> is a template, much more types are possible)
    00562         */
    00563     typedef DestValueType argument_type;
    00564
    00565         /* the functors result type
    00566         */
    00567     typedef DestValueType result_type;
    00568
    00569         /* \deprecated use argument_type and result_type
    00570         */
    00571     typedef DestValueType value_type;
    00572
    00573         /* type of the scale factor
    00574         */
    00575     typedef Multiplier scalar_multiplier_type;
    00576
    00577         /* init scale
    00578         */
    00579     ScalarIntensityTransform(scalar_multiplier_type scale)
    00580     : scale_(scale)
    00581     {}
    00582
    00583         /* calculate transform
    00584         */
    00585     template <class SrcValueType>
    00586     result_type operator()(SrcValueType const & s) const
    00587     {
    00588         return NumericTraits<result_type>::fromRealPromote(scale_ * s);
    00589     }
    00590
    00591   private:
    00592     scalar_multiplier_type scale_;
    00593 };
    00594
    00595 template <class DestValueType, class Multiplier>
    00596 class FunctorTraits<ScalarIntensityTransform<DestValueType, Multiplier> >
    00597 : public FunctorTraitsBase<ScalarIntensityTransform<DestValueType, Multiplier> >
    00598 {
    00599   public:
    00600     typedef VigraTrueType isUnaryFunctor;
    00601 };
    00602
    00603 /********************************************************/
    00604 /*                                                      */
    00605 /*              linearIntensityTransform                */
    00606 /*                                                      */
    00607 /********************************************************/
    00608
    00609 /** \brief Apply a linear transform to the source pixel values
    00610
    00611     Factory function for a functor that linearly transforms the
    00612     source pixel values. The functor applies the transform
    00613     '<TT>destvalue = scale * (srcvalue + offset)</TT>' to every pixel.
    00614     This can, for example, be used to transform images into the visible
    00615     range 0...255 or to invert an image.
    00616
    00617     If you leave out the second parameter / offset, you will get an
    00618     optimized version of the functor which only scales by the given
    00619     factor, however you have to make the template parameter (pixel
    00620     type) explicit then.
    00621
    00622     <b> Traits defined:</b>
    00623
    00624     <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>)
    00625
    00626     <b> Declaration:</b>
    00627
    00628     \code
    00629     namespace vigra {
    00630         template <class Multiplier, class DestValueType>
    00631         LinearIntensityTransform<DestValueType, Multiplier>
    00632         linearIntensityTransform(Multiplier scale, DestValueType offset);
    00633
    00634         template <class DestValueType, class Multiplier>
    00635         ScalarIntensityTransform<DestValueType, Multiplier>
    00636         linearIntensityTransform(Multiplier scale);
    00637     }
    00638     \endcode
    00639
    00640     <b> Usage:</b>
    00641
    00642         <b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>"<br>
    00643         Namespace: vigra
    00644
    00645     \code
    00646     vigra::IImage src(width, height);
    00647     vigra::BImage dest(width, height);
    00648     ...
    00649     vigra::FindMinMax<IImage::PixelType> minmax;   // functor to find range
    00650
    00651     vigra::inspectImage(srcImageRange(src), minmax); // find original range
    00652
    00653     // transform to range 0...255
    00654     vigra::transformImage(srcImageRange(src), destImage(dest),
    00655                           linearIntensityTransform(
    00656                             255.0 / (minmax.max - minmax.min), // scaling
    00657                           - minmax.min));                    // offset
    00658     \endcode
    00659
    00660     The one-parameter version can be used like this:
    00661
    00662     \code
    00663     // scale from 0..255 to 0..1.0
    00664     FImage dest(src.size());
    00665
    00666     vigra::transformImage(srcImageRange(src), destImage(dest),
    00667                           linearIntensityTransform<float>(1.0 / 255));
    00668     \endcode
    00669
    00670     <b> Required Interface:</b>
    00671
    00672     The source and destination value types must be models of \ref LinearSpace in both cases.
    00673
    00674 */
    00675 template <class Multiplier, class DestValueType>
    00676 LinearIntensityTransform<DestValueType, Multiplier>
    00677 linearIntensityTransform(Multiplier scale, DestValueType offset)
    00678 {
    00679     return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
    00680 }
    00681
    00682 template <class DestValueType, class Multiplier>
    00683 ScalarIntensityTransform<DestValueType, Multiplier>
    00684 linearIntensityTransform(Multiplier scale)
    00685 {
    00686     return ScalarIntensityTransform<DestValueType, Multiplier>(scale);
    00687 }
    00688
    00689 /********************************************************/
    00690 /*                                                      */
    00691 /*                   linearRangeMapping                 */
    00692 /*                                                      */
    00693 /********************************************************/
    00694
    00695 /** \brief Map a source intensity range linearly to a destination range.
    00696
    00697     Factory function for a functor that linearly transforms the
    00698     source pixel values. The functor applies the transform
    00699     '<TT>destvalue = scale * (srcvalue + offset)</TT>' to every pixel,
    00700     where <tt>scale = (dest_max - dest_min) / (src_max - src_min)</tt>
    00701     and <tt>offset = dest_min / scale - src_min</tt>. As a result,
    00702     the pixel values <tt>src_max</tt>, <tt>src_min</tt> in the source image
    00703     are mapped onto <tt>dest_max</tt>, <tt>dest_min</tt> respectively.
    00704     This works for scalar as well as vector pixel types.
    00705
    00706     <b> Declaration:</b>
    00707
    00708     \code
    00709     namespace vigra {
    00710         template <class SrcValueType, class DestValueType>
    00711         LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
    00712         linearRangeMapping(SrcValueType src_min, SrcValueType src_max,
    00713                            DestValueType dest_min, DestValueType dest_max );
    00714     }
    00715     \endcode
    00716
    00717     <b> Usage:</b>
    00718
    00719         <b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>"<br>
    00720         Namespace: vigra
    00721
    00722     \code
    00723     vigra::IImage src(width, height);
    00724     vigra::BImage dest(width, height);
    00725     ...
    00726     vigra::FindMinMax<IImage::PixelType> minmax;   // functor to find range
    00727
    00728     vigra::inspectImage(srcImageRange(src), minmax); // find original range
    00729
    00730     // transform to range 0...255
    00731     vigra::transformImage(srcImageRange(src), destImage(dest),
    00732                           linearRangeTransform(
    00733                             minmax.min, minmax.max,               // src range
    00734                             (unsigned char)0, (unsigned char)255) // dest range
    00735                           );
    00736     \endcode
    00737
    00738     <b> Required Interface:</b>
    00739
    00740     The source and destination value types must be models of \ref LinearSpace in both cases.
    00741
    00742 */
    00743 template <class SrcValueType, class DestValueType>
    00744 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
    00745 linearRangeMapping(SrcValueType src_min, SrcValueType src_max,
    00746                    DestValueType dest_min, DestValueType dest_max )
    00747 {
    00748     return linearRangeMapping(src_min, src_max, dest_min, dest_max,
    00749             typename NumericTraits<DestValueType>::isScalar());
    00750 }
    00751
    00752 template <class SrcValueType, class DestValueType>
    00753 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
    00754 linearRangeMapping(
    00755     SrcValueType src_min, SrcValueType src_max,
    00756     DestValueType dest_min, DestValueType dest_max,
    00757     VigraTrueType /* isScalar */ )
    00758 {
    00759     typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
    00760     Multiplier diff = src_max - src_min;
    00761     Multiplier scale = diff == NumericTraits<Multiplier>::zero()
    00762                      ? NumericTraits<Multiplier>::one()
    00763                      : (dest_max - dest_min) / diff;
    00764     return LinearIntensityTransform<DestValueType, Multiplier>(
    00765                                    scale, dest_min / scale - src_min );
    00766 }
    00767
    00768 template <class SrcValueType, class DestValueType>
    00769 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
    00770 linearRangeMapping(
    00771     SrcValueType src_min, SrcValueType src_max,
    00772     DestValueType dest_min, DestValueType dest_max,
    00773     VigraFalseType /* isScalar */ )
    00774 {
    00775     typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
    00776     typedef typename Multiplier::value_type MComponent;
    00777     Multiplier scale(dest_max), offset(dest_max);
    00778     for(unsigned int i=0; i<src_min.size(); ++i)
    00779     {
    00780         MComponent diff = src_max[i] - src_min[i];
    00781         scale[i] = diff == NumericTraits<MComponent>::zero()
    00782                      ? NumericTraits<MComponent>::one()
    00783                      : (dest_max[i] - dest_min[i]) / diff;
    00784         offset[i] = dest_min[i] / scale[i] - src_min[i];
    00785     }
    00786     return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
    00787 }
    00788
    00789 /********************************************************/
    00790 /*                                                      */
    00791 /*                      Threshold                       */
    00792 /*                                                      */
    00793 /********************************************************/
    00794
    00795 /** \brief Threshold an image.
    00796
    00797     If a source pixel is above or equal the lower and below
    00798     or equal the higher threshold (i.e. within the closed interval
    00799     [lower, heigher]) the destination pixel is set to 'yesresult',
    00800     otherwise to 'noresult'.
    00801
    00802     <b> Traits defined:</b>
    00803
    00804     <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>)
    00805
    00806     <b> Usage:</b>
    00807
    00808         <b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>"<br>
    00809         Namespace: vigra
    00810
    00811     \code
    00812     vigra::BImage src(width, height), dest(width, height);
    00813     ...
    00814     vigra::transformImage(src.upperLeft(), src.lowerRight(), src.accessor(),
    00815        dest.upperLeft(), dest.accessor(),
    00816        vigra::Threshold<
    00817           vigra::BImage::PixelType, vigra::BImage::PixelType>(10, 100, 0, 255));
    00818
    00819     \endcode
    00820
    00821     <b> Required Interface:</b>
    00822
    00823     \code
    00824
    00825     SrcValueType   src;
    00826     DestValueType  dest, yesresult, noresult;
    00827
    00828     dest = ((src < lower) || (higher < src)) ? noresult : yesresult;
    00829
    00830     \endcode
    00831
    00832 */
    00833 template <class SrcValueType, class DestValueType>
    00834 class Threshold
    00835 {
    00836    public:
    00837
    00838         /** the functor's argument type
    00839         */
    00840     typedef SrcValueType argument_type;
    00841
    00842         /** the functor's result type
    00843         */
    00844     typedef DestValueType result_type;
    00845
    00846         /** init thresholds and return values
    00847         */
    00848     Threshold(argument_type lower, argument_type higher,
    00849               result_type noresult, result_type yesresult)
    00850     : lower_(lower), higher_(higher),
    00851       yesresult_(yesresult), noresult_(noresult)
    00852     {}
    00853
    00854         /** calculate transform
    00855         */
    00856     result_type operator()(argument_type s) const
    00857     {
    00858         return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_;
    00859     }
    00860
    00861   private:
    00862
    00863     argument_type lower_, higher_;
    00864     result_type yesresult_, noresult_;
    00865 };
    00866
    00867 template <class SrcValueType, class DestValueType>
    00868 class FunctorTraits<Threshold<SrcValueType, DestValueType> >
    00869 : public FunctorTraitsBase<Threshold<SrcValueType, DestValueType> >
    00870 {
    00871   public:
    00872     typedef VigraTrueType isUnaryFunctor;
    00873 };
    00874
    00875 /********************************************************/
    00876 /*                                                      */
    00877 /*                BrightnessContrastFunctor             */
    00878 /*                                                      */
    00879 /********************************************************/
    00880
    00881 /** \brief Adjust brightness and contrast of an image.
    00882
    00883     This functor applies a gamma correction to each pixel in order to
    00884     modify the brightness of the image. To the result of the gamma correction,
    00885     another transform is applied that modifies the contrast. The brightness and
    00886     contrast parameters must be positive. Values greater than 1 will increase image
    00887     brightness and contrast, values smaller than 1 decrease them. A value = 1 will
    00888     have no effect.
    00889     For \ref RGBValue "RGBValue's", the transforms are applied component-wise. The pixel
    00890     values are assumed to lie between the given minimum and maximum
    00891     values. In case of RGB, this is again understood component-wise. In case
    00892     of <TT>unsigned char</TT>, min and max default to 0 and 255 respectively.
    00893     Precisely, the following transform is applied to each <em> PixelValue</em>:
    00894
    00895     \f[
    00896     \begin{array}{rcl}
    00897     V_1 & = & \frac{PixelValue - min}{max - min} \\
    00898     V_2 & = & V_1^\frac{1}{brightness} \\
    00899     V_3 & = & 2 V_2 - 1 \\
    00900     V_4 & = & \left\lbrace
    00901         \begin{array}{l}
    00902          V_3^\frac{1}{contrast} \mbox{\rm \quad if  } V_3 \ge 0 \\
    00903          - (-V_3)^\frac{1}{contrast} \mbox{\rm \quad otherwise}
    00904         \end{array} \right. \\
    00905     Result & = & \frac{V_4 + 1}{2} (max - min) + min
    00906     \end{array}
    00907     \f]
    00908
    00909     If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a look-up-table is used
    00910     for faster computation.
    00911
    00912     <b> Traits defined:</b>
    00913
    00914     <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>)
    00915
    00916     <b> Usage:</b>
    00917
    00918         <b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>"<br>
    00919         Namespace: vigra
    00920
    00921     \code
    00922     vigra::BImage bimage(width, height);
    00923     double brightness, contrast;
    00924     ...
    00925     vigra::transformImage(srcImageRange(bimage), destImage(bimage),
    00926        vigra::BrightnessContrastFunctor<unsigned char>(brightness, contrast));
    00927
    00928
    00929
    00930     vigra::FImage fimage(width, height);
    00931     ...
    00932
    00933     vigra::FindMinmax<float> minmax;
    00934     vigra::inspectImage(srcImageRange(fimage), minmax);
    00935
    00936     vigra::transformImage(srcImageRange(fimage), destImage(fimage),
    00937        vigra::BrightnessContrastFunctor<float>(brightness, contrast, minmax.min, minmax.max));
    00938
    00939
    00940     \endcode
    00941
    00942     <b> Required Interface:</b>
    00943
    00944     Scalar types: must be a linear algebra (+, - *, NumericTraits),
    00945     strict weakly ordered (<), and <TT>pow()</TT> must be defined.
    00946
    00947     RGB values: the component type must meet the above requirements.
    00948 */
    00949 template <class PixelType>
    00950 class BrightnessContrastFunctor
    00951 {
    00952     typedef typename
    00953         NumericTraits<PixelType>::RealPromote promote_type;
    00954
    00955  public:
    00956
    00957         /** the functor's argument type
    00958         */
    00959     typedef PixelType argument_type;
    00960
    00961         /** the functor's result type
    00962         */
    00963     typedef PixelType result_type;
    00964
    00965         /** \deprecated use argument_type and result_type
    00966         */
    00967     typedef PixelType value_type;
    00968
    00969         /** Init functor for argument range <TT>[min, max]</TT>.
    00970             <TT>brightness</TT> and <TT>contrast</TT> values > 1 will
    00971             increase brightness and contrast, < 1 will decrease them, and == 1 means
    00972             no change.
    00973         */
    00974     BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
    00975                               argument_type const & min, argument_type const & max)
    00976     : b_(1.0/brightness),
    00977       c_(1.0/contrast),
    00978       min_(min),
    00979       diff_(max - min),
    00980       zero_(NumericTraits<promote_type>::zero()),
    00981       one_(NumericTraits<promote_type>::one())
    00982     {}
    00983
    00984         /** Calculate modified gray or color value
    00985         */
    00986     result_type operator()(argument_type const & v) const
    00987     {
    00988         promote_type v1 = (v - min_) / diff_;
    00989         promote_type brighter = VIGRA_CSTD::pow(v1, b_);
    00990         promote_type v2 = 2.0 * brighter - one_;
    00991         promote_type contrasted = (v2 < zero_) ?
    00992                                      -VIGRA_CSTD::pow(-v2, c_) :
    00993                                       VIGRA_CSTD::pow(v2, c_);
    00994         return result_type(0.5 * diff_ * (contrasted + one_) + min_);
    00995     }
    00996
    00997   private:
    00998     promote_type b_, c_;
    00999     argument_type min_;
    01000     promote_type diff_, zero_, one_;
    01001 };
    01002
    01003 template <>
    01004 class BrightnessContrastFunctor<unsigned char>
    01005 {
    01006     typedef NumericTraits<unsigned char>::RealPromote promote_type;
    01007      unsigned char lut[256];
    01008
    01009  public:
    01010
    01011     typedef unsigned char value_type;
    01012
    01013     BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
    01014                               value_type const & min = 0, value_type const & max = 255)
    01015     {
    01016         BrightnessContrastFunctor<promote_type> f(brightness, contrast, min, max);
    01017
    01018         for(int i = min; i <= max; ++i)
    01019         {
    01020             lut[i] = static_cast<unsigned char>(f(i)+0.5);
    01021         }
    01022     }
    01023
    01024     value_type operator()(value_type const & v) const
    01025     {
    01026
    01027         return lut[v];
    01028     }
    01029 };
    01030
    01031 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01032
    01033 template <class ComponentType>
    01034 class BrightnessContrastFunctor<RGBValue<ComponentType> >
    01035 {
    01036     typedef typename
    01037         NumericTraits<ComponentType>::RealPromote promote_type;
    01038     BrightnessContrastFunctor<ComponentType> red, green, blue;
    01039
    01040  public:
    01041
    01042     typedef RGBValue<ComponentType> value_type;
    01043
    01044     BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
    01045                               value_type const & min, value_type const & max)
    01046     : red(brightness, contrast, min.red(), max.red()),
    01047       green(brightness, contrast, min.green(), max.green()),
    01048       blue(brightness, contrast, min.blue(), max.blue())
    01049     {}
    01050
    01051     value_type operator()(value_type const & v) const
    01052     {
    01053
    01054         return value_type(red(v.red()), green(v.green()), blue(v.blue()));
    01055     }
    01056 };
    01057
    01058 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01059
    01060 template <>
    01061 class BrightnessContrastFunctor<RGBValue<int> >
    01062 {
    01063     typedef NumericTraits<int>::RealPromote promote_type;
    01064     BrightnessContrastFunctor<int> red, green, blue;
    01065
    01066  public:
    01067
    01068     typedef RGBValue<int> value_type;
    01069
    01070     BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
    01071                               value_type const & min, value_type const & max)
    01072     : red(brightness, contrast, min.red(), max.red()),
    01073       green(brightness, contrast, min.green(), max.green()),
    01074       blue(brightness, contrast, min.blue(), max.blue())
    01075     {}
    01076
    01077     value_type operator()(value_type const & v) const
    01078     {
    01079
    01080         return value_type(red(v.red()), green(v.green()), blue(v.blue()));
    01081     }
    01082 };
    01083
    01084 template <>
    01085 class BrightnessContrastFunctor<RGBValue<float> >
    01086 {
    01087     typedef NumericTraits<float>::RealPromote promote_type;
    01088     BrightnessContrastFunctor<float> red, green, blue;
    01089
    01090  public:
    01091
    01092     typedef RGBValue<float> value_type;
    01093
    01094     BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
    01095                               value_type const & min, value_type const & max)
    01096     : red(brightness, contrast, min.red(), max.red()),
    01097       green(brightness, contrast, min.green(), max.green()),
    01098       blue(brightness, contrast, min.blue(), max.blue())
    01099     {}
    01100
    01101     value_type operator()(value_type const & v) const
    01102     {
    01103
    01104         return value_type(red(v.red()), green(v.green()), blue(v.blue()));
    01105     }
    01106 };
    01107
    01108 template <class PixelType>
    01109 class FunctorTraits<BrightnessContrastFunctor<PixelType> >
    01110 : public FunctorTraitsBase<BrightnessContrastFunctor<PixelType> >
    01111 {
    01112   public:
    01113     typedef VigraTrueType isUnaryFunctor;
    01114 };
    01115
    01116 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01117
    01118 template <>
    01119 class BrightnessContrastFunctor<RGBValue<unsigned char> >
    01120 {
    01121     typedef NumericTraits<unsigned char>::RealPromote promote_type;
    01122     BrightnessContrastFunctor<unsigned char> red, green, blue;
    01123
    01124  public:
    01125
    01126     typedef RGBValue<unsigned char> value_type;
    01127
    01128     BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
    01129        value_type const & min = value_type(0,0,0),
    01130        value_type const & max = value_type(255, 255, 255))
    01131     : red(brightness, contrast, min.red(), max.red()),
    01132       green(brightness, contrast, min.green(), max.green()),
    01133       blue(brightness, contrast, min.blue(), max.blue())
    01134     {}
    01135
    01136     value_type operator()(value_type const & v) const
    01137     {
    01138
    01139         return value_type(red(v.red()), green(v.green()), blue(v.blue()));
    01140     }
    01141 };
    01142
    01143
    01144
    01145 /********************************************************/
    01146 /*                                                      */
    01147 /*                     VectorNormFunctor                */
    01148 /*                                                      */
    01149 /********************************************************/
    01150
    01151 /** \brief A functor for computing the vector norm
    01152
    01153     Calculate the magnitude or norm from a given vector-valued
    01154     entity. The vector type will typically be some sort of
    01155     ref vigra::TinyVector. If the vector is represented by a pair of
    01156     scalar-valued images, use \ref vigra::MagnitudeFunctor instead.
    01157
    01158     At least, the vector type is required to have a function
    01159     '<em>result</em><TT> = dot(v,v)</TT>'.
    01160
    01161     <b> Traits defined:</b>
    01162
    01163     <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>)
    01164
    01165     <b> Usage:</b>
    01166
    01167         <b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>"<br>
    01168         Namespace: vigra
    01169
    01170     \code
    01171     typedef vigra::TinyVector<float, 2> Vector;
    01172     vigra::BasicImage<Vector> grad(width, height);
    01173     vigra::FImage magn(width,height);
    01174     ...
    01175     vigra::transformImage(srcImageRange(grad), destImage(magn),
    01176                           VectorNormFunctor<float>()
    01177                           );
    01178     \endcode
    01179
    01180     \see vigra::TinyVector, dot(), vigra::MagnitudeFunctor
    01181 */
    01182 template <class ValueType>
    01183 class VectorNormFunctor
    01184 {
    01185 public:
    01186   /** the functor's argument type
    01187    */
    01188   typedef ValueType argument_type;
    01189
    01190   /** the functor's result type
    01191    */
    01192   typedef typename NumericTraits<typename ValueType::value_type>::RealPromote result_type;
    01193
    01194   /** calculate transform '<TT>sqrt(v1*v1 + v2*v2 + ...)</TT>'.
    01195    */
    01196   result_type operator()( const argument_type &a ) const
    01197   {
    01198     return VIGRA_CSTD::sqrt( dot(a,a) );
    01199   }
    01200 };    //-- class VectorNormFunctor
    01201
    01202 template <class ValueType>
    01203 class FunctorTraits<VectorNormFunctor<ValueType> >
    01204 : public FunctorTraitsBase<VectorNormFunctor<ValueType> >
    01205 {
    01206   public:
    01207     typedef VigraTrueType isUnaryFunctor;
    01208 };
    01209
    01210 /** \brief A functor for computing the squared vector norm
    01211
    01212     Calculate the squared magnitude or norm from a given
    01213     vector-valued entity. The vector type will typically be some
    01214     sort of TinyVector.
    01215
    01216     At least, the vector type is required to have a function
    01217     '<em>result</em><TT> = dot(v,v)</TT>'.
    01218
    01219     For an example of its usage see VectorNormFunctor
    01220
    01221     <b> Traits defined:</b>
    01222
    01223     <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>)
    01224
    01225     \see TinyVector, dot()
    01226 */
    01227 template <class ValueType>
    01228 class VectorNormSqFunctor
    01229 {
    01230 public:
    01231   /** the functor's argument type
    01232    */
    01233   typedef ValueType argument_type;
    01234
    01235   /** the functor's result type
    01236    */
    01237   typedef typename NumericTraits<typename ValueType::value_type>::RealPromote result_type;
    01238
    01239   /** calculate transform '<TT>v1*v1 + v2*v2 + ...</TT>'.
    01240    */
    01241   result_type operator()( const argument_type &a ) const
    01242   {
    01243     return dot(a,a);
    01244   }
    01245 };    //-- class VectorNormSqFunctor
    01246
    01247 template <class ValueType>
    01248 class FunctorTraits<VectorNormSqFunctor<ValueType> >
    01249 : public FunctorTraitsBase<VectorNormSqFunctor<ValueType> >
    01250 {
    01251   public:
    01252     typedef VigraTrueType isUnaryFunctor;
    01253 };
    01254
    01255 //@}
    01256
    01257 } // namespace vigra
    01258
    01259 #endif // VIGRA_TRANSFORMIMAGE_HXX

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.5.0 (7 Dec 2006)