[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/colorconversions.hxx | ![]() |
---|
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2002 by Ullrich Koethe */ 00004 /* Cognitive Systems Group, University of Hamburg, Germany */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* ( Version 1.2.0, Aug 07 2003 ) */ 00008 /* You may use, modify, and distribute this software according */ 00009 /* to the terms stated in the LICENSE file included in */ 00010 /* the VIGRA distribution. */ 00011 /* */ 00012 /* The VIGRA Website is */ 00013 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00014 /* Please direct questions, bug reports, and contributions to */ 00015 /* koethe@informatik.uni-hamburg.de */ 00016 /* */ 00017 /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ 00018 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ 00019 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ 00020 /* */ 00021 /************************************************************************/ 00022 00023 00024 #ifndef VIGRA_COLORCONVERSIONS_HXX 00025 #define VIGRA_COLORCONVERSIONS_HXX 00026 00027 #include <cmath> 00028 #include "vigra/mathutil.hxx" 00029 #include "vigra/rgbvalue.hxx" 00030 00031 /** \page ColorConversions Color Space Conversions 00032 00033 Convert between RGB, R'G'B', XYZ, L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV color spaces. 00034 00035 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00036 Namespace: vigra 00037 00038 <UL> 00039 <LI> <b>RGB/R'G'B'</b><br> 00040 <em>linear and non-linear (gamma corrected) additive color</em> 00041 <p> 00042 <DL> 00043 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00044 vigra::RGB2RGBPrimeFunctor 00045 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00046 vigra::RGBPrime2RGBFunctor 00047 </DL><p> 00048 <LI> <b>XYZ</b><br> 00049 <em>device independent color representation 00050 (according to Publication CIE No 15.2 "Colorimetry" 00051 and ITU-R Recommendation BT.709)</em> 00052 <p> 00053 <DL> 00054 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00055 vigra::RGB2XYZFunctor 00056 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00057 vigra::RGBPrime2XYZFunctor 00058 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00059 vigra::XYZ2RGBFunctor 00060 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00061 vigra::XYZ2RGBPrimeFunctor 00062 </DL><p> 00063 <LI> <b>L*a*b* </b><br> 00064 <em>perceptually uniform color representation 00065 (according to Publication CIE No 15.2 "Colorimetry" and 00066 ITU-R Recommendation BT.709)</em> 00067 <p> 00068 <DL> 00069 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00070 vigra::RGB2LabFunctor 00071 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00072 vigra::RGBPrime2LabFunctor 00073 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00074 vigra::XYZ2LabFunctor 00075 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00076 vigra::Lab2RGBFunctor 00077 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00078 vigra::Lab2RGBPrimeFunctor 00079 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00080 vigra::Lab2XYZFunctor 00081 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00082 \ref polar2Lab "vigra::polar2Lab"() 00083 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00084 \ref lab2Polar "vigra::lab2Polar"() 00085 </DL><p> 00086 <LI> <b>L*u*v* </b><br> 00087 <em>perceptually uniform color representation 00088 (according to Publication CIE No 15.2 "Colorimetry" and 00089 ITU-R Recommendation BT.709)</em> 00090 <p> 00091 <DL> 00092 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00093 vigra::RGB2LuvFunctor 00094 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00095 vigra::RGBPrime2LuvFunctor 00096 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00097 vigra::XYZ2LuvFunctor 00098 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00099 vigra::Luv2RGBFunctor 00100 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00101 vigra::Luv2RGBPrimeFunctor 00102 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00103 vigra::Luv2XYZFunctor 00104 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00105 \ref polar2Luv "vigra::polar2Luv"() 00106 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00107 \ref luv2Polar "vigra::luv2Polar"() 00108 </DL><p> 00109 <LI> <b>Y'PbPr and Y'CbCr </b><br> 00110 <em>color difference coding 00111 (according to ITU-R Recommendation BT. 601)</em> 00112 <p> 00113 <DL> 00114 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00115 vigra::RGBPrime2YPrimePbPrFunctor 00116 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00117 vigra::YPrimePbPr2RGBPrimeFunctor 00118 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00119 \ref polar2YPrimePbPr "vigra::polar2YPrimePbPr"() 00120 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00121 \ref yPrimePbPr2Polar "vigra::yPrimePbPr2Polar"() 00122 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00123 vigra::RGBPrime2YPrimeCbCrFunctor 00124 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00125 vigra::YPrimeCbCr2RGBPrimeFunctor 00126 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00127 \ref polar2YPrimeCbCr "vigra::polar2YPrimeCbCr"() 00128 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00129 \ref yPrimeCbCr2Polar "vigra::yPrimeCbCr2Polar"() 00130 </DL><p> 00131 <LI> <b>Y'UV and Y'IQ </b><br> 00132 <em>analog video coding according to NTSC and PAL standards</em> 00133 <p> 00134 <DL> 00135 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00136 vigra::RGBPrime2YPrimeUVFunctor 00137 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00138 vigra::YPrimeUV2RGBPrimeFunctor 00139 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00140 \ref polar2YPrimeUV "vigra::polar2YPrimeUV"() 00141 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00142 \ref yPrimeUV2Polar "vigra::yPrimeUV2Polar"() 00143 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00144 vigra::RGBPrime2YPrimeIQFunctor 00145 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00146 vigra::YPrimeIQ2RGBPrimeFunctor 00147 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00148 \ref polar2YPrimeIQ "vigra::polar2YPrimeIQ"() 00149 <DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 00150 \ref yPrimeIQ2Polar "vigra::yPrimeIQ2Polar"() 00151 </DL><p> 00152 </UL> 00153 00154 \anchor _details 00155 This module provides conversion from RGB/R'G'B' into more perceptually uniform 00156 color spaces. In image analysis, colors are usually converted into another color space 00157 in order to get good estimates of perceived color differences by just calculating 00158 Euclidean distances between the transformed colors. The L*a*b* and L*u*v* were 00159 designed with exactly this application in mind and thus give the best results. But these 00160 conversions are also the most computationally demanding. The Y'PbPr color differenc 00161 space (designed for the coding of digital video) is computationally much cheaper, and 00162 almost as good. Y'CbCr represents esentially the same transformation, but the colors 00163 are stored so that they can be stored with 8 bits per channel with minimal loss of 00164 information. The other transformations are of lesser interest here: XYZ is a device independent 00165 (but not perceptually uniform) color representation, and Y'IQ and Y'UV are the color 00166 spaces used by the PAL and NTSC analog video standards. Detailed information about 00167 these color spaces and their transformations can be found in 00168 <a href="http://www.inforamp.net/~poynton/ColorFAQ.html">Charles Poynton's Color FAQ</a> 00169 00170 When you want to perform a color conversion, you must first know in which 00171 color space the data are given. Although this sounds trivial, it is 00172 quite often done wrong in practice, because the distinction 00173 between RGB and R'G'B' is frequently overlooked: nowadays, most images are stored in 00174 R'G'B' space, and treating them as RGB leads to wrong results. RGB and R'G'B' are 00175 related by a so called <em>gamma correction</em>: 00176 00177 \f[ 00178 R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad 00179 G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad 00180 B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45} 00181 \f] 00182 00183 (where usually \f$ R_{max} = G_{max} = B_{max} = 255 \f$). In practice, you can 00184 distinguish the two kinds of red, green, and blue by displaying the images: if they look 00185 too dark, they are probably RGB, if they are OK, they are likely R'G'B'. The distinction 00186 is important because some conversions start at RGB (XYZ, L*a*b*, L*u*v*), while others 00187 start at R'G'B' (Y'PbPr, Y'CbCr, Y'IQ, and Y'UV). The names of VIGRA's color conversion 00188 functors always make clear to which color space thay must be applied. 00189 00190 In addition VIGRA provides a <em>polar coordinate interface</em> 00191 to several color spaces (L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV). This 00192 interface makes use of the fact that these color spaces are conceptually similar: 00193 they represent colors by a "brightness" coordinate (L* or Y') and a pair of 00194 "chromaticity" coordinates that span a plane of colors with constant brightness. 00195 The polar representation transforms chroma coordinates into a color "angle" 00196 (similar to hue in the HSV system) and a "saturation". The polar coordinates are 00197 normalized so that a color angle of 0 degrees is always associated with red 00198 (green is at about 120 degrees, blue at about 240 degrees - exact values differ 00199 between color spaces). A saturation of 1 is the highest saturation that any RGB color 00200 has after transformation into the respective color space, and saturation 0 corresponds to 00201 gray. Polar coordinates provide a more intuitive interface to color specification by 00202 users and make different color spaces somewhat comparable. 00203 */ 00204 namespace vigra { 00205 00206 namespace detail 00207 { 00208 00209 double gammaCorrection(double value, double gamma) 00210 { 00211 return (value < 0.0) ? 00212 -VIGRA_CSTD::pow(-value, gamma) : 00213 VIGRA_CSTD::pow(value, gamma); 00214 } 00215 00216 double gammaCorrection(double value, double gamma, double norm) 00217 { 00218 return (value < 0.0) ? 00219 -norm*VIGRA_CSTD::pow(-value/norm, gamma) : 00220 norm*VIGRA_CSTD::pow(value/norm, gamma); 00221 } 00222 00223 } // namespace detail 00224 00225 /** \brief Convert linear (raw) RGB into non-linear (gamma corrected) R'G'B'. 00226 00227 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00228 Namespace: vigra 00229 00230 The functor realizes the transformation 00231 00232 \f[ 00233 R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad 00234 G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad 00235 B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45} 00236 \f] 00237 00238 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden 00239 in the constructor. If both source and target colors components are stored 00240 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation. 00241 */ 00242 template <class From, class To> 00243 class RGB2RGBPrimeFunctor 00244 { 00245 public: 00246 00247 /** the functor's argument type 00248 */ 00249 typedef TinyVector<From, 3> argument_type; 00250 00251 /** the functor's result type 00252 */ 00253 typedef RGBValue<To> result_type; 00254 00255 /** \deprecated use argument_type and result_type 00256 */ 00257 typedef RGBValue<To> value_type; 00258 00259 /** the result component's promote type 00260 */ 00261 typedef typename NumericTraits<To>::RealPromote component_type; 00262 00263 /** Default constructor. 00264 The maximum value for each RGB componentdefaults to 255 00265 */ 00266 RGB2RGBPrimeFunctor() 00267 : max_(255.0) 00268 {} 00269 00270 /** constructor 00271 \arg max - the maximum value for each RGB component 00272 */ 00273 RGB2RGBPrimeFunctor(component_type max) 00274 : max_(max) 00275 {} 00276 00277 /** apply the transformation 00278 */ 00279 result_type operator()(argument_type const & rgb) const 00280 { 00281 return RGBValue<To>( 00282 NumericTraits<To>::fromRealPromote(detail::gammaCorrection(rgb[0], 0.45, max_)), 00283 NumericTraits<To>::fromRealPromote(detail::gammaCorrection(rgb[1], 0.45, max_)), 00284 NumericTraits<To>::fromRealPromote(detail::gammaCorrection(rgb[2], 0.45, max_))); 00285 } 00286 00287 private: 00288 component_type max_; 00289 }; 00290 00291 template <> 00292 class RGB2RGBPrimeFunctor<unsigned char, unsigned char> 00293 { 00294 unsigned char lut_[256]; 00295 00296 public: 00297 00298 typedef RGBValue<unsigned char> value_type; 00299 00300 RGB2RGBPrimeFunctor() 00301 { 00302 for(int i=0; i<256; ++i) 00303 { 00304 lut_[i] = NumericTraits<unsigned char>::fromRealPromote(detail::gammaCorrection(i, 0.45, 255.0)); 00305 } 00306 } 00307 00308 RGB2RGBPrimeFunctor(double max) 00309 { 00310 for(int i=0; i<256; ++i) 00311 { 00312 lut_[i] = NumericTraits<unsigned char>::fromRealPromote(detail::gammaCorrection(i, 0.45, max)); 00313 } 00314 } 00315 00316 RGBValue<unsigned char> operator()(TinyVector<unsigned char, 3> const & rgb) const 00317 { 00318 return RGBValue<unsigned char>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]); 00319 } 00320 }; 00321 00322 /** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw) RGB. 00323 00324 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00325 Namespace: vigra 00326 00327 The functor realizes the transformation 00328 00329 \f[ 00330 R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad 00331 G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad 00332 B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45} 00333 \f] 00334 00335 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden 00336 in the constructor. If both source and target colors components are stored 00337 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation. 00338 */ 00339 template <class From, class To> 00340 class RGBPrime2RGBFunctor 00341 { 00342 public: 00343 00344 /** the functor's argument type 00345 */ 00346 typedef TinyVector<From, 3> argument_type; 00347 00348 /** the functor's result type 00349 */ 00350 typedef RGBValue<To> result_type; 00351 00352 /** \deprecated use argument_type and result_type 00353 */ 00354 typedef RGBValue<To> value_type; 00355 00356 /** the result component's promote type 00357 */ 00358 typedef typename NumericTraits<To>::RealPromote component_type; 00359 00360 /** Default constructor. 00361 The maximum value for each RGB component defaults to 255. 00362 */ 00363 RGBPrime2RGBFunctor() 00364 : max_(255.0), gamma_(1.0/0.45) 00365 {} 00366 00367 /** constructor 00368 \arg max - the maximum value for each RGB component 00369 */ 00370 RGBPrime2RGBFunctor(component_type max) 00371 : max_(max), gamma_(1.0/0.45) 00372 {} 00373 00374 /** apply the transformation 00375 */ 00376 result_type operator()(argument_type const & rgb) const 00377 { 00378 return RGBValue<To>( 00379 NumericTraits<To>::fromRealPromote(detail::gammaCorrection(rgb[0], gamma_, max_)), 00380 NumericTraits<To>::fromRealPromote(detail::gammaCorrection(rgb[1], gamma_, max_)), 00381 NumericTraits<To>::fromRealPromote(detail::gammaCorrection(rgb[2], gamma_, max_))); 00382 } 00383 00384 private: 00385 component_type max_; 00386 double gamma_; 00387 }; 00388 00389 template <> 00390 class RGBPrime2RGBFunctor<unsigned char, unsigned char> 00391 { 00392 unsigned char lut_[256]; 00393 00394 public: 00395 00396 typedef RGBValue<unsigned char> value_type; 00397 00398 RGBPrime2RGBFunctor() 00399 { 00400 for(int i=0; i<256; ++i) 00401 { 00402 lut_[i] = NumericTraits<unsigned char>::fromRealPromote(detail::gammaCorrection(i, 1.0/0.45, 255.0)); 00403 } 00404 } 00405 00406 RGBPrime2RGBFunctor(double max) 00407 { 00408 for(int i=0; i<256; ++i) 00409 { 00410 lut_[i] = NumericTraits<unsigned char>::fromRealPromote(detail::gammaCorrection(i, 1.0/0.45, max)); 00411 } 00412 } 00413 00414 RGBValue<unsigned char> operator()(TinyVector<unsigned char, 3> const & rgb) const 00415 { 00416 return RGBValue<unsigned char>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]); 00417 } 00418 }; 00419 00420 /** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ. 00421 00422 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00423 Namespace: vigra 00424 00425 According to ITU-R Recommendation BT.709, the functor realizes the transformation 00426 00427 \f[ 00428 \begin{array}{rcl} 00429 X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max} + 0.180423\enspace B / B_{max}\\ 00430 Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max} + 0.072169\enspace B / B_{max} \\ 00431 Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max} + 0.950227\enspace B / B_{max} 00432 \end{array} 00433 \f] 00434 00435 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden 00436 in the constructor. X, Y, and Z are always positive and reach their maximum for white. 00437 The white point is obtained by transforming RGB(255, 255, 255). It corresponds to the 00438 D65 illuminant. Y represents the <em>luminance</em> ("brightness") of the color. 00439 */ 00440 template <class T> 00441 class RGB2XYZFunctor 00442 { 00443 public: 00444 00445 /** the result's component type 00446 */ 00447 typedef typename NumericTraits<T>::RealPromote component_type; 00448 00449 /** the functor's argument type 00450 */ 00451 typedef TinyVector<T, 3> argument_type; 00452 00453 /** the functor's result type 00454 */ 00455 typedef TinyVector<component_type, 3> result_type; 00456 00457 /** \deprecated use argument_type and result_type 00458 */ 00459 typedef TinyVector<component_type, 3> value_type; 00460 00461 /** default constructor. 00462 The maximum value for each RGB component defaults to 255. 00463 */ 00464 RGB2XYZFunctor() 00465 : max_(255.0) 00466 {} 00467 00468 /** constructor 00469 \arg max - the maximum value for each RGB component 00470 */ 00471 RGB2XYZFunctor(component_type max) 00472 : max_(max) 00473 {} 00474 00475 /** apply the transformation 00476 */ 00477 result_type operator()(argument_type const & rgb) const 00478 { 00479 component_type red = rgb[0] / max_; 00480 component_type green = rgb[1] / max_; 00481 component_type blue = rgb[2] / max_; 00482 result_type result; 00483 result[0] = 0.412453*red + 0.357580*green + 0.180423*blue; 00484 result[1] = 0.212671*red + 0.715160*green + 0.072169*blue; 00485 result[2] = 0.019334*red + 0.119193*green + 0.950227*blue; 00486 return result; 00487 } 00488 00489 private: 00490 component_type max_; 00491 }; 00492 00493 /** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tri-stimulus XYZ. 00494 00495 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00496 Namespace: vigra 00497 00498 The functor realizes the transformation 00499 00500 \f[ 00501 R'G'B' \Rightarrow RGB \Rightarrow XYZ 00502 \f] 00503 00504 See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a description of the two 00505 steps. 00506 */ 00507 template <class T> 00508 class RGBPrime2XYZFunctor 00509 { 00510 public: 00511 00512 /** the result's component type 00513 */ 00514 typedef typename NumericTraits<T>::RealPromote component_type; 00515 00516 /** the functor's argument type 00517 */ 00518 typedef TinyVector<T, 3> argument_type; 00519 00520 /** the functor's result type 00521 */ 00522 typedef TinyVector<component_type, 3> result_type; 00523 00524 /** \deprecated use argument_type and result_type 00525 */ 00526 typedef TinyVector<component_type, 3> value_type; 00527 00528 /** default constructor 00529 The maximum value for each RGB component defaults to 255. 00530 */ 00531 RGBPrime2XYZFunctor() 00532 : max_(255.0), gamma_(1.0/ 0.45) 00533 {} 00534 00535 /** constructor 00536 \arg max - the maximum value for each RGB component 00537 */ 00538 RGBPrime2XYZFunctor(component_type max) 00539 : max_(max), gamma_(1.0/ 0.45) 00540 {} 00541 00542 /** apply the transformation 00543 */ 00544 result_type operator()(argument_type const & rgb) const 00545 { 00546 component_type red = detail::gammaCorrection(rgb[0]/max_, gamma_); 00547 component_type green = detail::gammaCorrection(rgb[1]/max_, gamma_); 00548 component_type blue = detail::gammaCorrection(rgb[2]/max_, gamma_); 00549 result_type result; 00550 result[0] = 0.412453*red + 0.357580*green + 0.180423*blue; 00551 result[1] = 0.212671*red + 0.715160*green + 0.072169*blue; 00552 result[2] = 0.019334*red + 0.119193*green + 0.950227*blue; 00553 return result; 00554 } 00555 00556 private: 00557 component_type max_, gamma_; 00558 }; 00559 00560 /** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB. 00561 00562 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00563 Namespace: vigra 00564 00565 According to ITU-R Recommendation BT.709, the functor realizes the transformation 00566 00567 \f[ 00568 \begin{array}{rcl} 00569 R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y - 0.4985363262\enspace Z) \\ 00570 G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y + 0.0415559266\enspace Z) \\ 00571 B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y + 1.0573110696\enspace Z) 00572 \end{array} 00573 \f] 00574 00575 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden 00576 in the constructor. This is the inverse transform of vigra::RGB2XYZFunctor. 00577 */ 00578 template <class T> 00579 class XYZ2RGBFunctor 00580 { 00581 typedef typename NumericTraits<T>::RealPromote component_type; 00582 00583 component_type max_; 00584 00585 public: 00586 /** the functor's argument type. (Actually, the argument type 00587 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 00588 <TT>V</TT>. But this cannot be expressed in a typedef.) 00589 */ 00590 typedef TinyVector<T, 3> argument_type; 00591 00592 /** the functor's result type 00593 */ 00594 typedef RGBValue<T> result_type; 00595 00596 /** \deprecated use argument_type and result_type 00597 */ 00598 typedef RGBValue<T> value_type; 00599 00600 /** default constructor. 00601 The maximum value for each RGB component defaults to 255. 00602 */ 00603 XYZ2RGBFunctor() 00604 : max_(255.0) 00605 {} 00606 00607 /** constructor 00608 \arg max - the maximum value for each RGB component 00609 */ 00610 XYZ2RGBFunctor(component_type max) 00611 : max_(max) 00612 {} 00613 00614 /** apply the transformation 00615 */ 00616 template <class V> 00617 value_type operator()(TinyVector<V, 3> const & xyz) const 00618 { 00619 component_type red = 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]; 00620 component_type green = -0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]; 00621 component_type blue = 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]; 00622 return value_type(NumericTraits<T>::fromRealPromote(red * max_), 00623 NumericTraits<T>::fromRealPromote(green * max_), 00624 NumericTraits<T>::fromRealPromote(blue * max_)); 00625 } 00626 }; 00627 00628 /** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma corrected) R'G'B'. 00629 00630 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00631 Namespace: vigra 00632 00633 The functor realizes the transformation 00634 00635 \f[ 00636 XYZ \Rightarrow RGB \Rightarrow R'G'B' 00637 \f] 00638 00639 See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a description of the two 00640 steps. 00641 */ 00642 template <class T> 00643 class XYZ2RGBPrimeFunctor 00644 { 00645 typedef typename NumericTraits<T>::RealPromote component_type; 00646 00647 component_type max_, gamma_; 00648 00649 public: 00650 00651 public: 00652 /** the functor's argument type. (actually, the argument type 00653 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 00654 <TT>V</TT>. But this cannot be expressed in a typedef.) 00655 */ 00656 typedef TinyVector<T, 3> argument_type; 00657 00658 /** the functor's result type 00659 */ 00660 typedef RGBValue<T> result_type; 00661 00662 /** \deprecated use argument_type and result_type 00663 */ 00664 typedef RGBValue<T> value_type; 00665 00666 /** default constructor. 00667 The maximum value for each RGB component defaults to 255. 00668 */ 00669 XYZ2RGBPrimeFunctor() 00670 : max_(255.0), gamma_(0.45) 00671 {} 00672 00673 /** constructor 00674 \arg max - the maximum value for each RGB component 00675 */ 00676 XYZ2RGBPrimeFunctor(component_type max) 00677 : max_(max), gamma_(0.45) 00678 {} 00679 00680 /** apply the transformation 00681 */ 00682 template <class V> 00683 value_type operator()(TinyVector<V, 3> const & xyz) const 00684 { 00685 component_type red = 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]; 00686 component_type green = -0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]; 00687 component_type blue = 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]; 00688 return value_type(NumericTraits<T>::fromRealPromote(detail::gammaCorrection(red, gamma_) * max_), 00689 NumericTraits<T>::fromRealPromote(detail::gammaCorrection(green, gamma_) * max_), 00690 NumericTraits<T>::fromRealPromote(detail::gammaCorrection(blue, gamma_) * max_)); 00691 } 00692 }; 00693 00694 /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*u*v*. 00695 00696 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00697 Namespace: vigra 00698 00699 The functor realizes the transformation 00700 00701 \f[ 00702 \begin{array}{rcl} 00703 L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\ 00704 & & \\ 00705 L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\ 00706 & & \\ 00707 00708 u' & = & \frac{4 X}{X+15 Y + 3 Z}, \quad 00709 v' = \frac{9 Y}{X+15 Y + 3 Z}\\ 00710 & & \\ 00711 u^{*} & = & 13 L^{*} (u' - u_n'), \quad v^{*} = 13 L^{*} (v' - v_n') 00712 \end{array} 00713 \f] 00714 00715 where \f$(X_n, Y_n, Z_n)\f$ is the reference white point, and 00716 \f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ calculated for this 00717 point. \f$L^{*}\f$ represents the 00718 <em>lighness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ code the 00719 chromaticity. 00720 */ 00721 template <class T> 00722 class XYZ2LuvFunctor 00723 { 00724 public: 00725 00726 /** the result's component type 00727 */ 00728 typedef typename NumericTraits<T>::RealPromote component_type; 00729 00730 /** the functor's argument type 00731 */ 00732 typedef TinyVector<T, 3> argument_type; 00733 00734 /** the functor's result type 00735 */ 00736 typedef TinyVector<component_type, 3> result_type; 00737 00738 /** \deprecated use argument_type and result_type 00739 */ 00740 typedef TinyVector<component_type, 3> value_type; 00741 00742 XYZ2LuvFunctor() 00743 : gamma_(1.0/3.0) 00744 {} 00745 00746 result_type operator()(TinyVector<T, 3> const & xyz) const 00747 { 00748 result_type result; 00749 if(xyz[1] == NumericTraits<T>::zero()) 00750 { 00751 result[0] = NumericTraits<component_type>::zero(); 00752 result[1] = NumericTraits<component_type>::zero(); 00753 result[2] = NumericTraits<component_type>::zero(); 00754 } 00755 else 00756 { 00757 component_type L = xyz[1] < 0.008856 ? 00758 903.3 * xyz[1] : 00759 116.0 * VIGRA_CSTD::pow(xyz[1], gamma_) - 16.0; 00760 component_type denom = xyz[0] + 15.0*xyz[1] + 3.0*xyz[2]; 00761 component_type uprime = 4.0 * xyz[0] / denom; 00762 component_type vprime = 9.0 * xyz[1] / denom; 00763 result[0] = L; 00764 result[1] = 13.0*L*(uprime - 0.197839); 00765 result[2] = 13.0*L*(vprime - 0.468342); 00766 } 00767 return result; 00768 } 00769 00770 private: 00771 component_type gamma_; 00772 }; 00773 00774 /** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stimulus XYZ. 00775 00776 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00777 Namespace: vigra 00778 00779 The functor realizes the inverse of the transformation described in vigra::XYZ2LuvFunctor 00780 */ 00781 template <class T> 00782 class Luv2XYZFunctor 00783 { 00784 public: 00785 00786 /** the result's component type 00787 */ 00788 typedef typename NumericTraits<T>::RealPromote component_type; 00789 00790 /** the functor's argument type 00791 */ 00792 typedef TinyVector<T, 3> argument_type; 00793 00794 /** the functor's result type 00795 */ 00796 typedef TinyVector<component_type, 3> result_type; 00797 00798 /** \deprecated use argument_type and result_type 00799 */ 00800 typedef TinyVector<component_type, 3> value_type; 00801 00802 Luv2XYZFunctor() 00803 : gamma_(3.0) 00804 {} 00805 00806 /** apply the transformation 00807 */ 00808 result_type operator()(TinyVector<T, 3> const & luv) const 00809 { 00810 result_type result; 00811 if(luv[0] == NumericTraits<T>::zero()) 00812 { 00813 result[0] = NumericTraits<component_type>::zero(); 00814 result[1] = NumericTraits<component_type>::zero(); 00815 result[2] = NumericTraits<component_type>::zero(); 00816 } 00817 else 00818 { 00819 component_type uprime = luv[1] / 13.0 / luv[0] + 0.197839; 00820 component_type vprime = luv[2] / 13.0 / luv[0] + 0.468342; 00821 00822 result[1] = luv[0] < 8.0 ? 00823 luv[0] / 903.3 : 00824 VIGRA_CSTD::pow((luv[0] + 16.0) / 116.0, gamma_); 00825 result[0] = 9.0*uprime*result[1] / 4.0 / vprime; 00826 result[2] = ((9.0 / vprime - 15.0)*result[1] - result[0])/ 3.0; 00827 } 00828 return result; 00829 } 00830 00831 private: 00832 component_type gamma_; 00833 }; 00834 00835 /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*a*b*. 00836 00837 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00838 Namespace: vigra 00839 00840 The functor realizes the transformation 00841 00842 \f[ 00843 \begin{array}{rcl} 00844 L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\ 00845 & & \\ 00846 L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\ 00847 & & \\ 00848 a^{*} & = & 500 \left[ \left( \frac{X}{X_n} \right)^\frac{1}{3} - \left( \frac{Y}{Y_n} \right)^\frac{1}{3} \right] \\ 00849 & & \\ 00850 b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\ 00851 \end{array} 00852 \f] 00853 00854 where \f$(X_n, Y_n, Z_n)\f$ is the reference white point. \f$L^{*}\f$ represents the 00855 <em>lighness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ code the 00856 chromaticity. 00857 */ 00858 template <class T> 00859 class XYZ2LabFunctor 00860 { 00861 public: 00862 00863 /** the result's component type 00864 */ 00865 typedef typename NumericTraits<T>::RealPromote component_type; 00866 00867 /** the functor's argument type 00868 */ 00869 typedef TinyVector<T, 3> argument_type; 00870 00871 /** the functor's result type 00872 */ 00873 typedef TinyVector<component_type, 3> result_type; 00874 00875 /** \deprecated use argument_type and result_type 00876 */ 00877 typedef TinyVector<component_type, 3> value_type; 00878 00879 XYZ2LabFunctor() 00880 : gamma_(1.0/3.0) 00881 {} 00882 00883 /** apply the transformation 00884 */ 00885 result_type operator()(TinyVector<T, 3> const & xyz) const 00886 { 00887 component_type xgamma = VIGRA_CSTD::pow(xyz[0] / 0.950456, gamma_); 00888 component_type ygamma = VIGRA_CSTD::pow(xyz[1], gamma_); 00889 component_type zgamma = VIGRA_CSTD::pow(xyz[2] / 1.088754, gamma_); 00890 component_type L = xyz[1] < 0.008856 ? 00891 903.3 * xyz[1] : 00892 116.0 * ygamma - 16.0; 00893 result_type result; 00894 result[0] = L; 00895 result[1] = 500.0*(xgamma - ygamma); 00896 result[2] = 200.0*(ygamma - zgamma); 00897 return result; 00898 } 00899 00900 private: 00901 component_type gamma_; 00902 }; 00903 00904 /** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stimulus XYZ. 00905 00906 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00907 Namespace: vigra 00908 00909 The functor realizes the inverse of the transformation described in vigra::XYZ2LabFunctor 00910 */ 00911 template <class T> 00912 class Lab2XYZFunctor 00913 { 00914 public: 00915 00916 /** the result's component type 00917 */ 00918 typedef typename NumericTraits<T>::RealPromote component_type; 00919 00920 /** the functor's argument type 00921 */ 00922 typedef TinyVector<T, 3> argument_type; 00923 00924 /** the functor's result type 00925 */ 00926 typedef TinyVector<component_type, 3> result_type; 00927 00928 /** \deprecated use argument_type and result_type 00929 */ 00930 typedef TinyVector<component_type, 3> value_type; 00931 00932 /** the functor's value type 00933 */ 00934 Lab2XYZFunctor() 00935 : gamma_(3.0) 00936 {} 00937 00938 /** apply the transformation 00939 */ 00940 result_type operator()(TinyVector<T, 3> const & lab) const 00941 { 00942 component_type Y = lab[0] < 8.0 ? 00943 lab[0] / 903.3 : 00944 VIGRA_CSTD::pow((lab[0] + 16.0) / 116.0, gamma_); 00945 component_type ygamma = VIGRA_CSTD::pow(Y, 1.0 / gamma_); 00946 component_type X = VIGRA_CSTD::pow(lab[1] / 500.0 + ygamma, gamma_) * 0.950456; 00947 component_type Z = VIGRA_CSTD::pow(-lab[2] / 200.0 + ygamma, gamma_) * 1.088754; 00948 result_type result; 00949 result[0] = X; 00950 result[1] = Y; 00951 result[2] = Z; 00952 return result; 00953 } 00954 00955 private: 00956 component_type gamma_; 00957 }; 00958 00959 00960 /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*. 00961 00962 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 00963 Namespace: vigra 00964 00965 The functor realizes the transformation 00966 00967 \f[ 00968 RGB \Rightarrow XYZ \Rightarrow L^*u^*v^* 00969 \f] 00970 00971 See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the two 00972 steps. The resulting color components will have the following bounds: 00973 00974 \f[ 00975 \begin{array}{rcl} 00976 0 \leq & L^* & \leq 100 \\ 00977 -83.077 \leq & u^* & \leq 175.015 \\ 00978 -134.101 \leq & v^* & \leq 107.393 00979 \end{array} 00980 \f] 00981 */ 00982 template <class T> 00983 class RGB2LuvFunctor 00984 { 00985 /* 00986 L in [0, 100] 00987 u in [-83.077, 175.015] 00988 v in [-134.101, 107.393] 00989 maximum saturation: 179.04 00990 red = [53.2406, 175.015, 37.7522] 00991 */ 00992 public: 00993 00994 /** the result's component type 00995 */ 00996 typedef typename NumericTraits<T>::RealPromote component_type; 00997 00998 /** the functor's argument type 00999 */ 01000 typedef TinyVector<T, 3> argument_type; 01001 01002 /** the functor's result type 01003 */ 01004 typedef typename XYZ2LuvFunctor<component_type>::result_type result_type; 01005 01006 /** \deprecated use argument_type and result_type 01007 */ 01008 typedef typename XYZ2LuvFunctor<component_type>::result_type value_type; 01009 01010 /** default constructor. 01011 The maximum value for each RGB component defaults to 255. 01012 */ 01013 RGB2LuvFunctor() 01014 : rgb2xyz(255.0) 01015 {} 01016 01017 /** constructor 01018 \arg max - the maximum value for each RGB component 01019 */ 01020 RGB2LuvFunctor(component_type max) 01021 : rgb2xyz(max) 01022 {} 01023 01024 /** apply the transformation 01025 */ 01026 result_type operator()(TinyVector<T, 3> const & rgb) const 01027 { 01028 return xyz2luv(rgb2xyz(rgb)); 01029 } 01030 01031 private: 01032 RGB2XYZFunctor<T> rgb2xyz; 01033 XYZ2LuvFunctor<component_type> xyz2luv; 01034 }; 01035 01036 /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*. 01037 01038 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01039 Namespace: vigra 01040 01041 The functor realizes the transformation 01042 01043 \f[ 01044 RGB \Rightarrow XYZ \Rightarrow L^*a^*b^* 01045 \f] 01046 01047 See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the two 01048 steps. The resulting color components will have the following bounds: 01049 01050 \f[ 01051 \begin{array}{rcl} 01052 0 \leq & L^* & \leq 100 \\ 01053 -86.1813 \leq & u^* & \leq 98.2352 \\ 01054 -107.862 \leq & v^* & \leq 94.4758 01055 \end{array} 01056 \f] 01057 */ 01058 template <class T> 01059 class RGB2LabFunctor 01060 { 01061 /* 01062 L in [0, 100] 01063 a in [-86.1813, 98.2352] 01064 b in [-107.862, 94.4758] 01065 maximum saturation: 133.809 01066 red = [53.2406, 80.0942, 67.2015] 01067 */ 01068 public: 01069 01070 /** the result's component type 01071 */ 01072 typedef typename NumericTraits<T>::RealPromote component_type; 01073 01074 /** the functor's argument type 01075 */ 01076 typedef TinyVector<T, 3> argument_type; 01077 01078 /** the functor's result type 01079 */ 01080 typedef typename XYZ2LabFunctor<component_type>::result_type result_type; 01081 01082 /** \deprecated use argument_type and result_type 01083 */ 01084 typedef typename XYZ2LabFunctor<component_type>::result_type value_type; 01085 01086 /** default constructor. 01087 The maximum value for each RGB component defaults to 255. 01088 */ 01089 RGB2LabFunctor() 01090 : rgb2xyz(255.0) 01091 {} 01092 01093 /** constructor 01094 \arg max - the maximum value for each RGB component 01095 */ 01096 RGB2LabFunctor(component_type max) 01097 : rgb2xyz(max) 01098 {} 01099 01100 /** apply the transformation 01101 */ 01102 result_type operator()(TinyVector<T, 3> const & rgb) const 01103 { 01104 return xyz2lab(rgb2xyz(rgb)); 01105 } 01106 01107 private: 01108 RGB2XYZFunctor<T> rgb2xyz; 01109 XYZ2LabFunctor<component_type> xyz2lab; 01110 }; 01111 01112 /** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB. 01113 01114 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01115 Namespace: vigra 01116 01117 The functor realizes the inverse of the transformation described in vigra::RGB2LuvFunctor 01118 */ 01119 template <class T> 01120 class Luv2RGBFunctor 01121 { 01122 typedef typename NumericTraits<T>::RealPromote component_type; 01123 01124 XYZ2RGBFunctor<T> xyz2rgb; 01125 Luv2XYZFunctor<component_type> luv2xyz; 01126 01127 public: 01128 /** the functor's argument type. (Actually, the argument type 01129 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 01130 <TT>V</TT>. But this cannot be expressed in a typedef.) 01131 */ 01132 typedef TinyVector<T, 3> argument_type; 01133 01134 /** the functor's result type 01135 */ 01136 typedef typename XYZ2RGBFunctor<T>::result_type result_type; 01137 01138 /** \deprecated use argument_type and result_type 01139 */ 01140 typedef typename XYZ2RGBFunctor<T>::result_type value_type; 01141 01142 Luv2RGBFunctor() 01143 : xyz2rgb(255.0) 01144 {} 01145 01146 Luv2RGBFunctor(component_type max) 01147 : xyz2rgb(max) 01148 {} 01149 01150 /** apply the transformation 01151 */ 01152 template <class V> 01153 result_type operator()(TinyVector<V, 3> const & luv) const 01154 { 01155 return xyz2rgb(luv2xyz(luv)); 01156 } 01157 }; 01158 01159 /** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB. 01160 01161 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01162 Namespace: vigra 01163 01164 The functor realizes the inverse of the transformation described in vigra::RGB2LabFunctor 01165 */ 01166 template <class T> 01167 class Lab2RGBFunctor 01168 { 01169 typedef typename NumericTraits<T>::RealPromote component_type; 01170 01171 XYZ2RGBFunctor<T> xyz2rgb; 01172 Lab2XYZFunctor<component_type> lab2xyz; 01173 01174 public: 01175 01176 /** the functor's argument type. (Actually, the argument type 01177 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 01178 <TT>V</TT>. But this cannot be expressed in a typedef.) 01179 */ 01180 typedef TinyVector<T, 3> argument_type; 01181 01182 /** the functor's result type 01183 */ 01184 typedef typename XYZ2RGBFunctor<T>::result_type result_type; 01185 01186 /** \deprecated use argument_type and result_type 01187 */ 01188 typedef typename XYZ2RGBFunctor<T>::result_type value_type; 01189 01190 /** default constructor. 01191 The maximum value for each RGB component defaults to 255. 01192 */ 01193 Lab2RGBFunctor() 01194 : xyz2rgb(255.0) 01195 {} 01196 01197 /** constructor 01198 \arg max - the maximum value for each RGB component 01199 */ 01200 Lab2RGBFunctor(component_type max) 01201 : xyz2rgb(max) 01202 {} 01203 01204 /** apply the transformation 01205 */ 01206 template <class V> 01207 result_type operator()(TinyVector<V, 3> const & lab) const 01208 { 01209 return xyz2rgb(lab2xyz(lab)); 01210 } 01211 }; 01212 01213 /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*u*v*. 01214 01215 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01216 Namespace: vigra 01217 01218 The functor realizes the transformation 01219 01220 \f[ 01221 R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^* 01222 \f] 01223 01224 See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the three 01225 steps. The resulting color components will have the following bounds: 01226 01227 \f[ 01228 \begin{array}{rcl} 01229 0 \leq & L^* & \leq 100 \\ 01230 -83.077 \leq & u^* & \leq 175.015 \\ 01231 -134.101 \leq & v^* & \leq 107.393 01232 \end{array} 01233 \f] 01234 */ 01235 template <class T> 01236 class RGBPrime2LuvFunctor 01237 { 01238 public: 01239 01240 /** the result's component type 01241 */ 01242 typedef typename NumericTraits<T>::RealPromote component_type; 01243 01244 /** the functor's argument type 01245 */ 01246 typedef TinyVector<T, 3> argument_type; 01247 01248 /** the functor's result type 01249 */ 01250 typedef typename XYZ2LuvFunctor<component_type>::result_type result_type; 01251 01252 /** \deprecated use argument_type and result_type 01253 */ 01254 typedef typename XYZ2LuvFunctor<component_type>::result_type value_type; 01255 01256 /** default constructor. 01257 The maximum value for each RGB component defaults to 255. 01258 */ 01259 RGBPrime2LuvFunctor() 01260 : rgb2xyz(255.0) 01261 {} 01262 01263 /** constructor 01264 \arg max - the maximum value for each RGB component 01265 */ 01266 RGBPrime2LuvFunctor(component_type max) 01267 : rgb2xyz(max) 01268 {} 01269 01270 /** apply the transformation 01271 */ 01272 result_type operator()(TinyVector<T, 3> const & rgb) const 01273 { 01274 return xyz2luv(rgb2xyz(rgb)); 01275 } 01276 01277 private: 01278 RGBPrime2XYZFunctor<T> rgb2xyz; 01279 XYZ2LuvFunctor<component_type> xyz2luv; 01280 }; 01281 01282 /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*a*b*. 01283 01284 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01285 Namespace: vigra 01286 01287 The functor realizes the transformation 01288 01289 \f[ 01290 R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^* 01291 \f] 01292 01293 See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the three 01294 steps. The resulting color components will have the following bounds: 01295 01296 \f[ 01297 \begin{array}{rcl} 01298 0 \leq & L^* & \leq 100 \\ 01299 -86.1813 \leq & u^* & \leq 98.2352 \\ 01300 -107.862 \leq & v^* & \leq 94.4758 01301 \end{array} 01302 \f] 01303 */ 01304 template <class T> 01305 class RGBPrime2LabFunctor 01306 { 01307 public: 01308 01309 /** the result's component type 01310 */ 01311 typedef typename NumericTraits<T>::RealPromote component_type; 01312 01313 /** the functor's argument type 01314 */ 01315 typedef TinyVector<T, 3> argument_type; 01316 01317 /** the functor's result type 01318 */ 01319 typedef typename XYZ2LabFunctor<component_type>::result_type result_type; 01320 01321 /** \deprecated use argument_type and result_type 01322 */ 01323 typedef typename XYZ2LabFunctor<component_type>::result_type value_type; 01324 01325 /** default constructor. 01326 The maximum value for each RGB component defaults to 255. 01327 */ 01328 RGBPrime2LabFunctor() 01329 : rgb2xyz(255.0) 01330 {} 01331 01332 /** constructor 01333 \arg max - the maximum value for each RGB component 01334 */ 01335 RGBPrime2LabFunctor(component_type max) 01336 : rgb2xyz(max) 01337 {} 01338 01339 /** apply the transformation 01340 */ 01341 result_type operator()(TinyVector<T, 3> const & rgb) const 01342 { 01343 return xyz2lab(rgb2xyz(rgb)); 01344 } 01345 01346 private: 01347 RGBPrime2XYZFunctor<T> rgb2xyz; 01348 XYZ2LabFunctor<component_type> xyz2lab; 01349 }; 01350 01351 /** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma corrected) R'G'B'. 01352 01353 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01354 Namespace: vigra 01355 01356 The functor realizes the inverse of the transformation described in vigra::RGBPrime2LuvFunctor 01357 */ 01358 template <class T> 01359 class Luv2RGBPrimeFunctor 01360 { 01361 typedef typename NumericTraits<T>::RealPromote component_type; 01362 01363 XYZ2RGBPrimeFunctor<T> xyz2rgb; 01364 Luv2XYZFunctor<component_type> luv2xyz; 01365 01366 public: 01367 01368 /** the functor's argument type. (Actually, the argument type 01369 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 01370 <TT>V</TT>. But this cannot be expressed in a typedef.) 01371 */ 01372 typedef TinyVector<T, 3> argument_type; 01373 01374 /** the functor's result type 01375 */ 01376 typedef typename XYZ2RGBFunctor<T>::result_type result_type; 01377 01378 /** \deprecated use argument_type and result_type 01379 */ 01380 typedef typename XYZ2RGBFunctor<T>::result_type value_type; 01381 01382 /** default constructor. 01383 The maximum value for each RGB component defaults to 255. 01384 */ 01385 Luv2RGBPrimeFunctor() 01386 : xyz2rgb(255.0) 01387 {} 01388 01389 /** constructor 01390 \arg max - the maximum value for each RGB component 01391 */ 01392 Luv2RGBPrimeFunctor(component_type max) 01393 : xyz2rgb(max) 01394 {} 01395 01396 /** apply the transformation 01397 */ 01398 template <class V> 01399 result_type operator()(TinyVector<V, 3> const & luv) const 01400 { 01401 return xyz2rgb(luv2xyz(luv)); 01402 } 01403 }; 01404 01405 /** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma corrected) R'G'B'. 01406 01407 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01408 Namespace: vigra 01409 01410 The functor realizes the inverse of the transformation described in vigra::RGBPrime2LabFunctor 01411 */ 01412 template <class T> 01413 class Lab2RGBPrimeFunctor 01414 { 01415 typedef typename NumericTraits<T>::RealPromote component_type; 01416 01417 XYZ2RGBPrimeFunctor<T> xyz2rgb; 01418 Lab2XYZFunctor<component_type> lab2xyz; 01419 01420 public: 01421 01422 /** the functor's argument type. (Actually, the argument type 01423 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 01424 <TT>V</TT>. But this cannot be expressed in a typedef.) 01425 */ 01426 typedef TinyVector<T, 3> argument_type; 01427 01428 /** the functor's result type 01429 */ 01430 typedef typename XYZ2RGBFunctor<T>::result_type result_type; 01431 01432 /** \deprecated use argument_type and result_type 01433 */ 01434 typedef typename XYZ2RGBFunctor<T>::result_type value_type; 01435 01436 /** default constructor. 01437 The maximum value for each RGB component defaults to 255. 01438 */ 01439 Lab2RGBPrimeFunctor() 01440 : xyz2rgb(255.0) 01441 {} 01442 01443 /** constructor 01444 \arg max - the maximum value for each RGB component 01445 */ 01446 Lab2RGBPrimeFunctor(component_type max) 01447 : xyz2rgb(max) 01448 {} 01449 01450 /** apply the transformation 01451 */ 01452 template <class V> 01453 result_type operator()(TinyVector<V, 3> const & lab) const 01454 { 01455 return xyz2rgb(lab2xyz(lab)); 01456 } 01457 }; 01458 01459 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color difference components. 01460 01461 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01462 Namespace: vigra 01463 01464 According to ITU-R Recommendation BT.601, the functor realizes the transformation 01465 01466 \f[ 01467 \begin{array}{rcl} 01468 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\ 01469 Pb & = & -0.1687358916\enspace R / R_{max} + 0.3312641084\enspace G / G_{max} + 0.5\enspace B / B_{max} \\ 01470 Pr & = & 0.5\enspace R / R_{max} + 0.4186875892\enspace G / G_{max} + 0.0813124108\enspace B / B_{max} 01471 \end{array} 01472 \f] 01473 01474 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden 01475 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color, and 01476 Pb and Pr are the blue (B'-Y') and red (R'-Y') color difference components. 01477 The transformation is scaled so that the following bounds apply: 01478 01479 \f[ 01480 \begin{array}{rcl} 01481 0 \leq & Y' & \leq 1 \\ 01482 -0.5 \leq & Pb & \leq 0.5 \\ 01483 -0.5 \leq & Pr & \leq 0.5 01484 \end{array} 01485 \f] 01486 */ 01487 template <class T> 01488 class RGBPrime2YPrimePbPrFunctor 01489 { 01490 /* 01491 Y in [0, 1] 01492 Pb in [-0.5, 0.5] 01493 Pr in [-0.5, 0.5] 01494 maximum saturation: 0.533887 01495 red = [0.299, -0.168736, 0.5] 01496 */ 01497 public: 01498 01499 /** the result's component type 01500 */ 01501 typedef typename NumericTraits<T>::RealPromote component_type; 01502 01503 /** the functor's argument type 01504 */ 01505 typedef TinyVector<T, 3> argument_type; 01506 01507 /** the functor's result type 01508 */ 01509 typedef TinyVector<component_type, 3> result_type; 01510 01511 /** \deprecated use argument_type and result_type 01512 */ 01513 typedef TinyVector<component_type, 3> value_type; 01514 01515 /** default constructor. 01516 The maximum value for each RGB component defaults to 255. 01517 */ 01518 RGBPrime2YPrimePbPrFunctor() 01519 : max_(255.0) 01520 {} 01521 01522 /** constructor 01523 \arg max - the maximum value for each RGB component 01524 */ 01525 RGBPrime2YPrimePbPrFunctor(component_type max) 01526 : max_(max) 01527 {} 01528 01529 /** apply the transformation 01530 */ 01531 result_type operator()(TinyVector<T, 3> const & rgb) const 01532 { 01533 component_type red = rgb[0] / max_; 01534 component_type green = rgb[1] / max_; 01535 component_type blue = rgb[2] / max_; 01536 01537 result_type result; 01538 result[0] = 0.299*red + 0.587*green + 0.114*blue; 01539 result[1] = -0.1687358916*red - 0.3312641084*green + 0.5*blue; 01540 result[2] = 0.5*red - 0.4186875892*green - 0.0813124108*blue; 01541 return result; 01542 } 01543 01544 private: 01545 component_type max_; 01546 }; 01547 01548 /** \brief Convert Y'PbPr color difference components into non-linear (gamma corrected) R'G'B'. 01549 01550 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01551 Namespace: vigra 01552 01553 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimePbPrFunctor 01554 */ 01555 template <class T> 01556 class YPrimePbPr2RGBPrimeFunctor 01557 { 01558 typedef typename NumericTraits<T>::RealPromote component_type; 01559 01560 component_type max_; 01561 01562 public: 01563 01564 /** the functor's argument type. (Actually, the argument type 01565 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 01566 <TT>V</TT>. But this cannot be expressed in a typedef.) 01567 */ 01568 typedef TinyVector<T, 3> argument_type; 01569 01570 /** the functor's result type 01571 */ 01572 typedef RGBValue<T> result_type; 01573 01574 /** \deprecated use argument_type and result_type 01575 */ 01576 typedef RGBValue<T> value_type; 01577 01578 /** default constructor. 01579 The maximum value for each RGB component defaults to 255. 01580 */ 01581 YPrimePbPr2RGBPrimeFunctor() 01582 : max_(255.0) 01583 {} 01584 01585 /** constructor 01586 \arg max - the maximum value for each RGB component 01587 */ 01588 YPrimePbPr2RGBPrimeFunctor(component_type max) 01589 : max_(max) 01590 {} 01591 01592 /** apply the transformation 01593 */ 01594 template <class V> 01595 result_type operator()(TinyVector<V, 3> const & ypbpr) const 01596 { 01597 component_type nred = ypbpr[0] + 1.402*ypbpr[2]; 01598 component_type ngreen = ypbpr[0] - 0.3441362862*ypbpr[1] - 0.7141362862*ypbpr[2]; 01599 component_type nblue = ypbpr[0] + 1.772*ypbpr[1]; 01600 return result_type(NumericTraits<T>::fromRealPromote(nred * max_), 01601 NumericTraits<T>::fromRealPromote(ngreen * max_), 01602 NumericTraits<T>::fromRealPromote(nblue * max_)); 01603 } 01604 }; 01605 01606 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components. 01607 01608 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01609 Namespace: vigra 01610 01611 According to the PAL analog videa standard, the functor realizes the transformation 01612 01613 \f[ 01614 \begin{array}{rcl} 01615 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\ 01616 I & = & 0.596\enspace R / R_{max} - 0.274\enspace G / G_{max} - 0.322\enspace B / B_{max} \\ 01617 Q & = & 0.212\enspace R / R_{max} - 0.523\enspace G / G_{max} + 0.311\enspace B / B_{max} 01618 \end{array} 01619 \f] 01620 01621 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden 01622 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color. 01623 The transformation is scaled so that the following bounds apply: 01624 01625 \f[ 01626 \begin{array}{rcl} 01627 0 \leq & Y' & \leq 1 \\ 01628 -0.596 \leq & I & \leq 0.596 \\ 01629 -0.523 \leq & Q & \leq 0.523 01630 \end{array} 01631 \f] 01632 */ 01633 template <class T> 01634 class RGBPrime2YPrimeIQFunctor 01635 { 01636 /* 01637 Y in [0, 1] 01638 I in [-0.596, 0.596] 01639 Q in [-0.523, 0.523] 01640 maximum saturation: 0.632582 01641 red = [0.299, 0.596, 0.212] 01642 */ 01643 public: 01644 01645 /** the result's component type 01646 */ 01647 typedef typename NumericTraits<T>::RealPromote component_type; 01648 01649 /** the functor's argument type 01650 */ 01651 typedef TinyVector<T, 3> argument_type; 01652 01653 /** the functor's result type 01654 */ 01655 typedef TinyVector<component_type, 3> result_type; 01656 01657 /** \deprecated use argument_type and result_type 01658 */ 01659 typedef TinyVector<component_type, 3> value_type; 01660 01661 /** default constructor. 01662 The maximum value for each RGB component defaults to 255. 01663 */ 01664 RGBPrime2YPrimeIQFunctor() 01665 : max_(255.0) 01666 {} 01667 01668 /** constructor 01669 \arg max - the maximum value for each RGB component 01670 */ 01671 RGBPrime2YPrimeIQFunctor(component_type max) 01672 : max_(max) 01673 {} 01674 01675 /** apply the transformation 01676 */ 01677 result_type operator()(TinyVector<T, 3> const & rgb) const 01678 { 01679 component_type red = rgb[0] / max_; 01680 component_type green = rgb[1] / max_; 01681 component_type blue = rgb[2] / max_; 01682 01683 result_type result; 01684 result[0] = 0.299*red + 0.587*green + 0.114*blue; 01685 result[1] = 0.596*red - 0.274*green - 0.322*blue; 01686 result[2] = 0.212*red - 0.523*green + 0.311*blue; 01687 return result; 01688 } 01689 01690 private: 01691 component_type max_; 01692 }; 01693 01694 /** \brief Convert Y'IQ color components into non-linear (gamma corrected) R'G'B'. 01695 01696 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01697 Namespace: vigra 01698 01699 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeIQFunctor 01700 */ 01701 template <class T> 01702 class YPrimeIQ2RGBPrimeFunctor 01703 { 01704 typedef typename NumericTraits<T>::RealPromote component_type; 01705 01706 component_type max_; 01707 01708 public: 01709 01710 /** the functor's argument type. (Actually, the argument type 01711 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 01712 <TT>V</TT>. But this cannot be expressed in a typedef.) 01713 */ 01714 typedef TinyVector<T, 3> argument_type; 01715 01716 /** the functor's result type 01717 */ 01718 typedef RGBValue<T> result_type; 01719 01720 /** \deprecated use argument_type and result_type 01721 */ 01722 typedef RGBValue<T> value_type; 01723 01724 /** default constructor. 01725 The maximum value for each RGB component defaults to 255. 01726 */ 01727 YPrimeIQ2RGBPrimeFunctor() 01728 : max_(255.0) 01729 {} 01730 01731 /** constructor 01732 \arg max - the maximum value for each RGB component 01733 */ 01734 YPrimeIQ2RGBPrimeFunctor(component_type max) 01735 : max_(max) 01736 {} 01737 01738 /** apply the transformation 01739 */ 01740 template <class V> 01741 result_type operator()(TinyVector<V, 3> const & yiq) const 01742 { 01743 component_type nred = yiq[0] + 0.9548892043*yiq[1] + 0.6221039350*yiq[2]; 01744 component_type ngreen = yiq[0] - 0.2713547827*yiq[1] - 0.6475120259*yiq[2]; 01745 component_type nblue = yiq[0] - 1.1072510054*yiq[1] + 1.7024603738*yiq[2]; 01746 return result_type(NumericTraits<T>::fromRealPromote(nred * max_), 01747 NumericTraits<T>::fromRealPromote(ngreen * max_), 01748 NumericTraits<T>::fromRealPromote(nblue * max_)); 01749 } 01750 }; 01751 01752 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components. 01753 01754 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01755 Namespace: vigra 01756 01757 According to the NTSC analog videa standard, the functor realizes the transformation 01758 01759 \f[ 01760 \begin{array}{rcl} 01761 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\ 01762 U & = & -0.147\enspace R / R_{max} - 0.289\enspace G / G_{max} + 0.436\enspace B / B_{max} \\ 01763 V & = & 0.615\enspace R / R_{max} - 0.515\enspace G / G_{max} - 0.100\enspace B / B_{max} 01764 \end{array} 01765 \f] 01766 01767 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden 01768 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color. 01769 The transformation is scaled so that the following bounds apply: 01770 01771 \f[ 01772 \begin{array}{rcl} 01773 0 \leq & Y' & \leq 1 \\ 01774 -0.436 \leq & U & \leq 0.436 \\ 01775 -0.615 \leq & V & \leq 0.615 01776 \end{array} 01777 \f] 01778 */ 01779 template <class T> 01780 class RGBPrime2YPrimeUVFunctor 01781 { 01782 /* 01783 Y in [0, 1] 01784 U in [-0.436, 0.436] 01785 V in [-0.615, 0.615] 01786 maximum saturation: 0.632324 01787 red = [0.299, -0.147, 0.615] 01788 */ 01789 public: 01790 01791 /** the result's component type 01792 */ 01793 typedef typename NumericTraits<T>::RealPromote component_type; 01794 01795 /** the functor's argument type 01796 */ 01797 typedef TinyVector<T, 3> argument_type; 01798 01799 /** the functor's result type 01800 */ 01801 typedef TinyVector<component_type, 3> result_type; 01802 01803 /** \deprecated use argument_type and result_type 01804 */ 01805 typedef TinyVector<component_type, 3> value_type; 01806 01807 /** default constructor. 01808 The maximum value for each RGB component defaults to 255. 01809 */ 01810 RGBPrime2YPrimeUVFunctor() 01811 : max_(255.0) 01812 {} 01813 01814 /** constructor 01815 \arg max - the maximum value for each RGB component 01816 */ 01817 RGBPrime2YPrimeUVFunctor(component_type max) 01818 : max_(max) 01819 {} 01820 01821 /** apply the transformation 01822 */ 01823 result_type operator()(TinyVector<T, 3> const & rgb) const 01824 { 01825 component_type red = rgb[0] / max_; 01826 component_type green = rgb[1] / max_; 01827 component_type blue = rgb[2] / max_; 01828 01829 result_type result; 01830 result[0] = 0.299*red + 0.587*green + 0.114*blue; 01831 result[1] = -0.1471376975*red - 0.2888623025*green + 0.436*blue; 01832 result[2] = 0.6149122807*red - 0.5149122807*green - 0.100*blue; 01833 return result; 01834 } 01835 01836 private: 01837 component_type max_; 01838 }; 01839 01840 /** \brief Convert Y'UV color components into non-linear (gamma corrected) R'G'B'. 01841 01842 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01843 Namespace: vigra 01844 01845 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeUVFunctor 01846 */ 01847 template <class T> 01848 class YPrimeUV2RGBPrimeFunctor 01849 { 01850 typedef typename NumericTraits<T>::RealPromote component_type; 01851 01852 component_type max_; 01853 01854 public: 01855 01856 /** the functor's argument type. (Actually, the argument type 01857 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 01858 <TT>V</TT>. But this cannot be expressed in a typedef.) 01859 */ 01860 typedef TinyVector<T, 3> argument_type; 01861 01862 /** the functor's result type 01863 */ 01864 typedef RGBValue<T> result_type; 01865 01866 /** \deprecated use argument_type and result_type 01867 */ 01868 typedef RGBValue<T> value_type; 01869 01870 /** default constructor. 01871 The maximum value for each RGB component defaults to 255. 01872 */ 01873 YPrimeUV2RGBPrimeFunctor() 01874 : max_(255.0) 01875 {} 01876 01877 /** constructor 01878 \arg max - the maximum value for each RGB component 01879 */ 01880 YPrimeUV2RGBPrimeFunctor(component_type max) 01881 : max_(max) 01882 {} 01883 01884 /** apply the transformation 01885 */ 01886 template <class V> 01887 result_type operator()(TinyVector<V, 3> const & yuv) const 01888 { 01889 component_type nred = yuv[0] + 1.140*yuv[2]; 01890 component_type ngreen = yuv[0] - 0.3946517044*yuv[1] - 0.580681431*yuv[2]; 01891 component_type nblue = yuv[0] + 2.0321100920*yuv[1]; 01892 return result_type(NumericTraits<T>::fromRealPromote(nred * max_), 01893 NumericTraits<T>::fromRealPromote(ngreen * max_), 01894 NumericTraits<T>::fromRealPromote(nblue * max_)); 01895 } 01896 }; 01897 01898 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color difference components. 01899 01900 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01901 Namespace: vigra 01902 01903 This functor basically applies the same transformation as vigra::RGBPrime2YPrimePbPrFunctor 01904 but the color components are scaled so that they can be coded as 8 bit intergers with 01905 minimal loss of information: 01906 01907 \f[ 01908 \begin{array}{rcl} 01909 16\leq & Y' & \leq 235 \\ 01910 16 \leq & Cb & \leq 240 \\ 01911 16 \leq & Cr & \leq 240 01912 \end{array} 01913 \f] 01914 */ 01915 template <class T> 01916 class RGBPrime2YPrimeCbCrFunctor 01917 { 01918 /* 01919 Y in [16, 235] 01920 Cb in [16, 240] 01921 Cr in [16, 240] 01922 maximum saturation: 119.591 01923 red = [81.481, 90.203, 240] 01924 */ 01925 public: 01926 01927 /** the result's component type 01928 */ 01929 typedef typename NumericTraits<T>::RealPromote component_type; 01930 01931 /** the functor's argument type 01932 */ 01933 typedef TinyVector<T, 3> argument_type; 01934 01935 /** the functor's result type 01936 */ 01937 typedef TinyVector<component_type, 3> result_type; 01938 01939 /** \deprecated use argument_type and result_type 01940 */ 01941 typedef TinyVector<component_type, 3> value_type; 01942 01943 /** default constructor. 01944 The maximum value for each RGB component defaults to 255. 01945 */ 01946 RGBPrime2YPrimeCbCrFunctor() 01947 : max_(255.0) 01948 {} 01949 01950 /** constructor 01951 \arg max - the maximum value for each RGB component 01952 */ 01953 RGBPrime2YPrimeCbCrFunctor(component_type max) 01954 : max_(max) 01955 {} 01956 01957 /** apply the transformation 01958 */ 01959 result_type operator()(TinyVector<T, 3> const & rgb) const 01960 { 01961 component_type red = rgb[0] / max_; 01962 component_type green = rgb[1] / max_; 01963 component_type blue = rgb[2] / max_; 01964 01965 result_type result; 01966 result[0] = 16.0 + 65.481*red + 128.553*green + 24.966*blue; 01967 result[1] = 128.0 - 37.79683972*red - 74.20316028*green + 112.0*blue; 01968 result[2] = 128.0 + 112.0*red - 93.78601998*green - 18.21398002*blue; 01969 return result; 01970 } 01971 01972 private: 01973 component_type max_; 01974 }; 01975 01976 /** \brief Convert Y'CbCr color difference components into non-linear (gamma corrected) R'G'B'. 01977 01978 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 01979 Namespace: vigra 01980 01981 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeCbCrFunctor 01982 */ 01983 template <class T> 01984 class YPrimeCbCr2RGBPrimeFunctor 01985 { 01986 typedef typename NumericTraits<T>::RealPromote component_type; 01987 01988 component_type max_; 01989 01990 public: 01991 01992 /** the functor's argument type. (Actually, the argument type 01993 is more general: <TT>TinyVector<V, 3></TT> with arbitrary 01994 <TT>V</TT>. But this cannot be expressed in a typedef.) 01995 */ 01996 typedef TinyVector<T, 3> argument_type; 01997 01998 /** the functor's result type 01999 */ 02000 typedef RGBValue<T> result_type; 02001 02002 /** \deprecated use argument_type and result_type 02003 */ 02004 typedef RGBValue<T> value_type; 02005 02006 /** default constructor. 02007 The maximum value for each RGB component defaults to 255. 02008 */ 02009 YPrimeCbCr2RGBPrimeFunctor() 02010 : max_(255.0) 02011 {} 02012 02013 /** constructor 02014 \arg max - the maximum value for each RGB component 02015 */ 02016 YPrimeCbCr2RGBPrimeFunctor(component_type max) 02017 : max_(max) 02018 {} 02019 02020 /** apply the transformation 02021 */ 02022 template <class V> 02023 result_type operator()(TinyVector<V, 3> const & ycbcr) const 02024 { 02025 component_type y = ycbcr[0] - 16.0; 02026 component_type cb = ycbcr[1] - 128.0; 02027 component_type cr = ycbcr[2] - 128.0; 02028 02029 component_type nred = 0.00456621*y + 0.006258928571*cr; 02030 component_type ngreen = 0.00456621*y - 0.001536322706*cb - 0.003188108420*cr; 02031 component_type nblue = 0.00456621*y + 0.007910714286*cb; 02032 return result_type(NumericTraits<T>::fromRealPromote(nred * max_), 02033 NumericTraits<T>::fromRealPromote(ngreen * max_), 02034 NumericTraits<T>::fromRealPromote(nblue * max_)); 02035 } 02036 }; 02037 02038 /* 02039 Polar coordinates of standard colors: 02040 ===================================== 02041 02042 Lab: black = [320.002, 0, 0] 02043 Luv: black = [347.827, 0, 0] 02044 YPbPr: black = [341.352, 0, 0] 02045 YCbCr: black = [341.352, 0, 0] 02046 YIQ: black = [19.5807, 0, 0] 02047 YUV: black = [346.557, 0, 0] 02048 Lab: red = [1.20391e-05, 0.532406, 0.781353] 02049 Luv: red = [360, 0.532406, 1] 02050 YPbPr: red = [360, 0.299, 0.988419] 02051 YCbCr: red = [360, 0.299, 0.988417] 02052 YIQ: red = [360, 0.299, 1] 02053 YUV: red = [360, 0.299, 1] 02054 Lab: green = [96.0184, 0.877351, 0.895108] 02055 Luv: green = [115.552, 0.877351, 0.758352] 02056 YPbPr: green = [123.001, 0.587, 1] 02057 YCbCr: green = [123.001, 0.587, 0.999996] 02058 YIQ: green = [137.231, 0.587, 0.933362] 02059 YUV: green = [137.257, 0.587, 0.933931] 02060 Lab: blue = [266.287, 0.322957, 0.999997] 02061 Luv: blue = [253.7, 0.322957, 0.729883] 02062 YPbPr: blue = [242.115, 0.114, 0.948831] 02063 YCbCr: blue = [242.115, 0.114, 0.948829] 02064 YIQ: blue = [243.585, 0.114, 0.707681] 02065 YUV: blue = [243.639, 0.114, 0.707424] 02066 Lab: yellow = [62.8531, 0.971395, 0.724189] 02067 Luv: yellow = [73.7, 0.971395, 0.597953] 02068 YPbPr: yellow = [62.1151, 0.886, 0.948831] 02069 YCbCr: yellow = [62.1149, 0.886, 0.948829] 02070 YIQ: yellow = [63.5851, 0.886, 0.707681] 02071 YUV: yellow = [63.6393, 0.886, 0.707424] 02072 Lab: magenta = [288.237, 0.603235, 0.863482] 02073 Luv: magenta = [295.553, 0.603235, 0.767457] 02074 YPbPr: magenta = [303.001, 0.413, 1] 02075 YCbCr: magenta = [303.001, 0.413, 0.999996] 02076 YIQ: magenta = [317.231, 0.413, 0.933362] 02077 YUV: magenta = [317.257, 0.413, 0.933931] 02078 Lab: cyan = [156.378, 0.911133, 0.374577] 02079 Luv: cyan = [180, 0.911133, 0.402694] 02080 YPbPr: cyan = [180, 0.701, 0.988419] 02081 YCbCr: cyan = [180, 0.701, 0.988417] 02082 YIQ: cyan = [180, 0.701, 1] 02083 YUV: cyan = [180, 0.701, 1] 02084 Lab: white = [320.002, 1, 0] 02085 Luv: white = [14.3606, 1, 3.26357e-06] 02086 YPbPr: white = [341.352, 1, 0] 02087 YCbCr: white = [341.352, 1, 0] 02088 YIQ: white = [154.581, 1, 1.24102e-16] 02089 YUV: white = [229.992, 1, 9.81512e-17] 02090 02091 */ 02092 02093 /** \addtogroup PolarColors Polar Color Coordinates 02094 02095 Transform colors from/to a polar representation (hue, brighness, saturation). 02096 In many situations, this is more inituitive than direct initialization in a 02097 particular color space. The polar coordinates are 02098 normalized so that a color angle of 0 degrees is always associated with red 02099 (green is at about 120 degrees, blue at about 240 degrees - exact values differ 02100 between color spaces). A saturation of 1 is the highest saturation that any RGB color 02101 gets after transformation into the respective color space, and saturation 0 corresponds to 02102 gray. Thus, different color spaces become somewhat comparable. 02103 */ 02104 //@{ 02105 /** \brief Init L*a*b* color triple from polar representation. 02106 02107 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02108 Namespace: vigra 02109 02110 <b> Declarations:</b> 02111 02112 \code 02113 TinyVector<float, 3> 02114 polar2Lab(double color, double brightness, double saturation); 02115 02116 TinyVector<float, 3> 02117 polar2Lab(TinyVector<float, 3> const & polar); 02118 \endcode 02119 02120 \arg color - the color angle in degrees 02121 \arg brightness - between 0 and 1 02122 \arg saturation - between 0 and 1 02123 02124 L*a*b* polar coordinates of some important colors: 02125 02126 \code 02127 black = [*, 0, 0] * - arbitrary 02128 white = [*, 1, 0] * - arbitrary 02129 02130 red = [ 0, 0.532406, 0.781353] 02131 yellow = [62.8531, 0.971395, 0.724189] 02132 green = [96.0184, 0.877351, 0.895108] 02133 cyan = [156.378, 0.911133, 0.374577] 02134 blue = [266.287, 0.322957, 0.999997] 02135 magenta = [288.237, 0.603235, 0.863482] 02136 \endcode 02137 */ 02138 inline TinyVector<float, 3> 02139 polar2Lab(double color, double brightness, double saturation) 02140 { 02141 double angle = (color+39.9977)/180.0*M_PI; 02142 double normsat = saturation*133.809; 02143 02144 TinyVector<float, 3> result; 02145 result[0] = 100.0*brightness; 02146 result[1] = normsat*VIGRA_CSTD::cos(angle); 02147 result[2] = normsat*VIGRA_CSTD::sin(angle); 02148 return result; 02149 } 02150 02151 inline TinyVector<float, 3> 02152 polar2Lab(TinyVector<float, 3> const & polar) 02153 { 02154 return polar2Lab(polar[0], polar[1], polar[2]); 02155 } 02156 02157 /** \brief Create polar representation form L*a*b* 02158 02159 <b> Declaration:</b> 02160 02161 \code 02162 namespace vigra { 02163 TinyVector<float, 3> lab2Polar(TinyVector<float, 3> const & lab); 02164 } 02165 \endcode 02166 02167 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02168 Namespace: vigra 02169 02170 This realizes the inverse of the transformation described in 02171 \link PolarColors#polar2Lab polar2Lab\endlink(). 02172 */ 02173 inline TinyVector<float, 3> 02174 lab2Polar(TinyVector<float, 3> const & lab) 02175 { 02176 TinyVector<float, 3> result; 02177 result[1] = lab[0]/100.0; 02178 double angle = VIGRA_CSTD::atan2(lab[2], lab[1])/M_PI*180.0-39.9977; 02179 result[0] = angle < 0.0 ? 02180 angle + 360.0 : 02181 angle; 02182 result[2] = VIGRA_CSTD::sqrt(lab[1]*lab[1] + lab[2]*lab[2])/133.809; 02183 return result; 02184 } 02185 02186 /** \brief Init L*u*v* color triple from polar representation. 02187 02188 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02189 Namespace: vigra 02190 02191 <b> Declarations:</b> 02192 02193 \code 02194 TinyVector<float, 3> 02195 polar2Luv(double color, double brightness, double saturation); 02196 02197 TinyVector<float, 3> 02198 polar2Luv(TinyVector<float, 3> const & polar); 02199 \endcode 02200 02201 \arg color - the color angle in degrees 02202 \arg brightness - between 0 and 1 02203 \arg saturation - between 0 and 1 02204 02205 L*u*v* polar coordinates of some important colors: 02206 02207 \code 02208 black = [*, 0, 0] * - arbitrary 02209 white = [*, 1, 0] * - arbitrary 02210 02211 red = [ 0, 0.532406, 1] 02212 yellow = [ 73.7, 0.971395, 0.597953] 02213 green = [115.552, 0.877351, 0.758352] 02214 cyan = [ 180.0, 0.911133, 0.402694] 02215 blue = [ 253.7, 0.322957, 0.729883] 02216 magenta = [295.553, 0.603235, 0.767457] 02217 \endcode 02218 */ 02219 inline TinyVector<float, 3> 02220 polar2Luv(double color, double brightness, double saturation) 02221 { 02222 double angle = (color+12.1727)/180.0*M_PI; 02223 double normsat = saturation*179.04; 02224 02225 TinyVector<float, 3> result; 02226 result[0] = 100.0*brightness; 02227 result[1] = normsat*VIGRA_CSTD::cos(angle); 02228 result[2] = normsat*VIGRA_CSTD::sin(angle); 02229 return result; 02230 } 02231 02232 inline TinyVector<float, 3> 02233 polar2Luv(TinyVector<float, 3> const & polar) 02234 { 02235 return polar2Luv(polar[0], polar[1], polar[2]); 02236 } 02237 02238 /** \brief Create polar representation form L*u*v* 02239 02240 <b> Declaration:</b> 02241 02242 \code 02243 namespace vigra { 02244 TinyVector<float, 3> luv2Polar(TinyVector<float, 3> const & luv); 02245 } 02246 \endcode 02247 02248 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02249 Namespace: vigra 02250 02251 This realizes the inverse of the transformation described in 02252 \link PolarColors#polar2Luv polar2Luv\endlink(). 02253 */ 02254 inline TinyVector<float, 3> 02255 luv2Polar(TinyVector<float, 3> const & luv) 02256 { 02257 TinyVector<float, 3> result; 02258 result[1] = luv[0]/100.0; 02259 double angle = VIGRA_CSTD::atan2(luv[2], luv[1])/M_PI*180.0-12.1727; 02260 result[0] = angle < 0.0 ? 02261 angle + 360.0 : 02262 angle; 02263 result[2] = VIGRA_CSTD::sqrt(luv[1]*luv[1] + luv[2]*luv[2])/179.04; 02264 return result; 02265 } 02266 02267 /** \brief Init Y'PbPr color triple from polar representation. 02268 02269 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02270 Namespace: vigra 02271 02272 <b> Declarations:</b> 02273 02274 \code 02275 TinyVector<float, 3> 02276 polar2YPrimePbPr(double color, double brightness, double saturation); 02277 02278 TinyVector<float, 3> 02279 polar2YPrimePbPr(TinyVector<float, 3> const & polar); 02280 \endcode 02281 02282 \arg color - the color angle in degrees 02283 \arg brightness - between 0 and 1 02284 \arg saturation - between 0 and 1 02285 02286 Y'PbPr polar coordinates of some important colors: 02287 02288 \code 02289 black = [*, 0, 0] * - arbitrary 02290 white = [*, 1, 0] * - arbitrary 02291 02292 red = [ 0, 0.299, 0.988419] 02293 yellow = [62.1151, 0.886, 0.948831] 02294 green = [123.001, 0.587, 1] 02295 cyan = [ 180.0, 0.701, 0.988419] 02296 blue = [242.115, 0.114, 0.948831] 02297 magenta = [303.001, 0.413, 1] 02298 \endcode 02299 */ 02300 inline TinyVector<float, 3> 02301 polar2YPrimePbPr(double color, double brightness, double saturation) 02302 { 02303 double angle = (color+18.6481)/180.0*M_PI; 02304 double normsat = saturation*0.533887; 02305 02306 TinyVector<float, 3> result; 02307 result[0] = brightness; 02308 result[1] = -normsat*VIGRA_CSTD::sin(angle); 02309 result[2] = normsat*VIGRA_CSTD::cos(angle); 02310 return result; 02311 } 02312 02313 inline TinyVector<float, 3> 02314 polar2YPrimePbPr(TinyVector<float, 3> const & polar) 02315 { 02316 return polar2YPrimePbPr(polar[0], polar[1], polar[2]); 02317 } 02318 02319 /** \brief Create polar representation form Y'PbPr 02320 02321 <b> Declaration:</b> 02322 02323 \code 02324 namespace vigra { 02325 TinyVector<float, 3> yPrimePbPr2Polar(TinyVector<float, 3> const & ypbpr); 02326 } 02327 \endcode 02328 02329 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02330 Namespace: vigra 02331 02332 This realizes the inverse of the transformation described in 02333 \link PolarColors#polar2YPrimePbPr polar2YPrimePbPr\endlink(). 02334 */ 02335 inline TinyVector<float, 3> 02336 yPrimePbPr2Polar(TinyVector<float, 3> const & ypbpr) 02337 { 02338 TinyVector<float, 3> result; 02339 result[1] = ypbpr[0]; 02340 double angle = VIGRA_CSTD::atan2(-ypbpr[1], ypbpr[2])/M_PI*180.0-18.6481; 02341 result[0] = angle < 0.0 ? 02342 angle + 360.0 : 02343 angle; 02344 result[2] = VIGRA_CSTD::sqrt(ypbpr[1]*ypbpr[1] + ypbpr[2]*ypbpr[2])/0.533887; 02345 return result; 02346 } 02347 02348 /** \brief Init Y'CbCr color triple from polar representation. 02349 02350 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02351 Namespace: vigra 02352 02353 <b> Declarations:</b> 02354 02355 \code 02356 TinyVector<float, 3> 02357 polar2YPrimeCbCr(double color, double brightness, double saturation); 02358 02359 TinyVector<float, 3> 02360 polar2YPrimeCbCr(TinyVector<float, 3> const & polar); 02361 \endcode 02362 02363 \arg color - the color angle in degrees 02364 \arg brightness - between 0 and 1 02365 \arg saturation - between 0 and 1 02366 02367 Y'CbCr polar coordinates of some important colors: 02368 02369 \code 02370 black = [*, 0, 0] * - arbitrary 02371 white = [*, 1, 0] * - arbitrary 02372 02373 red = [ 0, 0.299, 0.988419] 02374 yellow = [62.1151, 0.886, 0.948831] 02375 green = [123.001, 0.587, 1] 02376 cyan = [ 180.0, 0.701, 0.988419] 02377 blue = [242.115, 0.114, 0.948831] 02378 magenta = [303.001, 0.413, 1] 02379 \endcode 02380 */ 02381 inline TinyVector<float, 3> 02382 polar2YPrimeCbCr(double color, double brightness, double saturation) 02383 { 02384 double angle = (color+18.6482)/180.0*M_PI; 02385 double normsat = saturation*119.591; 02386 02387 TinyVector<float, 3> result; 02388 result[0] = brightness*219.0 + 16.0; 02389 result[1] = -normsat*VIGRA_CSTD::sin(angle)+128.0; 02390 result[2] = normsat*VIGRA_CSTD::cos(angle)+128.0; 02391 return result; 02392 } 02393 02394 inline TinyVector<float, 3> 02395 polar2YPrimeCbCr(TinyVector<float, 3> const & polar) 02396 { 02397 return polar2YPrimeCbCr(polar[0], polar[1], polar[2]); 02398 } 02399 02400 /** \brief Create polar representation form Y'CbCr 02401 02402 <b> Declaration:</b> 02403 02404 \code 02405 namespace vigra { 02406 TinyVector<float, 3> yPrimeCbCr2Polar(TinyVector<float, 3> const & ycbcr); 02407 } 02408 \endcode 02409 02410 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02411 Namespace: vigra 02412 02413 This realizes the inverse of the transformation described in 02414 \link PolarColors#polar2YPrimeCbCr polar2YPrimeCbCr\endlink(). 02415 */ 02416 inline TinyVector<float, 3> 02417 yPrimeCbCr2Polar(TinyVector<float, 3> const & ycbcr) 02418 { 02419 TinyVector<float, 3> result; 02420 result[1] = (ycbcr[0]-16.0)/219.0; 02421 double cb = ycbcr[1]-128.0; 02422 double cr = ycbcr[2]-128.0; 02423 double angle = VIGRA_CSTD::atan2(-cb, cr)/M_PI*180.0-18.6482; 02424 result[0] = angle < 0.0 ? 02425 angle + 360.0 : 02426 angle; 02427 result[2] = VIGRA_CSTD::sqrt(cb*cb + cr*cr)/119.591; 02428 return result; 02429 } 02430 02431 /** \brief Init Y'IQ color triple from polar representation. 02432 02433 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02434 Namespace: vigra 02435 02436 <b> Declarations:</b> 02437 02438 \code 02439 TinyVector<float, 3> 02440 polar2YPrimeIQ(double color, double brightness, double saturation); 02441 02442 TinyVector<float, 3> 02443 polar2YPrimeIQ(TinyVector<float, 3> const & polar); 02444 \endcode 02445 02446 \arg color - the color angle in degrees 02447 \arg brightness - between 0 and 1 02448 \arg saturation - between 0 and 1 02449 02450 Y'IQ polar coordinates of some important colors: 02451 02452 \code 02453 black = [*, 0, 0] * - arbitrary 02454 white = [*, 1, 0] * - arbitrary 02455 02456 red = [ 0, 0.299, 1] 02457 yellow = [63.5851, 0.886, 0.707681] 02458 green = [137.231, 0.587, 0.933362] 02459 cyan = [ 180.0, 0.701, 1] 02460 blue = [243.585, 0.114, 0.707681] 02461 magenta = [317.231, 0.413, 0.933362] 02462 \endcode 02463 */ 02464 inline TinyVector<float, 3> 02465 polar2YPrimeIQ(double color, double brightness, double saturation) 02466 { 02467 double angle = (color-19.5807)/180.0*M_PI; 02468 double normsat = saturation*0.632582; 02469 02470 TinyVector<float, 3> result; 02471 result[0] = brightness; 02472 result[1] = normsat*VIGRA_CSTD::cos(angle); 02473 result[2] = -normsat*VIGRA_CSTD::sin(angle); 02474 return result; 02475 } 02476 02477 inline TinyVector<float, 3> 02478 polar2YPrimeIQ(TinyVector<float, 3> const & polar) 02479 { 02480 return polar2YPrimeIQ(polar[0], polar[1], polar[2]); 02481 } 02482 02483 /** \brief Create polar representation form Y'IQ 02484 02485 <b> Declaration:</b> 02486 02487 \code 02488 namespace vigra { 02489 TinyVector<float, 3> yPrimeIQ2Polar(TinyVector<float, 3> const & yiq); 02490 } 02491 \endcode 02492 02493 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02494 Namespace: vigra 02495 02496 This realizes the inverse of the transformation described in 02497 \link PolarColors#polar2YPrimeIQ polar2YPrimeIQ\endlink(). 02498 */ 02499 inline TinyVector<float, 3> 02500 yPrimeIQ2Polar(TinyVector<float, 3> const & yiq) 02501 { 02502 TinyVector<float, 3> result; 02503 result[1] = yiq[0]; 02504 double angle = VIGRA_CSTD::atan2(-yiq[2], yiq[1])/M_PI*180.0+19.5807; 02505 result[0] = angle < 0.0 ? 02506 angle + 360.0 : 02507 angle; 02508 result[2] = VIGRA_CSTD::sqrt(yiq[1]*yiq[1] + yiq[2]*yiq[2])/0.632582; 02509 return result; 02510 } 02511 02512 /** \brief Init Y'UV color triple from polar representation. 02513 02514 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02515 Namespace: vigra 02516 02517 <b> Declarations:</b> 02518 02519 \code 02520 TinyVector<float, 3> 02521 polar2YPrimeUV(double color, double brightness, double saturation); 02522 02523 TinyVector<float, 3> 02524 polar2YPrimeUV(TinyVector<float, 3> const & polar); 02525 \endcode 02526 02527 \arg color - the color angle in degrees 02528 \arg brightness - between 0 and 1 02529 \arg saturation - between 0 and 1 02530 02531 Y'UV polar coordinates of some important colors: 02532 02533 \code 02534 black = [*, 0, 0] * - arbitrary 02535 white = [*, 1, 0] * - arbitrary 02536 02537 red = [ 0, 0.299, 1] 02538 yellow = [63.5851, 0.886, 0.707681] 02539 green = [137.231, 0.587, 0.933362] 02540 cyan = [ 180.0, 0.701, 1] 02541 blue = [243.585, 0.114, 0.707681] 02542 magenta = [317.231, 0.413, 0.933362] 02543 \endcode 02544 */ 02545 inline TinyVector<float, 3> 02546 polar2YPrimeUV(double color, double brightness, double saturation) 02547 { 02548 double angle = (color+13.4569)/180.0*M_PI; 02549 double normsat = saturation*0.632324; 02550 02551 TinyVector<float, 3> result; 02552 result[0] = brightness; 02553 result[1] = -normsat*VIGRA_CSTD::sin(angle); 02554 result[2] = normsat*VIGRA_CSTD::cos(angle); 02555 return result; 02556 } 02557 02558 inline TinyVector<float, 3> 02559 polar2YPrimeUV(TinyVector<float, 3> const & polar) 02560 { 02561 return polar2YPrimeUV(polar[0], polar[1], polar[2]); 02562 } 02563 02564 /** \brief Create polar representation form Y'UV 02565 02566 <b> Declaration:</b> 02567 02568 \code 02569 namespace vigra { 02570 TinyVector<float, 3> yPrimeUV2Polar(TinyVector<float, 3> const & yuv); 02571 } 02572 \endcode 02573 02574 <b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>"<br> 02575 Namespace: vigra 02576 02577 This realizes the inverse of the transformation described in 02578 \link PolarColors#polar2YPrimeUV polar2YPrimeUV\endlink(). 02579 */ 02580 inline TinyVector<float, 3> 02581 yPrimeUV2Polar(TinyVector<float, 3> const & yuv) 02582 { 02583 TinyVector<float, 3> result; 02584 result[1] = yuv[0]; 02585 double angle = VIGRA_CSTD::atan2(-yuv[1], yuv[2])/M_PI*180.0-13.4569; 02586 result[0] = angle < 0.0 ? 02587 angle + 360.0 : 02588 angle; 02589 result[2] = VIGRA_CSTD::sqrt(yuv[1]*yuv[1] + yuv[2]*yuv[2])/0.632324; 02590 return result; 02591 } 02592 02593 //@} 02594 02595 } // namespace vigra 02596 02597 #endif /* VIGRA_COLORCONVERSIONS_HXX */
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|