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