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