[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
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.6.0, Aug 13 2008 ) */ 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 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00012 /* vigra@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 doxygen_overloaded_function(template <...> void transformImage) 00167 00168 template <class SrcImageIterator, class SrcAccessor, 00169 class DestImageIterator, class DestAccessor, class Functor> 00170 void 00171 transformImage(SrcImageIterator src_upperleft, 00172 SrcImageIterator src_lowerright, SrcAccessor sa, 00173 DestImageIterator dest_upperleft, DestAccessor da, 00174 Functor const & f) 00175 { 00176 int w = src_lowerright.x - src_upperleft.x; 00177 00178 for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y) 00179 { 00180 transformLine(src_upperleft.rowIterator(), 00181 src_upperleft.rowIterator() + w, sa, 00182 dest_upperleft.rowIterator(), da, f); 00183 } 00184 } 00185 00186 template <class SrcImageIterator, class SrcAccessor, 00187 class DestImageIterator, class DestAccessor, class Functor> 00188 inline 00189 void 00190 transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00191 pair<DestImageIterator, DestAccessor> dest, 00192 Functor const & f) 00193 { 00194 transformImage(src.first, src.second, src.third, 00195 dest.first, dest.second, f); 00196 } 00197 00198 /********************************************************/ 00199 /* */ 00200 /* transformImageIf */ 00201 /* */ 00202 /********************************************************/ 00203 00204 /** \brief Apply unary point transformation to each pixel within the ROI 00205 (i.e., where the mask is non-zero). 00206 00207 The transformation given by the functor is applied to every source 00208 pixel in the ROI (i.e. when the return vlaue of the mask's accessor 00209 is not zero) 00210 and the result is written into the corresponding destination pixel. 00211 The function uses accessors to access the pixel data. 00212 Note that the unary functors of the STL can be used in addition to 00213 the functors specifically defined in \ref TransformFunctor. 00214 Creation of new functors is easiest by using \ref FunctorExpressions. 00215 00216 <b> Declarations:</b> 00217 00218 pass arguments explicitly: 00219 \code 00220 namespace vigra { 00221 template <class SrcImageIterator, class SrcAccessor, 00222 class MaskImageIterator, class MaskAccessor, 00223 class DestImageIterator, clas DestAccessor, 00224 class Functor> 00225 void 00226 transformImageIf(SrcImageIterator src_upperleft, 00227 SrcImageIterator src_lowerright, SrcAccessor sa, 00228 MaskImageIterator mask_upperleft, MaskAccessor ma, 00229 DestImageIterator dest_upperleft, DestAccessor da, 00230 Functor const & f) 00231 } 00232 \endcode 00233 00234 00235 use argument objects in conjunction with \ref ArgumentObjectFactories : 00236 \code 00237 namespace vigra { 00238 template <class SrcImageIterator, class SrcAccessor, 00239 class MaskImageIterator, class MaskAccessor, 00240 class DestImageIterator, clas DestAccessor, 00241 class Functor> 00242 void 00243 transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00244 pair<MaskImageIterator, MaskAccessor> mask, 00245 pair<DestImageIterator, DestAccessor> dest, 00246 Functor const & f) 00247 } 00248 \endcode 00249 00250 <b> Usage:</b> 00251 00252 <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br> 00253 Namespace: vigra 00254 00255 \code 00256 #include <cmath> // for sqrt() 00257 00258 vigra::transformImageIf(srcImageRange(src), 00259 maskImage(mask), 00260 destImage(dest), 00261 (double(*)(double))&std::sqrt ); 00262 00263 \endcode 00264 00265 <b> Required Interface:</b> 00266 00267 \code 00268 SrcImageIterator src_upperleft, src_lowerright; 00269 DestImageIterator dest_upperleft; 00270 MaskImageIterator mask_upperleft; 00271 SrcImageIterator::row_iterator sx = src_upperleft.rowIterator(); 00272 MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator(); 00273 DestImageIterator::row_iterator dx = dest_upperleft.rowIterator(); 00274 00275 SrcAccessor src_accessor; 00276 DestAccessor dest_accessor; 00277 MaskAccessor mask_accessor; 00278 Functor functor; 00279 00280 if(mask_accessor(mx)) 00281 dest_accessor.set(functor(src_accessor(sx)), dx); 00282 00283 \endcode 00284 00285 */ 00286 doxygen_overloaded_function(template <...> void transformImageIf) 00287 00288 template <class SrcImageIterator, class SrcAccessor, 00289 class MaskImageIterator, class MaskAccessor, 00290 class DestImageIterator, class DestAccessor, 00291 class Functor> 00292 void 00293 transformImageIf(SrcImageIterator src_upperleft, 00294 SrcImageIterator src_lowerright, SrcAccessor sa, 00295 MaskImageIterator mask_upperleft, MaskAccessor ma, 00296 DestImageIterator dest_upperleft, DestAccessor da, 00297 Functor const & f) 00298 { 00299 int w = src_lowerright.x - src_upperleft.x; 00300 00301 for(; src_upperleft.y < src_lowerright.y; 00302 ++src_upperleft.y, ++mask_upperleft.y, ++dest_upperleft.y) 00303 { 00304 transformLineIf(src_upperleft.rowIterator(), 00305 src_upperleft.rowIterator() + w, sa, 00306 mask_upperleft.rowIterator(), ma, 00307 dest_upperleft.rowIterator(), da, f); 00308 } 00309 } 00310 00311 template <class SrcImageIterator, class SrcAccessor, 00312 class MaskImageIterator, class MaskAccessor, 00313 class DestImageIterator, class DestAccessor, 00314 class Functor> 00315 inline 00316 void 00317 transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00318 pair<MaskImageIterator, MaskAccessor> mask, 00319 pair<DestImageIterator, DestAccessor> dest, 00320 Functor const & f) 00321 { 00322 transformImageIf(src.first, src.second, src.third, 00323 mask.first, mask.second, 00324 dest.first, dest.second, f); 00325 } 00326 00327 /********************************************************/ 00328 /* */ 00329 /* gradientBasedTransform */ 00330 /* */ 00331 /********************************************************/ 00332 00333 /** \brief Calculate a function of the image gradient. 00334 00335 The gradient and the function represented by <TT>Functor f</TT> 00336 are calculated in one go: for each location, the symmetric 00337 difference in x- and y-directions (asymmetric difference at the 00338 image borders) are passed to the given functor, and the result is 00339 written the destination image. Functors to be used with this 00340 function include \ref MagnitudeFunctor and \ref 00341 RGBGradientMagnitudeFunctor. 00342 00343 <b> Declarations:</b> 00344 00345 pass arguments explicitly: 00346 \code 00347 namespace vigra { 00348 template <class SrcImageIterator, class SrcAccessor, 00349 class DestImageIterator, class DestAccessor, class Functor> 00350 void 00351 gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa, 00352 DestImageIterator destul, DestAccessor da, Functor const & f) 00353 } 00354 \endcode 00355 00356 00357 use argument objects in conjunction with \ref ArgumentObjectFactories : 00358 \code 00359 namespace vigra { 00360 template <class SrcImageIterator, class SrcAccessor, 00361 class DestImageIterator, class DestAccessor, class Functor> 00362 void 00363 gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00364 pair<DestImageIterator, DestAccessor> dest, Functor const & const & f) 00365 } 00366 \endcode 00367 00368 <b> Usage:</b> 00369 00370 <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>> 00371 00372 00373 \code 00374 vigra::FImage src(w,h), magnitude(w,h); 00375 ... 00376 00377 gradientBasedTransform(srcImageRange(src), destImage(magnitude), 00378 vigra::MagnitudeFunctor<float>()); 00379 \endcode 00380 00381 <b> Required Interface:</b> 00382 00383 \code 00384 SrcImageIterator is, isend; 00385 DestImageIterator id; 00386 00387 SrcAccessor src_accessor; 00388 DestAccessor dest_accessor; 00389 00390 typename NumericTraits<typename SrcAccessor::value_type>::RealPromote 00391 diffx, diffy; 00392 00393 diffx = src_accessor(is, Diff2D(-1,0)) - src_accessor(is, Diff2D(1,0)); 00394 diffy = src_accessor(is, Diff2D(0,-1)) - src_accessor(is, Diff2D(0,1)); 00395 00396 Functor f; 00397 00398 dest_accessor.set(f(diffx, diffy), id); 00399 00400 \endcode 00401 00402 */ 00403 doxygen_overloaded_function(template <...> void gradientBasedTransform) 00404 00405 template <class SrcImageIterator, class SrcAccessor, 00406 class DestImageIterator, class DestAccessor, class Functor> 00407 void 00408 gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa, 00409 DestImageIterator destul, DestAccessor da, Functor const & grad) 00410 { 00411 int w = srclr.x - srcul.x; 00412 int h = srclr.y - srcul.y; 00413 int x,y; 00414 00415 SrcImageIterator sy = srcul; 00416 DestImageIterator dy = destul; 00417 00418 static const Diff2D left(-1,0); 00419 static const Diff2D right(1,0); 00420 static const Diff2D top(0,-1); 00421 static const Diff2D bottom(0,1); 00422 00423 typename NumericTraits<typename SrcAccessor::value_type>::RealPromote 00424 diffx, diffy; 00425 00426 SrcImageIterator sx = sy; 00427 DestImageIterator dx = dy; 00428 00429 diffx = sa(sx) - sa(sx, right); 00430 diffy = sa(sx) - sa(sx, bottom); 00431 da.set(grad(diffx, diffy), dx); 00432 00433 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x) 00434 { 00435 diffx = (sa(sx, left) - sa(sx, right)) / 2.0; 00436 diffy = sa(sx) - sa(sx, bottom); 00437 da.set(grad(diffx, diffy), dx); 00438 } 00439 00440 diffx = sa(sx, left) - sa(sx); 00441 diffy = sa(sx) - sa(sx, bottom); 00442 da.set(grad(diffx, diffy), dx); 00443 00444 ++sy.y; 00445 ++dy.y; 00446 00447 for(y=2; y<h; ++y, ++sy.y, ++dy.y) 00448 { 00449 sx = sy; 00450 dx = dy; 00451 00452 diffx = sa(sx) - sa(sx, right); 00453 diffy = (sa(sx, top) - sa(sx, bottom)) / 2.0; 00454 da.set(grad(diffx, diffy), dx); 00455 00456 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x) 00457 { 00458 diffx = (sa(sx, left) - sa(sx, right)) / 2.0; 00459 diffy = (sa(sx, top) - sa(sx, bottom)) / 2.0; 00460 da.set(grad(diffx, diffy), dx); 00461 } 00462 00463 diffx = sa(sx, left) - sa(sx); 00464 diffy = (sa(sx, top) - sa(sx, bottom)) / 2.0; 00465 da.set(grad(diffx, diffy), dx); 00466 } 00467 00468 sx = sy; 00469 dx = dy; 00470 00471 diffx = sa(sx) - sa(sx, right); 00472 diffy = sa(sx, top) - sa(sx); 00473 da.set(grad(diffx, diffy), dx); 00474 00475 for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x) 00476 { 00477 diffx = (sa(sx, left) - sa(sx, right)) / 2.0; 00478 diffy = sa(sx, top) - sa(sx); 00479 da.set(grad(diffx, diffy), dx); 00480 } 00481 00482 diffx = sa(sx, left) - sa(sx); 00483 diffy = sa(sx, top) - sa(sx); 00484 da.set(grad(diffx, diffy), dx); 00485 } 00486 00487 template <class SrcImageIterator, class SrcAccessor, 00488 class DestImageIterator, class DestAccessor, class Functor> 00489 inline 00490 void 00491 gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00492 pair<DestImageIterator, DestAccessor> dest, Functor const & grad) 00493 { 00494 gradientBasedTransform(src.first, src.second, src.third, 00495 dest.first, dest.second, grad); 00496 } 00497 00498 /** @} */ 00499 /** \addtogroup TransformFunctor Functors to Transform Images 00500 00501 Note that the unary functors of the STL can also be used in 00502 connection with \ref transformImage(). 00503 */ 00504 //@{ 00505 00506 template <class DestValueType, class Multiplier = double> 00507 class LinearIntensityTransform 00508 { 00509 public: 00510 /* the functors argument type (actually, since 00511 <tt>operator()</tt> is a template, much more types are possible) 00512 */ 00513 typedef DestValueType argument_type; 00514 00515 /* the functors result type 00516 */ 00517 typedef DestValueType result_type; 00518 00519 /* \deprecated use argument_type and result_type 00520 */ 00521 typedef DestValueType value_type; 00522 00523 /* type of the offset (used in internal calculations to prevent 00524 overflows and minimize round-off errors). 00525 */ 00526 typedef typename 00527 NumericTraits<DestValueType>::RealPromote argument_promote; 00528 00529 /* type of the scale factor 00530 */ 00531 typedef Multiplier scalar_multiplier_type; 00532 00533 /* init scale and offset 00534 */ 00535 LinearIntensityTransform(scalar_multiplier_type scale, argument_promote offset) 00536 : scale_(scale), offset_(offset) 00537 {} 00538 00539 /* calculate transform 00540 */ 00541 template <class SrcValueType> 00542 result_type operator()(SrcValueType const & s) const 00543 { 00544 return NumericTraits<result_type>::fromRealPromote(scale_ * (s + offset_)); 00545 } 00546 00547 private: 00548 00549 scalar_multiplier_type scale_; 00550 argument_promote offset_; 00551 }; 00552 00553 template <class DestValueType, class Multiplier> 00554 class FunctorTraits<LinearIntensityTransform<DestValueType, Multiplier> > 00555 : public FunctorTraitsBase<LinearIntensityTransform<DestValueType, Multiplier> > 00556 { 00557 public: 00558 typedef VigraTrueType isUnaryFunctor; 00559 }; 00560 00561 template <class DestValueType, class Multiplier = double> 00562 class ScalarIntensityTransform 00563 { 00564 public: 00565 /* the functors argument type (actually, since 00566 <tt>operator()</tt> is a template, much more types are possible) 00567 */ 00568 typedef DestValueType argument_type; 00569 00570 /* the functors result type 00571 */ 00572 typedef DestValueType result_type; 00573 00574 /* \deprecated use argument_type and result_type 00575 */ 00576 typedef DestValueType value_type; 00577 00578 /* type of the scale factor 00579 */ 00580 typedef Multiplier scalar_multiplier_type; 00581 00582 /* init scale 00583 */ 00584 ScalarIntensityTransform(scalar_multiplier_type scale) 00585 : scale_(scale) 00586 {} 00587 00588 /* calculate transform 00589 */ 00590 template <class SrcValueType> 00591 result_type operator()(SrcValueType const & s) const 00592 { 00593 return NumericTraits<result_type>::fromRealPromote(scale_ * s); 00594 } 00595 00596 private: 00597 scalar_multiplier_type scale_; 00598 }; 00599 00600 template <class DestValueType, class Multiplier> 00601 class FunctorTraits<ScalarIntensityTransform<DestValueType, Multiplier> > 00602 : public FunctorTraitsBase<ScalarIntensityTransform<DestValueType, Multiplier> > 00603 { 00604 public: 00605 typedef VigraTrueType isUnaryFunctor; 00606 }; 00607 00608 /********************************************************/ 00609 /* */ 00610 /* linearIntensityTransform */ 00611 /* */ 00612 /********************************************************/ 00613 00614 /** \brief Apply a linear transform to the source pixel values 00615 00616 Factory function for a functor that linearly transforms the 00617 source pixel values. The functor applies the transform 00618 '<TT>destvalue = scale * (srcvalue + offset)</TT>' to every pixel. 00619 This can, for example, be used to transform images into the visible 00620 range 0...255 or to invert an image. 00621 00622 If you leave out the second parameter / offset, you will get an 00623 optimized version of the functor which only scales by the given 00624 factor, however you have to make the template parameter (pixel 00625 type) explicit then. 00626 00627 <b> Traits defined:</b> 00628 00629 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>) 00630 00631 <b> Declaration:</b> 00632 00633 \code 00634 namespace vigra { 00635 template <class Multiplier, class DestValueType> 00636 LinearIntensityTransform<DestValueType, Multiplier> 00637 linearIntensityTransform(Multiplier scale, DestValueType offset); 00638 00639 template <class DestValueType, class Multiplier> 00640 ScalarIntensityTransform<DestValueType, Multiplier> 00641 linearIntensityTransform(Multiplier scale); 00642 } 00643 \endcode 00644 00645 <b> Usage:</b> 00646 00647 <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br> 00648 Namespace: vigra 00649 00650 \code 00651 vigra::IImage src(width, height); 00652 vigra::BImage dest(width, height); 00653 ... 00654 vigra::FindMinMax<IImage::PixelType> minmax; // functor to find range 00655 00656 vigra::inspectImage(srcImageRange(src), minmax); // find original range 00657 00658 // transform to range 0...255 00659 vigra::transformImage(srcImageRange(src), destImage(dest), 00660 linearIntensityTransform( 00661 255.0 / (minmax.max - minmax.min), // scaling 00662 - minmax.min)); // offset 00663 \endcode 00664 00665 The one-parameter version can be used like this: 00666 00667 \code 00668 // scale from 0..255 to 0..1.0 00669 FImage dest(src.size()); 00670 00671 vigra::transformImage(srcImageRange(src), destImage(dest), 00672 linearIntensityTransform<float>(1.0 / 255)); 00673 \endcode 00674 00675 <b> Required Interface:</b> 00676 00677 The source and destination value types must be models of \ref LinearSpace in both cases. 00678 00679 */ 00680 template <class Multiplier, class DestValueType> 00681 LinearIntensityTransform<DestValueType, Multiplier> 00682 linearIntensityTransform(Multiplier scale, DestValueType offset) 00683 { 00684 return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset); 00685 } 00686 00687 template <class DestValueType, class Multiplier> 00688 ScalarIntensityTransform<DestValueType, Multiplier> 00689 linearIntensityTransform(Multiplier scale) 00690 { 00691 return ScalarIntensityTransform<DestValueType, Multiplier>(scale); 00692 } 00693 00694 /********************************************************/ 00695 /* */ 00696 /* linearRangeMapping */ 00697 /* */ 00698 /********************************************************/ 00699 00700 /** \brief Map a source intensity range linearly to a destination range. 00701 00702 Factory function for a functor that linearly transforms the 00703 source pixel values. The functor applies the transform 00704 '<TT>destvalue = scale * (srcvalue + offset)</TT>' to every pixel, 00705 where <tt>scale = (dest_max - dest_min) / (src_max - src_min)</tt> 00706 and <tt>offset = dest_min / scale - src_min</tt>. As a result, 00707 the pixel values <tt>src_max</tt>, <tt>src_min</tt> in the source image 00708 are mapped onto <tt>dest_max</tt>, <tt>dest_min</tt> respectively. 00709 This works for scalar as well as vector pixel types. 00710 00711 <b> Declaration:</b> 00712 00713 \code 00714 namespace vigra { 00715 template <class SrcValueType, class DestValueType> 00716 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote> 00717 linearRangeMapping(SrcValueType src_min, SrcValueType src_max, 00718 DestValueType dest_min, DestValueType dest_max ); 00719 } 00720 \endcode 00721 00722 <b> Usage:</b> 00723 00724 <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br> 00725 Namespace: vigra 00726 00727 \code 00728 vigra::IImage src(width, height); 00729 vigra::BImage dest(width, height); 00730 ... 00731 vigra::FindMinMax<IImage::PixelType> minmax; // functor to find range 00732 00733 vigra::inspectImage(srcImageRange(src), minmax); // find original range 00734 00735 // transform to range 0...255 00736 vigra::transformImage(srcImageRange(src), destImage(dest), 00737 linearRangeTransform( 00738 minmax.min, minmax.max, // src range 00739 (unsigned char)0, (unsigned char)255) // dest range 00740 ); 00741 \endcode 00742 00743 <b> Required Interface:</b> 00744 00745 The source and destination value types must be models of \ref LinearSpace in both cases. 00746 00747 */ 00748 template <class SrcValueType, class DestValueType> 00749 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote> 00750 linearRangeMapping(SrcValueType src_min, SrcValueType src_max, 00751 DestValueType dest_min, DestValueType dest_max ) 00752 { 00753 return linearRangeMapping(src_min, src_max, dest_min, dest_max, 00754 typename NumericTraits<DestValueType>::isScalar()); 00755 } 00756 00757 template <class SrcValueType, class DestValueType> 00758 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote> 00759 linearRangeMapping( 00760 SrcValueType src_min, SrcValueType src_max, 00761 DestValueType dest_min, DestValueType dest_max, 00762 VigraTrueType /* isScalar */ ) 00763 { 00764 typedef typename NumericTraits<DestValueType>::RealPromote Multiplier; 00765 Multiplier diff = src_max - src_min; 00766 Multiplier scale = diff == NumericTraits<Multiplier>::zero() 00767 ? NumericTraits<Multiplier>::one() 00768 : (dest_max - dest_min) / diff; 00769 return LinearIntensityTransform<DestValueType, Multiplier>( 00770 scale, dest_min / scale - src_min ); 00771 } 00772 00773 template <class SrcValueType, class DestValueType> 00774 LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote> 00775 linearRangeMapping( 00776 SrcValueType src_min, SrcValueType src_max, 00777 DestValueType dest_min, DestValueType dest_max, 00778 VigraFalseType /* isScalar */ ) 00779 { 00780 typedef typename NumericTraits<DestValueType>::RealPromote Multiplier; 00781 typedef typename Multiplier::value_type MComponent; 00782 Multiplier scale(dest_max), offset(dest_max); 00783 for(unsigned int i=0; i<src_min.size(); ++i) 00784 { 00785 MComponent diff = src_max[i] - src_min[i]; 00786 scale[i] = diff == NumericTraits<MComponent>::zero() 00787 ? NumericTraits<MComponent>::one() 00788 : (dest_max[i] - dest_min[i]) / diff; 00789 offset[i] = dest_min[i] / scale[i] - src_min[i]; 00790 } 00791 return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset); 00792 } 00793 00794 /********************************************************/ 00795 /* */ 00796 /* Threshold */ 00797 /* */ 00798 /********************************************************/ 00799 00800 /** \brief Threshold an image. 00801 00802 If a source pixel is above or equal the lower and below 00803 or equal the higher threshold (i.e. within the closed interval 00804 [lower, heigher]) the destination pixel is set to 'yesresult', 00805 otherwise to 'noresult'. 00806 00807 <b> Traits defined:</b> 00808 00809 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>) 00810 00811 <b> Usage:</b> 00812 00813 <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br> 00814 Namespace: vigra 00815 00816 \code 00817 vigra::BImage src(width, height), dest(width, height); 00818 ... 00819 vigra::transformImage(src.upperLeft(), src.lowerRight(), src.accessor(), 00820 dest.upperLeft(), dest.accessor(), 00821 vigra::Threshold< 00822 vigra::BImage::PixelType, vigra::BImage::PixelType>(10, 100, 0, 255)); 00823 00824 \endcode 00825 00826 <b> Required Interface:</b> 00827 00828 \code 00829 00830 SrcValueType src; 00831 DestValueType dest, yesresult, noresult; 00832 00833 dest = ((src < lower) || (higher < src)) ? noresult : yesresult; 00834 00835 \endcode 00836 00837 */ 00838 template <class SrcValueType, class DestValueType> 00839 class Threshold 00840 { 00841 public: 00842 00843 /** the functor's argument type 00844 */ 00845 typedef SrcValueType argument_type; 00846 00847 /** the functor's result type 00848 */ 00849 typedef DestValueType result_type; 00850 00851 /** init thresholds and return values 00852 */ 00853 Threshold(argument_type lower, argument_type higher, 00854 result_type noresult, result_type yesresult) 00855 : lower_(lower), higher_(higher), 00856 yesresult_(yesresult), noresult_(noresult) 00857 {} 00858 00859 /** calculate transform 00860 */ 00861 result_type operator()(argument_type s) const 00862 { 00863 return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_; 00864 } 00865 00866 private: 00867 00868 argument_type lower_, higher_; 00869 result_type yesresult_, noresult_; 00870 }; 00871 00872 template <class SrcValueType, class DestValueType> 00873 class FunctorTraits<Threshold<SrcValueType, DestValueType> > 00874 : public FunctorTraitsBase<Threshold<SrcValueType, DestValueType> > 00875 { 00876 public: 00877 typedef VigraTrueType isUnaryFunctor; 00878 }; 00879 00880 /********************************************************/ 00881 /* */ 00882 /* BrightnessContrastFunctor */ 00883 /* */ 00884 /********************************************************/ 00885 00886 /** \brief Adjust brightness and contrast of an image. 00887 00888 This functor applies a gamma correction to each pixel in order to 00889 modify the brightness of the image. To the result of the gamma 00890 correction, another transform is applied that modifies the 00891 contrast. The brightness and contrast parameters must be 00892 positive. Values greater than 1 will increase image brightness or 00893 contrast respectively, values smaller than 1 decrease them. A 00894 value of exactly 1 will have no effect. If contrast is set to 1, 00895 the result is equivalent to that of the GammaFunctor with gamma = 00896 1./brightness. 00897 00898 For \ref RGBValue "RGBValue's", the transforms are applied 00899 component-wise. The pixel values are assumed to lie between the 00900 given minimum and maximum values (in case of RGB, this is again 00901 understood component-wise). In case of <TT>unsigned char</TT>, min 00902 and max default to 0 and 255 respectively. Precisely, the 00903 following transform is applied to each <em> PixelValue</em>: 00904 00905 \f[ 00906 \begin{array}{rcl} 00907 V_1 & = & \frac{PixelValue - min}{max - min} \\ 00908 V_2 & = & V_1^\frac{1}{brightness} \\ 00909 V_3 & = & 2 V_2 - 1 \\ 00910 V_4 & = & \left\lbrace 00911 \begin{array}{l} 00912 V_3^\frac{1}{contrast} \mbox{\rm \quad if } V_3 \ge 0 \\ 00913 - (-V_3)^\frac{1}{contrast} \mbox{\rm \quad otherwise} 00914 \end{array} \right. \\ 00915 Result & = & \frac{V_4 + 1}{2} (max - min) + min 00916 \end{array} 00917 \f] 00918 00919 If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a look-up-table is used 00920 for faster computation. 00921 00922 <b> Traits defined:</b> 00923 00924 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>) 00925 00926 <b> Usage:</b> 00927 00928 <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br> 00929 Namespace: vigra 00930 00931 \code 00932 vigra::BImage bimage(width, height); 00933 double brightness, contrast; 00934 ... 00935 vigra::transformImage(srcImageRange(bimage), destImage(bimage), 00936 vigra::BrightnessContrastFunctor<unsigned char>(brightness, contrast)); 00937 00938 00939 00940 vigra::FImage fimage(width, height); 00941 ... 00942 00943 vigra::FindMinmax<float> minmax; 00944 vigra::inspectImage(srcImageRange(fimage), minmax); 00945 00946 vigra::transformImage(srcImageRange(fimage), destImage(fimage), 00947 vigra::BrightnessContrastFunctor<float>(brightness, contrast, minmax.min, minmax.max)); 00948 00949 00950 \endcode 00951 00952 <b> Required Interface:</b> 00953 00954 Scalar types: must be a linear algebra (+, - *, NumericTraits), 00955 strict weakly ordered (<), and <TT>pow()</TT> must be defined. 00956 00957 RGB values: the component type must meet the above requirements. 00958 */ 00959 template <class PixelType> 00960 class BrightnessContrastFunctor 00961 { 00962 typedef typename 00963 NumericTraits<PixelType>::RealPromote promote_type; 00964 00965 public: 00966 00967 /** the functor's argument type 00968 */ 00969 typedef PixelType argument_type; 00970 00971 /** the functor's result type 00972 */ 00973 typedef PixelType result_type; 00974 00975 /** \deprecated use argument_type and result_type 00976 */ 00977 typedef PixelType value_type; 00978 00979 /** Init functor for argument range <TT>[min, max]</TT>. 00980 <TT>brightness</TT> and <TT>contrast</TT> values > 1 will 00981 increase brightness and contrast, < 1 will decrease them, and == 1 means 00982 no change. 00983 */ 00984 BrightnessContrastFunctor(promote_type brightness, promote_type contrast, 00985 argument_type const & min, argument_type const & max) 00986 : b_(1.0/brightness), 00987 c_(1.0/contrast), 00988 min_(min), 00989 diff_(max - min), 00990 zero_(NumericTraits<promote_type>::zero()), 00991 one_(NumericTraits<promote_type>::one()) 00992 {} 00993 00994 /** Calculate modified gray or color value 00995 */ 00996 result_type operator()(argument_type const & v) const 00997 { 00998 promote_type v1 = (v - min_) / diff_; 00999 promote_type brighter = VIGRA_CSTD::pow(v1, b_); 01000 promote_type v2 = 2.0 * brighter - one_; 01001 promote_type contrasted = (v2 < zero_) ? 01002 -VIGRA_CSTD::pow(-v2, c_) : 01003 VIGRA_CSTD::pow(v2, c_); 01004 return result_type(0.5 * diff_ * (contrasted + one_) + min_); 01005 } 01006 01007 private: 01008 promote_type b_, c_; 01009 argument_type min_; 01010 promote_type diff_, zero_, one_; 01011 }; 01012 01013 template <> 01014 class BrightnessContrastFunctor<unsigned char> 01015 { 01016 typedef NumericTraits<unsigned char>::RealPromote promote_type; 01017 unsigned char lut[256]; 01018 01019 public: 01020 01021 typedef unsigned char value_type; 01022 01023 BrightnessContrastFunctor(promote_type brightness, promote_type contrast, 01024 value_type const & min = 0, value_type const & max = 255) 01025 { 01026 BrightnessContrastFunctor<promote_type> f(brightness, contrast, min, max); 01027 01028 for(int i = min; i <= max; ++i) 01029 { 01030 lut[i] = static_cast<unsigned char>(f(i)+0.5); 01031 } 01032 } 01033 01034 value_type operator()(value_type const & v) const 01035 { 01036 01037 return lut[v]; 01038 } 01039 }; 01040 01041 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 01042 01043 template <class ComponentType> 01044 class BrightnessContrastFunctor<RGBValue<ComponentType> > 01045 { 01046 typedef typename 01047 NumericTraits<ComponentType>::RealPromote promote_type; 01048 BrightnessContrastFunctor<ComponentType> red, green, blue; 01049 01050 public: 01051 01052 typedef RGBValue<ComponentType> value_type; 01053 01054 BrightnessContrastFunctor(promote_type brightness, promote_type contrast, 01055 value_type const & min, value_type const & max) 01056 : red(brightness, contrast, min.red(), max.red()), 01057 green(brightness, contrast, min.green(), max.green()), 01058 blue(brightness, contrast, min.blue(), max.blue()) 01059 {} 01060 01061 value_type operator()(value_type const & v) const 01062 { 01063 01064 return value_type(red(v.red()), green(v.green()), blue(v.blue())); 01065 } 01066 }; 01067 01068 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 01069 01070 template <> 01071 class BrightnessContrastFunctor<RGBValue<int> > 01072 { 01073 typedef NumericTraits<int>::RealPromote promote_type; 01074 BrightnessContrastFunctor<int> red, green, blue; 01075 01076 public: 01077 01078 typedef RGBValue<int> value_type; 01079 01080 BrightnessContrastFunctor(promote_type brightness, promote_type contrast, 01081 value_type const & min, value_type const & max) 01082 : red(brightness, contrast, min.red(), max.red()), 01083 green(brightness, contrast, min.green(), max.green()), 01084 blue(brightness, contrast, min.blue(), max.blue()) 01085 {} 01086 01087 value_type operator()(value_type const & v) const 01088 { 01089 01090 return value_type(red(v.red()), green(v.green()), blue(v.blue())); 01091 } 01092 }; 01093 01094 template <> 01095 class BrightnessContrastFunctor<RGBValue<float> > 01096 { 01097 typedef NumericTraits<float>::RealPromote promote_type; 01098 BrightnessContrastFunctor<float> red, green, blue; 01099 01100 public: 01101 01102 typedef RGBValue<float> value_type; 01103 01104 BrightnessContrastFunctor(promote_type brightness, promote_type contrast, 01105 value_type const & min, value_type const & max) 01106 : red(brightness, contrast, min.red(), max.red()), 01107 green(brightness, contrast, min.green(), max.green()), 01108 blue(brightness, contrast, min.blue(), max.blue()) 01109 {} 01110 01111 value_type operator()(value_type const & v) const 01112 { 01113 01114 return value_type(red(v.red()), green(v.green()), blue(v.blue())); 01115 } 01116 }; 01117 01118 template <class PixelType> 01119 class FunctorTraits<BrightnessContrastFunctor<PixelType> > 01120 : public FunctorTraitsBase<BrightnessContrastFunctor<PixelType> > 01121 { 01122 public: 01123 typedef VigraTrueType isUnaryFunctor; 01124 }; 01125 01126 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 01127 01128 template <> 01129 class BrightnessContrastFunctor<RGBValue<unsigned char> > 01130 { 01131 typedef NumericTraits<unsigned char>::RealPromote promote_type; 01132 BrightnessContrastFunctor<unsigned char> red, green, blue; 01133 01134 public: 01135 01136 typedef RGBValue<unsigned char> value_type; 01137 01138 BrightnessContrastFunctor(promote_type brightness, promote_type contrast, 01139 value_type const & min = value_type(0,0,0), 01140 value_type const & max = value_type(255, 255, 255)) 01141 : red(brightness, contrast, min.red(), max.red()), 01142 green(brightness, contrast, min.green(), max.green()), 01143 blue(brightness, contrast, min.blue(), max.blue()) 01144 {} 01145 01146 value_type operator()(value_type const & v) const 01147 { 01148 01149 return value_type(red(v.red()), green(v.green()), blue(v.blue())); 01150 } 01151 }; 01152 01153 01154 01155 /********************************************************/ 01156 /* */ 01157 /* GammaFunctor */ 01158 /* */ 01159 /********************************************************/ 01160 01161 /** \brief Perform gamma correction of an image. 01162 01163 This functor applies a gamma correction to each pixel in order to 01164 modify the brightness of the image. Gamma values smaller than 1 01165 will increase image brightness, whereas values greater than 1 01166 decrease it. A value of gamma = 1 will have no effect. (See also 01167 BrightnessContrastFunctor, which additionally changes the 01168 contrast.) 01169 01170 For \ref RGBValue "RGBValue's", the transforms are applied 01171 component-wise. For ease of use, the pixel values are assumed to 01172 lie between the given minimum and maximum values (in case of RGB, 01173 this is again understood component-wise). In case of <TT>unsigned 01174 char</TT>, min and max default to 0 and 255 respectively. 01175 Precisely, the following transform is applied to each <em> 01176 PixelValue</em>: 01177 01178 \f[ 01179 \begin{array}{rcl} 01180 V_1 & = & \frac{PixelValue - min}{max - min} \\ 01181 V_2 & = & V_1^{gamma} \\ 01182 Result & = & V_2 (max - min) + min 01183 \end{array} 01184 \f] 01185 01186 If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a 01187 look-up-table is used for faster computation. 01188 01189 <b> Traits defined:</b> 01190 01191 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>) 01192 01193 <b> Usage:</b> 01194 01195 <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br> 01196 Namespace: vigra 01197 01198 \code 01199 vigra::BImage bimage(width, height); 01200 double gamma; 01201 ... 01202 vigra::transformImage(srcImageRange(bimage), destImage(bimage), 01203 vigra::GammaFunctor<unsigned char>(gamma)); 01204 01205 01206 01207 vigra::FImage fimage(width, height); 01208 ... 01209 01210 vigra::FindMinmax<float> minmax; 01211 vigra::inspectImage(srcImageRange(fimage), minmax); 01212 01213 vigra::transformImage(srcImageRange(fimage), destImage(fimage), 01214 vigra::GammaFunctor<float>(gamma, minmax.min, minmax.max)); 01215 01216 \endcode 01217 01218 <b> Required Interface:</b> 01219 01220 Scalar types: must be a linear algebra (+, - *, NumericTraits), 01221 strict weakly ordered (<), and <TT>pow()</TT> must be defined. 01222 01223 RGB values: the component type must meet the above requirements. 01224 */ 01225 template <class PixelType> 01226 class GammaFunctor 01227 { 01228 typedef typename 01229 NumericTraits<PixelType>::RealPromote promote_type; 01230 01231 public: 01232 01233 /** the functor's argument type 01234 */ 01235 typedef PixelType argument_type; 01236 01237 /** the functor's result type 01238 */ 01239 typedef PixelType result_type; 01240 01241 /** \deprecated use argument_type and result_type 01242 */ 01243 typedef PixelType value_type; 01244 01245 /** Init functor for argument range <TT>[min, max]</TT>. 01246 <TT>gamma</TT> values < 1 will increase brightness, > 1 01247 will decrease it (gamma == 1 means no change). 01248 */ 01249 GammaFunctor(promote_type gamma, 01250 argument_type const & min, argument_type const & max) 01251 : gamma_(gamma), 01252 min_(min), 01253 diff_(max - min), 01254 zero_(NumericTraits<promote_type>::zero()), 01255 one_(NumericTraits<promote_type>::one()) 01256 {} 01257 01258 /** Calculate modified gray or color value 01259 */ 01260 result_type operator()(argument_type const & v) const 01261 { 01262 promote_type v1 = (v - min_) / diff_; 01263 promote_type brighter = VIGRA_CSTD::pow(v1, gamma_); 01264 return result_type(diff_ * brighter + min_); 01265 } 01266 01267 private: 01268 promote_type gamma_; 01269 argument_type min_; 01270 promote_type diff_, zero_, one_; 01271 }; 01272 01273 template <> 01274 class GammaFunctor<unsigned char> 01275 { 01276 typedef NumericTraits<unsigned char>::RealPromote promote_type; 01277 unsigned char lut[256]; 01278 01279 public: 01280 01281 typedef unsigned char value_type; 01282 01283 GammaFunctor(promote_type gamma, 01284 value_type const & min = 0, value_type const & max = 255) 01285 { 01286 GammaFunctor<promote_type> f(gamma, min, max); 01287 01288 for(int i = min; i <= max; ++i) 01289 { 01290 lut[i] = static_cast<unsigned char>(f(i)+0.5); 01291 } 01292 } 01293 01294 value_type operator()(value_type const & v) const 01295 { 01296 01297 return lut[v]; 01298 } 01299 }; 01300 01301 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 01302 01303 template <class ComponentType> 01304 class GammaFunctor<RGBValue<ComponentType> > 01305 { 01306 typedef typename 01307 NumericTraits<ComponentType>::RealPromote promote_type; 01308 GammaFunctor<ComponentType> red, green, blue; 01309 01310 public: 01311 01312 typedef RGBValue<ComponentType> value_type; 01313 01314 GammaFunctor(promote_type gamma, 01315 value_type const & min, value_type const & max) 01316 : red(gamma, min.red(), max.red()), 01317 green(gamma, min.green(), max.green()), 01318 blue(gamma, min.blue(), max.blue()) 01319 {} 01320 01321 value_type operator()(value_type const & v) const 01322 { 01323 return value_type(red(v.red()), green(v.green()), blue(v.blue())); 01324 } 01325 }; 01326 01327 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 01328 01329 template <> 01330 class GammaFunctor<RGBValue<int> > 01331 { 01332 typedef NumericTraits<int>::RealPromote promote_type; 01333 GammaFunctor<int> red, green, blue; 01334 01335 public: 01336 01337 typedef RGBValue<int> value_type; 01338 01339 GammaFunctor(promote_type gamma, 01340 value_type const & min, value_type const & max) 01341 : red(gamma, min.red(), max.red()), 01342 green(gamma, min.green(), max.green()), 01343 blue(gamma, min.blue(), max.blue()) 01344 {} 01345 01346 value_type operator()(value_type const & v) const 01347 { 01348 return value_type(red(v.red()), green(v.green()), blue(v.blue())); 01349 } 01350 }; 01351 01352 template <> 01353 class GammaFunctor<RGBValue<float> > 01354 { 01355 typedef NumericTraits<float>::RealPromote promote_type; 01356 GammaFunctor<float> red, green, blue; 01357 01358 public: 01359 01360 typedef RGBValue<float> value_type; 01361 01362 GammaFunctor(promote_type gamma, 01363 value_type const & min, value_type const & max) 01364 : red(gamma, min.red(), max.red()), 01365 green(gamma, min.green(), max.green()), 01366 blue(gamma, min.blue(), max.blue()) 01367 {} 01368 01369 value_type operator()(value_type const & v) const 01370 { 01371 return value_type(red(v.red()), green(v.green()), blue(v.blue())); 01372 } 01373 }; 01374 01375 template <class PixelType> 01376 class FunctorTraits<GammaFunctor<PixelType> > 01377 : public FunctorTraitsBase<GammaFunctor<PixelType> > 01378 { 01379 public: 01380 typedef VigraTrueType isUnaryFunctor; 01381 }; 01382 01383 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 01384 01385 template <> 01386 class GammaFunctor<RGBValue<unsigned char> > 01387 { 01388 typedef NumericTraits<unsigned char>::RealPromote promote_type; 01389 GammaFunctor<unsigned char> red, green, blue; 01390 01391 public: 01392 typedef RGBValue<unsigned char> value_type; 01393 01394 GammaFunctor(promote_type gamma, 01395 value_type const & min = value_type(0,0,0), 01396 value_type const & max = value_type(255, 255, 255)) 01397 : red(gamma, min.red(), max.red()), 01398 green(gamma, min.green(), max.green()), 01399 blue(gamma, min.blue(), max.blue()) 01400 {} 01401 01402 value_type operator()(value_type const & v) const 01403 { 01404 return value_type(red(v.red()), green(v.green()), blue(v.blue())); 01405 } 01406 }; 01407 01408 01409 /********************************************************/ 01410 /* */ 01411 /* VectorNormFunctor */ 01412 /* */ 01413 /********************************************************/ 01414 01415 /** \brief A functor for computing the vector norm 01416 01417 Calculate the magnitude or norm from a given vector-valued 01418 entity. The vector type will typically be some sort of 01419 ref vigra::TinyVector. If the vector is represented by a pair of 01420 scalar-valued images, use \ref vigra::MagnitudeFunctor instead. 01421 01422 At least, the vector type is required to have a function 01423 '<em>result</em><TT> = dot(v,v)</TT>'. 01424 01425 <b> Traits defined:</b> 01426 01427 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>) 01428 01429 <b> Usage:</b> 01430 01431 <b>\#include</b> <<a href="transformimage_8hxx-source.html">vigra/transformimage.hxx</a>><br> 01432 Namespace: vigra 01433 01434 \code 01435 typedef vigra::TinyVector<float, 2> Vector; 01436 vigra::BasicImage<Vector> grad(width, height); 01437 vigra::FImage magn(width,height); 01438 ... 01439 vigra::transformImage(srcImageRange(grad), destImage(magn), 01440 VectorNormFunctor<float>() 01441 ); 01442 \endcode 01443 01444 \see vigra::TinyVector, dot(), vigra::MagnitudeFunctor 01445 */ 01446 template <class ValueType> 01447 class VectorNormFunctor 01448 { 01449 public: 01450 /** the functor's argument type 01451 */ 01452 typedef ValueType argument_type; 01453 01454 /** the functor's result type 01455 */ 01456 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote result_type; 01457 01458 /** calculate transform '<TT>sqrt(v1*v1 + v2*v2 + ...)</TT>'. 01459 */ 01460 result_type operator()( const argument_type &a ) const 01461 { 01462 return VIGRA_CSTD::sqrt( dot(a,a) ); 01463 } 01464 }; //-- class VectorNormFunctor 01465 01466 template <class ValueType> 01467 class FunctorTraits<VectorNormFunctor<ValueType> > 01468 : public FunctorTraitsBase<VectorNormFunctor<ValueType> > 01469 { 01470 public: 01471 typedef VigraTrueType isUnaryFunctor; 01472 }; 01473 01474 /** \brief A functor for computing the squared vector norm 01475 01476 Calculate the squared magnitude or norm from a given 01477 vector-valued entity. The vector type will typically be some 01478 sort of TinyVector. 01479 01480 At least, the vector type is required to have a function 01481 '<em>result</em><TT> = dot(v,v)</TT>'. 01482 01483 For an example of its usage see VectorNormFunctor 01484 01485 <b> Traits defined:</b> 01486 01487 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>) 01488 01489 \see TinyVector, dot() 01490 */ 01491 template <class ValueType> 01492 class VectorNormSqFunctor 01493 { 01494 public: 01495 /** the functor's argument type 01496 */ 01497 typedef ValueType argument_type; 01498 01499 /** the functor's result type 01500 */ 01501 typedef typename NumericTraits<typename ValueType::value_type>::RealPromote result_type; 01502 01503 /** calculate transform '<TT>v1*v1 + v2*v2 + ...</TT>'. 01504 */ 01505 result_type operator()( const argument_type &a ) const 01506 { 01507 return dot(a,a); 01508 } 01509 }; //-- class VectorNormSqFunctor 01510 01511 template <class ValueType> 01512 class FunctorTraits<VectorNormSqFunctor<ValueType> > 01513 : public FunctorTraitsBase<VectorNormSqFunctor<ValueType> > 01514 { 01515 public: 01516 typedef VigraTrueType isUnaryFunctor; 01517 }; 01518 01519 //@} 01520 01521 } // namespace vigra 01522 01523 #endif // VIGRA_TRANSFORMIMAGE_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|