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

transformimage.hxx
1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 
37 #ifndef VIGRA_TRANSFORMIMAGE_HXX
38 #define VIGRA_TRANSFORMIMAGE_HXX
39 
40 #include "utilities.hxx"
41 #include "numerictraits.hxx"
42 #include "iteratortraits.hxx"
43 #include "rgbvalue.hxx"
44 #include "functortraits.hxx"
45 
46 namespace vigra {
47 
48 /** \addtogroup TransformAlgo Algorithms to Transform Images
49  Apply functor to calculate a pixelwise transformation of one image
50 
51  @{
52 */
53 
54 /********************************************************/
55 /* */
56 /* transformLine */
57 /* */
58 /********************************************************/
59 
60 template <class SrcIterator, class SrcAccessor,
61  class DestIterator, class DestAccessor, class Functor>
62 void
63 transformLine(SrcIterator s,
64  SrcIterator send, SrcAccessor src,
65  DestIterator d, DestAccessor dest,
66  Functor const & f)
67 {
68  for(; s != send; ++s, ++d)
69  dest.set(f(src(s)), d);
70 }
71 
72 template <class SrcIterator, class SrcAccessor,
73  class MaskIterator, class MaskAccessor,
74  class DestIterator, class DestAccessor,
75  class Functor>
76 void
77 transformLineIf(SrcIterator s,
78  SrcIterator send, SrcAccessor src,
79  MaskIterator m, MaskAccessor mask,
80  DestIterator d, DestAccessor dest,
81  Functor const & f)
82 {
83  for(; s != send; ++s, ++d, ++m)
84  if(mask(m))
85  dest.set(f(src(s)), d);
86 }
87 
88 /********************************************************/
89 /* */
90 /* transformImage */
91 /* */
92 /********************************************************/
93 
94 /** \brief Apply unary point transformation to each pixel.
95 
96  The transformation given by the functor is applied to every source
97  pixel and the result written into the corresponding destination pixel.
98  The function uses accessors to access the pixel data.
99  Note that the unary functors of the STL can be used in addition to
100  the functors specifically defined in \ref TransformFunctor.
101  Creation of new functors is easiest by using \ref FunctorExpressions.
102 
103  <b> Declarations:</b>
104 
105  pass arguments explicitly:
106  \code
107  namespace vigra {
108  template <class SrcImageIterator, class SrcAccessor,
109  class DestImageIterator, class DestAccessor, class Functor>
110  void
111  transformImage(SrcImageIterator src_upperleft,
112  SrcImageIterator src_lowerright, SrcAccessor sa,
113  DestImageIterator dest_upperleft, DestAccessor da,
114  Functor const & f)
115  }
116  \endcode
117 
118 
119  use argument objects in conjunction with \ref ArgumentObjectFactories :
120  \code
121  namespace vigra {
122  template <class SrcImageIterator, class SrcAccessor,
123  class DestImageIterator, class DestAccessor, class Functor>
124  void
125  transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
126  pair<DestImageIterator, DestAccessor> dest,
127  Functor const & f)
128  }
129  \endcode
130 
131  <b> Usage:</b>
132 
133  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br>
134  Namespace: vigra
135 
136  \code
137 
138  #include <cmath> // for sqrt()
139 
140  vigra::transformImage(srcImageRange(src),
141  destImage(dest),
142  (double(*)(double))&std::sqrt );
143 
144  \endcode
145 
146  <b> Required Interface:</b>
147 
148  \code
149  SrcImageIterator src_upperleft, src_lowerright;
150  DestImageIterator dest_upperleft;
151  SrcImageIterator::row_iterator sx = src_upperleft.rowIterator();
152  DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
153 
154  SrcAccessor src_accessor;
155  DestAccessor dest_accessor;
156 
157  Functor functor;
158 
159  dest_accessor.set(functor(src_accessor(sx)), dx);
160 
161  \endcode
162 
163 */
164 doxygen_overloaded_function(template <...> void transformImage)
165 
166 template <class SrcImageIterator, class SrcAccessor,
167  class DestImageIterator, class DestAccessor, class Functor>
168 void
169 transformImage(SrcImageIterator src_upperleft,
170  SrcImageIterator src_lowerright, SrcAccessor sa,
171  DestImageIterator dest_upperleft, DestAccessor da,
172  Functor const & f)
173 {
174  int w = src_lowerright.x - src_upperleft.x;
175 
176  for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y)
177  {
178  transformLine(src_upperleft.rowIterator(),
179  src_upperleft.rowIterator() + w, sa,
180  dest_upperleft.rowIterator(), da, f);
181  }
182 }
183 
184 template <class SrcImageIterator, class SrcAccessor,
185  class DestImageIterator, class DestAccessor, class Functor>
186 inline
187 void
188 transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
189  pair<DestImageIterator, DestAccessor> dest,
190  Functor const & f)
191 {
192  transformImage(src.first, src.second, src.third,
193  dest.first, dest.second, f);
194 }
195 
196 /********************************************************/
197 /* */
198 /* transformImageIf */
199 /* */
200 /********************************************************/
201 
202 /** \brief Apply unary point transformation to each pixel within the ROI
203  (i.e., where the mask is non-zero).
204 
205  The transformation given by the functor is applied to every source
206  pixel in the ROI (i.e. when the return vlaue of the mask's accessor
207  is not zero)
208  and the result is written into the corresponding destination pixel.
209  The function uses accessors to access the pixel data.
210  Note that the unary functors of the STL can be used in addition to
211  the functors specifically defined in \ref TransformFunctor.
212  Creation of new functors is easiest by using \ref FunctorExpressions.
213 
214  <b> Declarations:</b>
215 
216  pass arguments explicitly:
217  \code
218  namespace vigra {
219  template <class SrcImageIterator, class SrcAccessor,
220  class MaskImageIterator, class MaskAccessor,
221  class DestImageIterator, clas DestAccessor,
222  class Functor>
223  void
224  transformImageIf(SrcImageIterator src_upperleft,
225  SrcImageIterator src_lowerright, SrcAccessor sa,
226  MaskImageIterator mask_upperleft, MaskAccessor ma,
227  DestImageIterator dest_upperleft, DestAccessor da,
228  Functor const & f)
229  }
230  \endcode
231 
232 
233  use argument objects in conjunction with \ref ArgumentObjectFactories :
234  \code
235  namespace vigra {
236  template <class SrcImageIterator, class SrcAccessor,
237  class MaskImageIterator, class MaskAccessor,
238  class DestImageIterator, clas DestAccessor,
239  class Functor>
240  void
241  transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
242  pair<MaskImageIterator, MaskAccessor> mask,
243  pair<DestImageIterator, DestAccessor> dest,
244  Functor const & f)
245  }
246  \endcode
247 
248  <b> Usage:</b>
249 
250  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br>
251  Namespace: vigra
252 
253  \code
254  #include <cmath> // for sqrt()
255 
256  vigra::transformImageIf(srcImageRange(src),
257  maskImage(mask),
258  destImage(dest),
259  (double(*)(double))&std::sqrt );
260 
261  \endcode
262 
263  <b> Required Interface:</b>
264 
265  \code
266  SrcImageIterator src_upperleft, src_lowerright;
267  DestImageIterator dest_upperleft;
268  MaskImageIterator mask_upperleft;
269  SrcImageIterator::row_iterator sx = src_upperleft.rowIterator();
270  MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
271  DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
272 
273  SrcAccessor src_accessor;
274  DestAccessor dest_accessor;
275  MaskAccessor mask_accessor;
276  Functor functor;
277 
278  if(mask_accessor(mx))
279  dest_accessor.set(functor(src_accessor(sx)), dx);
280 
281  \endcode
282 
283 */
285 
286 template <class SrcImageIterator, class SrcAccessor,
287  class MaskImageIterator, class MaskAccessor,
288  class DestImageIterator, class DestAccessor,
289  class Functor>
290 void
291 transformImageIf(SrcImageIterator src_upperleft,
292  SrcImageIterator src_lowerright, SrcAccessor sa,
293  MaskImageIterator mask_upperleft, MaskAccessor ma,
294  DestImageIterator dest_upperleft, DestAccessor da,
295  Functor const & f)
296 {
297  int w = src_lowerright.x - src_upperleft.x;
298 
299  for(; src_upperleft.y < src_lowerright.y;
300  ++src_upperleft.y, ++mask_upperleft.y, ++dest_upperleft.y)
301  {
302  transformLineIf(src_upperleft.rowIterator(),
303  src_upperleft.rowIterator() + w, sa,
304  mask_upperleft.rowIterator(), ma,
305  dest_upperleft.rowIterator(), da, f);
306  }
307 }
308 
309 template <class SrcImageIterator, class SrcAccessor,
310  class MaskImageIterator, class MaskAccessor,
311  class DestImageIterator, class DestAccessor,
312  class Functor>
313 inline
314 void
315 transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
316  pair<MaskImageIterator, MaskAccessor> mask,
317  pair<DestImageIterator, DestAccessor> dest,
318  Functor const & f)
319 {
320  transformImageIf(src.first, src.second, src.third,
321  mask.first, mask.second,
322  dest.first, dest.second, f);
323 }
324 
325 /********************************************************/
326 /* */
327 /* gradientBasedTransform */
328 /* */
329 /********************************************************/
330 
331 /** \brief Calculate a function of the image gradient.
332 
333  The gradient and the function represented by <TT>Functor f</TT>
334  are calculated in one go: for each location, the symmetric
335  difference in x- and y-directions (asymmetric difference at the
336  image borders) are passed to the given functor, and the result is
337  written the destination image. Functors to be used with this
338  function include \ref MagnitudeFunctor and \ref
339  RGBGradientMagnitudeFunctor.
340 
341  <b> Declarations:</b>
342 
343  pass arguments explicitly:
344  \code
345  namespace vigra {
346  template <class SrcImageIterator, class SrcAccessor,
347  class DestImageIterator, class DestAccessor, class Functor>
348  void
349  gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa,
350  DestImageIterator destul, DestAccessor da, Functor const & f)
351  }
352  \endcode
353 
354 
355  use argument objects in conjunction with \ref ArgumentObjectFactories :
356  \code
357  namespace vigra {
358  template <class SrcImageIterator, class SrcAccessor,
359  class DestImageIterator, class DestAccessor, class Functor>
360  void
361  gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
362  pair<DestImageIterator, DestAccessor> dest, Functor const & const & f)
363  }
364  \endcode
365 
366  <b> Usage:</b>
367 
368  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>>
369 
370 
371  \code
372  vigra::FImage src(w,h), magnitude(w,h);
373  ...
374 
375  gradientBasedTransform(srcImageRange(src), destImage(magnitude),
376  vigra::MagnitudeFunctor<float>());
377  \endcode
378 
379  <b> Required Interface:</b>
380 
381  \code
382  SrcImageIterator is, isend;
383  DestImageIterator id;
384 
385  SrcAccessor src_accessor;
386  DestAccessor dest_accessor;
387 
388  typename NumericTraits<typename SrcAccessor::value_type>::RealPromote
389  diffx, diffy;
390 
391  diffx = src_accessor(is, Diff2D(-1,0)) - src_accessor(is, Diff2D(1,0));
392  diffy = src_accessor(is, Diff2D(0,-1)) - src_accessor(is, Diff2D(0,1));
393 
394  Functor f;
395 
396  dest_accessor.set(f(diffx, diffy), id);
397 
398  \endcode
399 
400 */
402 
403 template <class SrcImageIterator, class SrcAccessor,
404  class DestImageIterator, class DestAccessor, class Functor>
405 void
406 gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa,
407  DestImageIterator destul, DestAccessor da, Functor const & grad)
408 {
409  int w = srclr.x - srcul.x;
410  int h = srclr.y - srcul.y;
411  int x,y;
412 
413  SrcImageIterator sy = srcul;
414  DestImageIterator dy = destul;
415 
416  static const Diff2D left(-1,0);
417  static const Diff2D right(1,0);
418  static const Diff2D top(0,-1);
419  static const Diff2D bottom(0,1);
420 
421  typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
422  TmpType diffx, diffy;
423 
424  SrcImageIterator sx = sy;
425  DestImageIterator dx = dy;
426 
427  diffx = sa(sx) - sa(sx, right);
428  diffy = sa(sx) - sa(sx, bottom);
429  da.set(grad(diffx, diffy), dx);
430 
431  for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
432  {
433  diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
434  diffy = sa(sx) - sa(sx, bottom);
435  da.set(grad(diffx, diffy), dx);
436  }
437 
438  diffx = sa(sx, left) - sa(sx);
439  diffy = sa(sx) - sa(sx, bottom);
440  da.set(grad(diffx, diffy), dx);
441 
442  ++sy.y;
443  ++dy.y;
444 
445  for(y=2; y<h; ++y, ++sy.y, ++dy.y)
446  {
447  sx = sy;
448  dx = dy;
449 
450  diffx = sa(sx) - sa(sx, right);
451  diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
452  da.set(grad(diffx, diffy), dx);
453 
454  for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
455  {
456  diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
457  diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
458  da.set(grad(diffx, diffy), dx);
459  }
460 
461  diffx = sa(sx, left) - sa(sx);
462  diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
463  da.set(grad(diffx, diffy), dx);
464  }
465 
466  sx = sy;
467  dx = dy;
468 
469  diffx = sa(sx) - sa(sx, right);
470  diffy = sa(sx, top) - sa(sx);
471  da.set(grad(diffx, diffy), dx);
472 
473  for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
474  {
475  diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
476  diffy = sa(sx, top) - sa(sx);
477  da.set(grad(diffx, diffy), dx);
478  }
479 
480  diffx = sa(sx, left) - sa(sx);
481  diffy = sa(sx, top) - sa(sx);
482  da.set(grad(diffx, diffy), dx);
483 }
484 
485 template <class SrcImageIterator, class SrcAccessor,
486  class DestImageIterator, class DestAccessor, class Functor>
487 inline
488 void
489 gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
490  pair<DestImageIterator, DestAccessor> dest, Functor const & grad)
491 {
492  gradientBasedTransform(src.first, src.second, src.third,
493  dest.first, dest.second, grad);
494 }
495 
496 /** @} */
497 /** \addtogroup TransformFunctor Functors to Transform Images
498 
499  Note that the unary functors of the STL can also be used in
500  connection with \ref transformImage().
501 */
502 //@{
503 
504 template <class DestValueType, class Multiplier = double>
505 class LinearIntensityTransform
506 {
507  public:
508  /* the functors argument type (actually, since
509  <tt>operator()</tt> is a template, much more types are possible)
510  */
511  typedef DestValueType argument_type;
512 
513  /* the functors result type
514  */
515  typedef DestValueType result_type;
516 
517  /* \deprecated use argument_type and result_type
518  */
519  typedef DestValueType value_type;
520 
521  /* type of the offset (used in internal calculations to prevent
522  overflows and minimize round-off errors).
523  */
524  typedef typename
525  NumericTraits<DestValueType>::RealPromote argument_promote;
526 
527  /* type of the scale factor
528  */
529  typedef Multiplier scalar_multiplier_type;
530 
531  /* init scale and offset
532  */
533  LinearIntensityTransform(scalar_multiplier_type scale, argument_promote offset)
534  : scale_(scale), offset_(offset)
535  {}
536 
537  /* calculate transform
538  */
539  template <class SrcValueType>
540  result_type operator()(SrcValueType const & s) const
541  {
542  return NumericTraits<result_type>::fromRealPromote(scale_ * (s + offset_));
543  }
544 
545  private:
546 
547  scalar_multiplier_type scale_;
548  argument_promote offset_;
549 };
550 
551 template <class DestValueType, class Multiplier>
552 class FunctorTraits<LinearIntensityTransform<DestValueType, Multiplier> >
553 : public FunctorTraitsBase<LinearIntensityTransform<DestValueType, Multiplier> >
554 {
555  public:
556  typedef VigraTrueType isUnaryFunctor;
557 };
558 
559 template <class DestValueType, class Multiplier = double>
560 class ScalarIntensityTransform
561 {
562  public:
563  /* the functors argument type (actually, since
564  <tt>operator()</tt> is a template, much more types are possible)
565  */
566  typedef DestValueType argument_type;
567 
568  /* the functors result type
569  */
570  typedef DestValueType result_type;
571 
572  /* \deprecated use argument_type and result_type
573  */
574  typedef DestValueType value_type;
575 
576  /* type of the scale factor
577  */
578  typedef Multiplier scalar_multiplier_type;
579 
580  /* init scale
581  */
582  ScalarIntensityTransform(scalar_multiplier_type scale)
583  : scale_(scale)
584  {}
585 
586  /* calculate transform
587  */
588  template <class SrcValueType>
589  result_type operator()(SrcValueType const & s) const
590  {
591  return NumericTraits<result_type>::fromRealPromote(scale_ * s);
592  }
593 
594  private:
595  scalar_multiplier_type scale_;
596 };
597 
598 template <class DestValueType, class Multiplier>
599 class FunctorTraits<ScalarIntensityTransform<DestValueType, Multiplier> >
600 : public FunctorTraitsBase<ScalarIntensityTransform<DestValueType, Multiplier> >
601 {
602  public:
603  typedef VigraTrueType isUnaryFunctor;
604 };
605 
606 /********************************************************/
607 /* */
608 /* linearIntensityTransform */
609 /* */
610 /********************************************************/
611 
612 /** \brief Apply a linear transform to the source pixel values
613 
614  Factory function for a functor that linearly transforms the
615  source pixel values. The functor applies the transform
616  '<TT>destvalue = scale * (srcvalue + offset)</TT>' to every pixel.
617  This can, for example, be used to transform images into the visible
618  range 0...255 or to invert an image.
619 
620  If you leave out the second parameter / offset, you will get an
621  optimized version of the functor which only scales by the given
622  factor, however you have to make the template parameter (pixel
623  type) explicit then.
624 
625  <b> Traits defined:</b>
626 
627  <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
628 
629  <b> Declaration:</b>
630 
631  \code
632  namespace vigra {
633  template <class Multiplier, class DestValueType>
634  LinearIntensityTransform<DestValueType, Multiplier>
635  linearIntensityTransform(Multiplier scale, DestValueType offset);
636 
637  template <class DestValueType, class Multiplier>
638  ScalarIntensityTransform<DestValueType, Multiplier>
639  linearIntensityTransform(Multiplier scale);
640  }
641  \endcode
642 
643  <b> Usage:</b>
644 
645  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br>
646  Namespace: vigra
647 
648  \code
649  vigra::IImage src(width, height);
650  vigra::BImage dest(width, height);
651  ...
652  vigra::FindMinMax<IImage::PixelType> minmax; // functor to find range
653 
654  vigra::inspectImage(srcImageRange(src), minmax); // find original range
655 
656  // transform to range 0...255
657  vigra::transformImage(srcImageRange(src), destImage(dest),
658  linearIntensityTransform(
659  255.0 / (minmax.max - minmax.min), // scaling
660  - minmax.min)); // offset
661  \endcode
662 
663  The one-parameter version can be used like this:
664 
665  \code
666  // scale from 0..255 to 0..1.0
667  FImage dest(src.size());
668 
669  vigra::transformImage(srcImageRange(src), destImage(dest),
670  linearIntensityTransform<float>(1.0 / 255));
671  \endcode
672 
673  <b> Required Interface:</b>
674 
675  The source and destination value types must be models of \ref LinearSpace in both cases.
676 
677 */
678 template <class Multiplier, class DestValueType>
679 LinearIntensityTransform<DestValueType, Multiplier>
680 linearIntensityTransform(Multiplier scale, DestValueType offset)
681 {
682  return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
683 }
684 
685 template <class DestValueType, class Multiplier>
686 ScalarIntensityTransform<DestValueType, Multiplier>
687 linearIntensityTransform(Multiplier scale)
688 {
689  return ScalarIntensityTransform<DestValueType, Multiplier>(scale);
690 }
691 
692 /********************************************************/
693 /* */
694 /* linearRangeMapping */
695 /* */
696 /********************************************************/
697 
698 /** \brief Map a source intensity range linearly to a destination range.
699 
700  Factory function for a functor that linearly transforms the
701  source pixel values. The functor applies the transform
702  '<TT>destvalue = scale * (srcvalue + offset)</TT>' to every pixel,
703  where <tt>scale = (dest_max - dest_min) / (src_max - src_min)</tt>
704  and <tt>offset = dest_min / scale - src_min</tt>. As a result,
705  the pixel values <tt>src_max</tt>, <tt>src_min</tt> in the source image
706  are mapped onto <tt>dest_max</tt>, <tt>dest_min</tt> respectively.
707  This works for scalar as well as vector pixel types.
708 
709  <b> Declaration:</b>
710 
711  \code
712  namespace vigra {
713  template <class SrcValueType, class DestValueType>
714  LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
715  linearRangeMapping(SrcValueType src_min, SrcValueType src_max,
716  DestValueType dest_min, DestValueType dest_max );
717  }
718  \endcode
719 
720  <b> Usage:</b>
721 
722  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br>
723  Namespace: vigra
724 
725  \code
726  vigra::IImage src(width, height);
727  vigra::BImage dest(width, height);
728  ...
729  vigra::FindMinMax<IImage::PixelType> minmax; // functor to find range
730 
731  vigra::inspectImage(srcImageRange(src), minmax); // find original range
732 
733  // transform to range 0...255
734  vigra::transformImage(srcImageRange(src), destImage(dest),
735  linearRangeTransform(
736  minmax.min, minmax.max, // src range
737  (unsigned char)0, (unsigned char)255) // dest range
738  );
739  \endcode
740 
741  <b> Required Interface:</b>
742 
743  The source and destination value types must be models of \ref LinearSpace in both cases.
744 
745 */
746 template <class SrcValueType, class DestValueType>
747 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
748 linearRangeMapping(SrcValueType src_min, SrcValueType src_max,
749  DestValueType dest_min, DestValueType dest_max )
750 {
751  return linearRangeMapping(src_min, src_max, dest_min, dest_max,
752  typename NumericTraits<DestValueType>::isScalar());
753 }
754 
755 template <class SrcValueType, class DestValueType>
756 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
758  SrcValueType src_min, SrcValueType src_max,
759  DestValueType dest_min, DestValueType dest_max,
760  VigraTrueType /* isScalar */ )
761 {
762  typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
763  Multiplier diff = src_max - src_min;
764  Multiplier scale = diff == NumericTraits<Multiplier>::zero()
765  ? NumericTraits<Multiplier>::one()
766  : (dest_max - dest_min) / diff;
767  return LinearIntensityTransform<DestValueType, Multiplier>(
768  scale, dest_min / scale - src_min );
769 }
770 
771 template <class SrcValueType, class DestValueType>
772 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
774  SrcValueType src_min, SrcValueType src_max,
775  DestValueType dest_min, DestValueType dest_max,
776  VigraFalseType /* isScalar */ )
777 {
778  typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
779  typedef typename Multiplier::value_type MComponent;
780  Multiplier scale(dest_max), offset(dest_max);
781  for(unsigned int i=0; i<src_min.size(); ++i)
782  {
783  MComponent diff = src_max[i] - src_min[i];
784  scale[i] = diff == NumericTraits<MComponent>::zero()
785  ? NumericTraits<MComponent>::one()
786  : (dest_max[i] - dest_min[i]) / diff;
787  offset[i] = dest_min[i] / scale[i] - src_min[i];
788  }
789  return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
790 }
791 
792 /********************************************************/
793 /* */
794 /* Threshold */
795 /* */
796 /********************************************************/
797 
798 /** \brief Threshold an image.
799 
800  If a source pixel is above or equal the lower and below
801  or equal the higher threshold (i.e. within the closed interval
802  [lower, heigher]) the destination pixel is set to 'yesresult',
803  otherwise to 'noresult'.
804 
805  <b> Traits defined:</b>
806 
807  <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
808 
809  <b> Usage:</b>
810 
811  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br>
812  Namespace: vigra
813 
814  \code
815  vigra::BImage src(width, height), dest(width, height);
816  ...
817  vigra::transformImage(src.upperLeft(), src.lowerRight(), src.accessor(),
818  dest.upperLeft(), dest.accessor(),
819  vigra::Threshold<
820  vigra::BImage::PixelType, vigra::BImage::PixelType>(10, 100, 0, 255));
821 
822  \endcode
823 
824  <b> Required Interface:</b>
825 
826  \code
827 
828  SrcValueType src;
829  DestValueType dest, yesresult, noresult;
830 
831  dest = ((src < lower) || (higher < src)) ? noresult : yesresult;
832 
833  \endcode
834 
835 */
836 template <class SrcValueType, class DestValueType>
838 {
839  public:
840 
841  /** the functor's argument type
842  */
843  typedef SrcValueType argument_type;
844 
845  /** the functor's result type
846  */
847  typedef DestValueType result_type;
848 
849  /** init thresholds and return values
850  */
852  result_type noresult, result_type yesresult)
853  : lower_(lower), higher_(higher),
854  yesresult_(yesresult), noresult_(noresult)
855  {}
856 
857  /** calculate transform
858  */
860  {
861  return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_;
862  }
863 
864  private:
865 
866  argument_type lower_, higher_;
867  result_type yesresult_, noresult_;
868 };
869 
870 template <class SrcValueType, class DestValueType>
871 class FunctorTraits<Threshold<SrcValueType, DestValueType> >
872 : public FunctorTraitsBase<Threshold<SrcValueType, DestValueType> >
873 {
874  public:
875  typedef VigraTrueType isUnaryFunctor;
876 };
877 
878 /********************************************************/
879 /* */
880 /* BrightnessContrastFunctor */
881 /* */
882 /********************************************************/
883 
884 /** \brief Adjust brightness and contrast of an image.
885 
886  This functor applies a gamma correction to each pixel in order to
887  modify the brightness of the image. To the result of the gamma
888  correction, another transform is applied that modifies the
889  contrast. The brightness and contrast parameters must be
890  positive. Values greater than 1 will increase image brightness or
891  contrast respectively, values smaller than 1 decrease them. A
892  value of exactly 1 will have no effect. If contrast is set to 1,
893  the result is equivalent to that of the GammaFunctor with gamma =
894  1./brightness.
895 
896  For \ref RGBValue "RGBValue's", the transforms are applied
897  component-wise. The pixel values are assumed to lie between the
898  given minimum and maximum values (in case of RGB, this is again
899  understood component-wise). In case of <TT>unsigned char</TT>, min
900  and max default to 0 and 255 respectively. Precisely, the
901  following transform is applied to each <em> PixelValue</em>:
902 
903  \f[
904  \begin{array}{rcl}
905  V_1 & = & \frac{PixelValue - min}{max - min} \\
906  V_2 & = & V_1^\frac{1}{brightness} \\
907  V_3 & = & 2 V_2 - 1 \\
908  V_4 & = & \left\lbrace
909  \begin{array}{l}
910  V_3^\frac{1}{contrast} \mbox{\rm \quad if } V_3 \ge 0 \\
911  - (-V_3)^\frac{1}{contrast} \mbox{\rm \quad otherwise}
912  \end{array} \right. \\
913  Result & = & \frac{V_4 + 1}{2} (max - min) + min
914  \end{array}
915  \f]
916 
917  If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a look-up-table is used
918  for faster computation.
919 
920  <b> Traits defined:</b>
921 
922  <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
923 
924  <b> Usage:</b>
925 
926  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br>
927  Namespace: vigra
928 
929  \code
930  vigra::BImage bimage(width, height);
931  double brightness, contrast;
932  ...
933  vigra::transformImage(srcImageRange(bimage), destImage(bimage),
934  vigra::BrightnessContrastFunctor<unsigned char>(brightness, contrast));
935 
936 
937 
938  vigra::FImage fimage(width, height);
939  ...
940 
941  vigra::FindMinmax<float> minmax;
942  vigra::inspectImage(srcImageRange(fimage), minmax);
943 
944  vigra::transformImage(srcImageRange(fimage), destImage(fimage),
945  vigra::BrightnessContrastFunctor<float>(brightness, contrast, minmax.min, minmax.max));
946 
947 
948  \endcode
949 
950  <b> Required Interface:</b>
951 
952  Scalar types: must be a linear algebra (+, - *, NumericTraits),
953  strict weakly ordered (<), and <TT>pow()</TT> must be defined.
954 
955  RGB values: the component type must meet the above requirements.
956 */
957 template <class PixelType>
959 {
960  typedef typename
961  NumericTraits<PixelType>::RealPromote promote_type;
962 
963  public:
964 
965  /** the functor's argument type
966  */
967  typedef PixelType argument_type;
968 
969  /** the functor's result type
970  */
971  typedef PixelType result_type;
972 
973  /** \deprecated use argument_type and result_type
974  */
975  typedef PixelType value_type;
976 
977  /** Init functor for argument range <TT>[min, max]</TT>.
978  <TT>brightness</TT> and <TT>contrast</TT> values > 1 will
979  increase brightness and contrast, < 1 will decrease them, and == 1 means
980  no change.
981  */
982  BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
983  argument_type const & min, argument_type const & max)
984  : b_(1.0/brightness),
985  c_(1.0/contrast),
986  min_(min),
987  diff_(max - min),
988  zero_(NumericTraits<promote_type>::zero()),
989  one_(NumericTraits<promote_type>::one())
990  {}
991 
992  /** Calculate modified gray or color value
993  */
995  {
996  promote_type v1 = (v - min_) / diff_;
997  promote_type brighter = VIGRA_CSTD::pow(v1, b_);
998  promote_type v2 = 2.0 * brighter - one_;
999  promote_type contrasted = (v2 < zero_) ?
1000  -VIGRA_CSTD::pow(-v2, c_) :
1001  VIGRA_CSTD::pow(v2, c_);
1002  return result_type(0.5 * diff_ * (contrasted + one_) + min_);
1003  }
1004 
1005  private:
1006  promote_type b_, c_;
1007  argument_type min_;
1008  promote_type diff_, zero_, one_;
1009 };
1010 
1011 template <>
1012 class BrightnessContrastFunctor<unsigned char>
1013 {
1014  typedef NumericTraits<unsigned char>::RealPromote promote_type;
1015  unsigned char lut[256];
1016 
1017  public:
1018 
1019  typedef unsigned char value_type;
1020 
1021  BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
1022  value_type const & min = 0, value_type const & max = 255)
1023  {
1024  BrightnessContrastFunctor<promote_type> f(brightness, contrast, min, max);
1025 
1026  for(int i = min; i <= max; ++i)
1027  {
1028  lut[i] = static_cast<unsigned char>(f(i)+0.5);
1029  }
1030  }
1031 
1032  value_type operator()(value_type const & v) const
1033  {
1034 
1035  return lut[v];
1036  }
1037 };
1038 
1039 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1040 
1041 template <class ComponentType>
1042 class BrightnessContrastFunctor<RGBValue<ComponentType> >
1043 {
1044  typedef typename
1045  NumericTraits<ComponentType>::RealPromote promote_type;
1046  BrightnessContrastFunctor<ComponentType> red, green, blue;
1047 
1048  public:
1049 
1050  typedef RGBValue<ComponentType> value_type;
1051 
1052  BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
1053  value_type const & min, value_type const & max)
1054  : red(brightness, contrast, min.red(), max.red()),
1055  green(brightness, contrast, min.green(), max.green()),
1056  blue(brightness, contrast, min.blue(), max.blue())
1057  {}
1058 
1059  value_type operator()(value_type const & v) const
1060  {
1061 
1062  return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1063  }
1064 };
1065 
1066 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1067 
1068 template <>
1069 class BrightnessContrastFunctor<RGBValue<int> >
1070 {
1071  typedef NumericTraits<int>::RealPromote promote_type;
1072  BrightnessContrastFunctor<int> red, green, blue;
1073 
1074  public:
1075 
1076  typedef RGBValue<int> value_type;
1077 
1078  BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
1079  value_type const & min, value_type const & max)
1080  : red(brightness, contrast, min.red(), max.red()),
1081  green(brightness, contrast, min.green(), max.green()),
1082  blue(brightness, contrast, min.blue(), max.blue())
1083  {}
1084 
1085  value_type operator()(value_type const & v) const
1086  {
1087 
1088  return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1089  }
1090 };
1091 
1092 template <>
1093 class BrightnessContrastFunctor<RGBValue<float> >
1094 {
1095  typedef NumericTraits<float>::RealPromote promote_type;
1096  BrightnessContrastFunctor<float> red, green, blue;
1097 
1098  public:
1099 
1100  typedef RGBValue<float> value_type;
1101 
1102  BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
1103  value_type const & min, value_type const & max)
1104  : red(brightness, contrast, min.red(), max.red()),
1105  green(brightness, contrast, min.green(), max.green()),
1106  blue(brightness, contrast, min.blue(), max.blue())
1107  {}
1108 
1109  value_type operator()(value_type const & v) const
1110  {
1111 
1112  return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1113  }
1114 };
1115 
1116 template <class PixelType>
1117 class FunctorTraits<BrightnessContrastFunctor<PixelType> >
1118 : public FunctorTraitsBase<BrightnessContrastFunctor<PixelType> >
1119 {
1120  public:
1121  typedef VigraTrueType isUnaryFunctor;
1122 };
1123 
1124 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1125 
1126 template <>
1127 class BrightnessContrastFunctor<RGBValue<unsigned char> >
1128 {
1129  typedef NumericTraits<unsigned char>::RealPromote promote_type;
1130  BrightnessContrastFunctor<unsigned char> red, green, blue;
1131 
1132  public:
1133 
1134  typedef RGBValue<unsigned char> value_type;
1135 
1136  BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
1137  value_type const & min = value_type(0,0,0),
1138  value_type const & max = value_type(255, 255, 255))
1139  : red(brightness, contrast, min.red(), max.red()),
1140  green(brightness, contrast, min.green(), max.green()),
1141  blue(brightness, contrast, min.blue(), max.blue())
1142  {}
1143 
1144  value_type operator()(value_type const & v) const
1145  {
1146 
1147  return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1148  }
1149 };
1150 
1151 
1152 
1153 /********************************************************/
1154 /* */
1155 /* GammaFunctor */
1156 /* */
1157 /********************************************************/
1158 
1159 /** \brief Perform gamma correction of an image.
1160 
1161  This functor applies a gamma correction to each pixel in order to
1162  modify the brightness of the image. Gamma values smaller than 1
1163  will increase image brightness, whereas values greater than 1
1164  decrease it. A value of gamma = 1 will have no effect. (See also
1165  BrightnessContrastFunctor, which additionally changes the
1166  contrast.)
1167 
1168  For \ref RGBValue "RGBValue's", the transforms are applied
1169  component-wise. For ease of use, the pixel values are assumed to
1170  lie between the given minimum and maximum values (in case of RGB,
1171  this is again understood component-wise). In case of <TT>unsigned
1172  char</TT>, min and max default to 0 and 255 respectively.
1173  Precisely, the following transform is applied to each <em>
1174  PixelValue</em>:
1175 
1176  \f[
1177  \begin{array}{rcl}
1178  V_1 & = & \frac{PixelValue - min}{max - min} \\
1179  V_2 & = & V_1^{gamma} \\
1180  Result & = & V_2 (max - min) + min
1181  \end{array}
1182  \f]
1183 
1184  If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a
1185  look-up-table is used for faster computation.
1186 
1187  <b> Traits defined:</b>
1188 
1189  <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1190 
1191  <b> Usage:</b>
1192 
1193  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br>
1194  Namespace: vigra
1195 
1196  \code
1197  vigra::BImage bimage(width, height);
1198  double gamma;
1199  ...
1200  vigra::transformImage(srcImageRange(bimage), destImage(bimage),
1201  vigra::GammaFunctor<unsigned char>(gamma));
1202 
1203 
1204 
1205  vigra::FImage fimage(width, height);
1206  ...
1207 
1208  vigra::FindMinmax<float> minmax;
1209  vigra::inspectImage(srcImageRange(fimage), minmax);
1210 
1211  vigra::transformImage(srcImageRange(fimage), destImage(fimage),
1212  vigra::GammaFunctor<float>(gamma, minmax.min, minmax.max));
1213 
1214  \endcode
1215 
1216  <b> Required Interface:</b>
1217 
1218  Scalar types: must be a linear algebra (+, - *, NumericTraits),
1219  strict weakly ordered (<), and <TT>pow()</TT> must be defined.
1220 
1221  RGB values: the component type must meet the above requirements.
1222 */
1223 template <class PixelType>
1225 {
1226  typedef typename
1227  NumericTraits<PixelType>::RealPromote promote_type;
1228 
1229  public:
1230 
1231  /** the functor's argument type
1232  */
1233  typedef PixelType argument_type;
1234 
1235  /** the functor's result type
1236  */
1237  typedef PixelType result_type;
1238 
1239  /** \deprecated use argument_type and result_type
1240  */
1241  typedef PixelType value_type;
1242 
1243  /** Init functor for argument range <TT>[min, max]</TT>.
1244  <TT>gamma</TT> values < 1 will increase brightness, > 1
1245  will decrease it (gamma == 1 means no change).
1246  */
1247  GammaFunctor(double gamma,
1248  argument_type const & min, argument_type const & max)
1249  : gamma_((promote_type)gamma),
1250  min_(min),
1251  diff_(max - min),
1252  zero_(NumericTraits<promote_type>::zero()),
1253  one_(NumericTraits<promote_type>::one())
1254  {}
1255 
1256  /** Calculate modified gray or color value
1257  */
1259  {
1260  promote_type v1 = (v - min_) / diff_;
1261  promote_type brighter = VIGRA_CSTD::pow(v1, gamma_);
1262  return result_type(diff_ * brighter + min_);
1263  }
1264 
1265  private:
1266  promote_type gamma_;
1267  argument_type min_;
1268  promote_type diff_, zero_, one_;
1269 };
1270 
1271 template <>
1272 class GammaFunctor<unsigned char>
1273 {
1274  typedef NumericTraits<unsigned char>::RealPromote promote_type;
1275  unsigned char lut[256];
1276 
1277  public:
1278 
1279  typedef unsigned char value_type;
1280 
1281  GammaFunctor(promote_type gamma,
1282  value_type const & min = 0, value_type const & max = 255)
1283  {
1284  GammaFunctor<promote_type> f(gamma, min, max);
1285 
1286  for(int i = min; i <= max; ++i)
1287  {
1288  lut[i] = static_cast<unsigned char>(f(i)+0.5);
1289  }
1290  }
1291 
1292  value_type operator()(value_type const & v) const
1293  {
1294 
1295  return lut[v];
1296  }
1297 };
1298 
1299 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1300 
1301 template <class ComponentType>
1302 class GammaFunctor<RGBValue<ComponentType> >
1303 {
1304  typedef typename
1305  NumericTraits<ComponentType>::RealPromote promote_type;
1306  GammaFunctor<ComponentType> red, green, blue;
1307 
1308  public:
1309 
1310  typedef RGBValue<ComponentType> value_type;
1311 
1312  GammaFunctor(promote_type gamma,
1313  value_type const & min, value_type const & max)
1314  : red(gamma, min.red(), max.red()),
1315  green(gamma, min.green(), max.green()),
1316  blue(gamma, min.blue(), max.blue())
1317  {}
1318 
1319  value_type operator()(value_type const & v) const
1320  {
1321  return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1322  }
1323 };
1324 
1325 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1326 
1327 template <>
1328 class GammaFunctor<RGBValue<int> >
1329 {
1330  typedef NumericTraits<int>::RealPromote promote_type;
1331  GammaFunctor<int> red, green, blue;
1332 
1333  public:
1334 
1335  typedef RGBValue<int> value_type;
1336 
1337  GammaFunctor(promote_type gamma,
1338  value_type const & min, value_type const & max)
1339  : red(gamma, min.red(), max.red()),
1340  green(gamma, min.green(), max.green()),
1341  blue(gamma, min.blue(), max.blue())
1342  {}
1343 
1344  value_type operator()(value_type const & v) const
1345  {
1346  return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1347  }
1348 };
1349 
1350 template <>
1351 class GammaFunctor<RGBValue<float> >
1352 {
1353  typedef NumericTraits<float>::RealPromote promote_type;
1354  GammaFunctor<float> red, green, blue;
1355 
1356  public:
1357 
1358  typedef RGBValue<float> value_type;
1359 
1360  GammaFunctor(promote_type gamma,
1361  value_type const & min, value_type const & max)
1362  : red(gamma, min.red(), max.red()),
1363  green(gamma, min.green(), max.green()),
1364  blue(gamma, min.blue(), max.blue())
1365  {}
1366 
1367  value_type operator()(value_type const & v) const
1368  {
1369  return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1370  }
1371 };
1372 
1373 template <class PixelType>
1374 class FunctorTraits<GammaFunctor<PixelType> >
1375 : public FunctorTraitsBase<GammaFunctor<PixelType> >
1376 {
1377  public:
1378  typedef VigraTrueType isUnaryFunctor;
1379 };
1380 
1381 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1382 
1383 template <>
1384 class GammaFunctor<RGBValue<unsigned char> >
1385 {
1386  typedef NumericTraits<unsigned char>::RealPromote promote_type;
1387  GammaFunctor<unsigned char> red, green, blue;
1388 
1389  public:
1390  typedef RGBValue<unsigned char> value_type;
1391 
1392  GammaFunctor(promote_type gamma,
1393  value_type const & min = value_type(0,0,0),
1394  value_type const & max = value_type(255, 255, 255))
1395  : red(gamma, min.red(), max.red()),
1396  green(gamma, min.green(), max.green()),
1397  blue(gamma, min.blue(), max.blue())
1398  {}
1399 
1400  value_type operator()(value_type const & v) const
1401  {
1402  return value_type(red(v.red()), green(v.green()), blue(v.blue()));
1403  }
1404 };
1405 
1406 
1407 /********************************************************/
1408 /* */
1409 /* VectorNormFunctor */
1410 /* */
1411 /********************************************************/
1412 
1413 /** \brief A functor for computing the vector norm
1414 
1415  Calculate the magnitude or norm from a given vector-valued
1416  entity. The vector type will typically be some sort of
1417  ref vigra::TinyVector. If the vector is represented by a pair of
1418  scalar-valued images, use \ref vigra::MagnitudeFunctor instead.
1419 
1420  At least, the vector type is required to have a function
1421  '<em>result</em><TT> = dot(v,v)</TT>'.
1422 
1423  <b> Traits defined:</b>
1424 
1425  <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1426 
1427  <b> Usage:</b>
1428 
1429  <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br>
1430  Namespace: vigra
1431 
1432  \code
1433  typedef vigra::TinyVector<float, 2> Vector;
1434  vigra::BasicImage<Vector> grad(width, height);
1435  vigra::FImage magn(width,height);
1436  ...
1437  vigra::transformImage(srcImageRange(grad), destImage(magn),
1438  VectorNormFunctor<float>()
1439  );
1440  \endcode
1441 
1442  \see vigra::TinyVector, dot(), vigra::MagnitudeFunctor
1443 */
1444 template <class ValueType>
1446 {
1447 public:
1448  /** the functor's argument type
1449  */
1450  typedef ValueType argument_type;
1451 
1452  /** the functor's result type
1453  */
1454  typedef typename NumericTraits<typename ValueType::value_type>::RealPromote result_type;
1455 
1456  /** calculate transform '<TT>sqrt(v1*v1 + v2*v2 + ...)</TT>'.
1457  */
1459  {
1460  return VIGRA_CSTD::sqrt( dot(a,a) );
1461  }
1462 }; //-- class VectorNormFunctor
1463 
1464 template <class ValueType>
1465 class FunctorTraits<VectorNormFunctor<ValueType> >
1466 : public FunctorTraitsBase<VectorNormFunctor<ValueType> >
1467 {
1468  public:
1469  typedef VigraTrueType isUnaryFunctor;
1470 };
1471 
1472 /** \brief A functor for computing the squared vector norm
1473 
1474  Calculate the squared magnitude or norm from a given
1475  vector-valued entity. The vector type will typically be some
1476  sort of TinyVector.
1477 
1478  At least, the vector type is required to have a function
1479  '<em>result</em><TT> = dot(v,v)</TT>'.
1480 
1481  For an example of its usage see VectorNormFunctor
1482 
1483  <b> Traits defined:</b>
1484 
1485  <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1486 
1487  \see TinyVector, dot()
1488 */
1489 template <class ValueType>
1491 {
1492 public:
1493  /** the functor's argument type
1494  */
1495  typedef ValueType argument_type;
1496 
1497  /** the functor's result type
1498  */
1499  typedef typename NumericTraits<typename ValueType::value_type>::RealPromote result_type;
1500 
1501  /** calculate transform '<TT>v1*v1 + v2*v2 + ...</TT>'.
1502  */
1504  {
1505  return dot(a,a);
1506  }
1507 }; //-- class VectorNormSqFunctor
1508 
1509 template <class ValueType>
1510 class FunctorTraits<VectorNormSqFunctor<ValueType> >
1511 : public FunctorTraitsBase<VectorNormSqFunctor<ValueType> >
1512 {
1513  public:
1514  typedef VigraTrueType isUnaryFunctor;
1515 };
1516 
1517 //@}
1518 
1519 } // namespace vigra
1520 
1521 #endif // VIGRA_TRANSFORMIMAGE_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.7.1 (Thu Jun 14 2012)