1 /************************************************************************/
3 /* Copyright 1998-2002 by Ullrich Koethe */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
34 /************************************************************************/
37 #ifndef VIGRA_COLORCONVERSIONS_HXX
38 #define VIGRA_COLORCONVERSIONS_HXX
41 #include "mathutil.hxx"
42 #include "rgbvalue.hxx"
43 #include "functortraits.hxx"
50 template<class ValueType>
51 inline ValueType gammaCorrection(double value, double gamma)
53 typedef typename NumericTraits<ValueType>::RealPromote Promote;
54 return NumericTraits<ValueType>::fromRealPromote(
55 RequiresExplicitCast<Promote>::cast(
57 ? -std::pow(-value, gamma)
58 : std::pow(value, gamma)));
61 template<class ValueType>
62 inline ValueType gammaCorrection(double value, double gamma, double norm)
64 typedef typename NumericTraits<ValueType>::RealPromote Promote;
65 return NumericTraits<ValueType>::fromRealPromote(
66 RequiresExplicitCast<Promote>::cast(
68 ? -norm*std::pow(-value/norm, gamma)
69 : norm*std::pow(value/norm, gamma)));
72 template<class ValueType>
73 inline ValueType sRGBCorrection(double value, double norm)
76 typedef typename NumericTraits<ValueType>::RealPromote Promote;
77 return NumericTraits<ValueType>::fromRealPromote(
78 RequiresExplicitCast<ValueType>::cast(
81 : norm*(1.055*std::pow(value, 0.41666666666666667) - 0.055)));
84 template<class ValueType>
85 inline ValueType inverse_sRGBCorrection(double value, double norm)
88 typedef typename NumericTraits<ValueType>::RealPromote Promote;
89 return NumericTraits<ValueType>::fromRealPromote(
90 RequiresExplicitCast<ValueType>::cast(
93 : norm*VIGRA_CSTD::pow((value + 0.055)/1.055, 2.4)));
99 /** \defgroup ColorConversions Color Space Conversions
101 Convert between RGB, sRGB, R'G'B', XYZ, L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV color spaces.
103 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
107 <LI> <b>RGB/sRGB/R'G'B'</b><br>
108 <em>linear and non-linear (gamma corrected) additive color</em>
110 <UL style="list-style-image:url(documents/bullet.gif)">
111 <LI> \ref vigra::RGB2sRGBFunctor
112 <LI> \ref vigra::sRGB2RGBFunctor
113 <LI> \ref vigra::RGB2RGBPrimeFunctor
114 <LI> \ref vigra::RGBPrime2RGBFunctor
117 <em>device independent color representation
118 (according to Publication CIE No 15.2 "Colorimetry"
119 and ITU-R Recommendation BT.709)</em>
121 <UL style="list-style-image:url(documents/bullet.gif)">
122 <LI> \ref vigra::RGB2XYZFunctor
123 <LI> \ref vigra::RGBPrime2XYZFunctor
124 <LI> \ref vigra::XYZ2RGBFunctor
125 <LI> \ref vigra::XYZ2RGBPrimeFunctor
127 <LI> <b>L*a*b* </b><br>
128 <em>perceptually uniform color representation
129 (according to Publication CIE No 15.2 "Colorimetry" and
130 ITU-R Recommendation BT.709)</em>
132 <UL style="list-style-image:url(documents/bullet.gif)">
133 <LI> \ref vigra::RGB2LabFunctor
134 <LI> \ref vigra::RGBPrime2LabFunctor
135 <LI> \ref vigra::XYZ2LabFunctor
136 <LI> \ref vigra::Lab2RGBFunctor
137 <LI> \ref vigra::Lab2RGBPrimeFunctor
138 <LI> \ref vigra::Lab2XYZFunctor
139 <LI> \ref polar2Lab()
140 <LI> \ref lab2Polar()
142 <LI> <b>L*u*v* </b><br>
143 <em>perceptually uniform color representation
144 (according to Publication CIE No 15.2 "Colorimetry" and
145 ITU-R Recommendation BT.709)</em>
147 <UL style="list-style-image:url(documents/bullet.gif)">
148 <LI> \ref vigra::RGB2LuvFunctor
149 <LI> \ref vigra::RGBPrime2LuvFunctor
150 <LI> \ref vigra::XYZ2LuvFunctor
151 <LI> \ref vigra::Luv2RGBFunctor
152 <LI> \ref vigra::Luv2RGBPrimeFunctor
153 <LI> \ref vigra::Luv2XYZFunctor
154 <LI> \ref polar2Luv()
155 <LI> \ref luv2Polar()
157 <LI> <b>Y'PbPr and Y'CbCr </b><br>
158 <em>color difference coding
159 (according to ITU-R Recommendation BT. 601)</em>
161 <UL style="list-style-image:url(documents/bullet.gif)">
162 <LI> \ref vigra::RGBPrime2YPrimePbPrFunctor
163 <LI> \ref vigra::YPrimePbPr2RGBPrimeFunctor
164 <LI> \ref polar2YPrimePbPr()
165 <LI> \ref yPrimePbPr2Polar()
166 <LI> \ref vigra::RGBPrime2YPrimeCbCrFunctor
167 <LI> \ref vigra::YPrimeCbCr2RGBPrimeFunctor
168 <LI> \ref polar2YPrimeCbCr()
169 <LI> \ref yPrimeCbCr2Polar()
171 <LI> <b>Y'UV and Y'IQ </b><br>
172 <em>analog video coding according to NTSC and PAL standards</em>
174 <UL style="list-style-image:url(documents/bullet.gif)">
175 <LI> \ref vigra::RGBPrime2YPrimeUVFunctor
176 <LI> \ref vigra::YPrimeUV2RGBPrimeFunctor
177 <LI> \ref polar2YPrimeUV()
178 <LI> \ref yPrimeUV2Polar()
179 <LI> \ref vigra::RGBPrime2YPrimeIQFunctor
180 <LI> \ref vigra::YPrimeIQ2RGBPrimeFunctor
181 <LI> \ref polar2YPrimeIQ()
182 <LI> \ref yPrimeIQ2Polar()
187 This module provides conversion from RGB/R'G'B' into more perceptually uniform
188 color spaces. In image analysis, colors are usually converted into another color space
189 in order to get good estimates of perceived color differences by just calculating
190 Euclidean distances between the transformed colors. The L*a*b* and L*u*v* were
191 designed with exactly this application in mind and thus give the best results. But these
192 conversions are also the most computationally demanding. The Y'PbPr color difference
193 space (designed for coding digital video) is computationally much cheaper, and
194 almost as good. Y'CbCr represents esentially the same transformation, but the color values
195 are scaled so that they can be stored with 8 bits per channel with minimal loss of
196 information. The other transformations are of lesser interest here: XYZ is a device independent
197 (but not perceptually uniform) color representation, and Y'IQ and Y'UV are the color
198 spaces used by the PAL and NTSC analog video standards. Detailed information about
199 these color spaces and their transformations can be found in
200 <a href="http://www.poynton.com/ColorFAQ.html">Charles Poynton's Color FAQ</a>
202 When you want to perform a color conversion, you must first know in which
203 color space the data are given. Although this sounds trivial, it is
204 quite often done wrong, because the distinction between RGB and sRGB (still images) or R'G'B'
205 (digital video) is frequently overlooked: nowadays, most still images are stored in
206 sRGB space, and treating them as RGB leads to wrong results (although the color primaries
207 are named the same). RGB and R'G'B' are related by a so called <em>gamma correction</em>:
210 C' = C_{max} \left(\frac{C_{RGB}}{C_{max}} \right)^{0.45} \qquad
213 where C represents one of the color channels R, G, and B, and \f$ C_{max} \f$ usually equals 255.
214 The sRGB color space realizes a slight enhancement of this definition:
217 C_{sRGB} = \left\{\begin{array}{ll}
218 12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.00304 \\
219 C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.055\right) & \textrm{ otherwise}
223 sRGB has now become a widely accepted international standard (IEC 61966-2.1) which is used by most
224 consumer products (digital cameras, printers, and screens). In practice, you can
225 distinguish between linear and gamma-corrected red, green, and blue by displaying the images: if they look
226 too dark, they are probably RGB, if they are OK, they are likely sRGB. (However, there are still a few older
227 graphics cards and display programs which silently apply an additional gamma correction to every image,
228 so that RGB appears correct and sRGB is too bright.) Whether or not the data are represented
229 in the sRGB color space can also be seen in the color space tag of an image's EXIF data, if available.
231 The distinction between RGB and R'G'B' is important because some conversions start at
232 RGB (XYZ, L*a*b*, L*u*v*), while others start at R'G'B' (Y'PbPr, Y'CbCr, Y'IQ, and Y'UV).
233 The names of VIGRA's color conversion functors always make clear to which color space
234 they must be applied.
236 In addition VIGRA provides a <em>\ref PolarColors "polar coordinate interface"</em>
237 to several color spaces (L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV). This
238 interface makes use of the fact that these color spaces are conceptually similar:
239 they represent colors by a "brightness" coordinate (L* or Y') and a pair of
240 "chromaticity" coordinates that span a plane of colors with equal brightness.
241 The polar representation transforms chroma coordinates into a color "angle"
242 (similar to hue in the HSV system) and a "saturation". The polar coordinates are
243 normalized so that a color angle of 0 degrees is always associated with red
244 (green is at about 120 degrees, blue at about 240 degrees - exact values differ
245 between color spaces). A saturation of 1 is the highest saturation that any RGB color
246 in the unit cube can have after transformation into the respective color space,
247 and saturation 0 corresponds to gray. Polar coordinates provide a more intuitive
248 interface to color specification by users and make different color spaces somewhat
254 /** \brief Convert linear (raw) RGB into non-linear (gamma corrected) R'G'B'.
256 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
259 The functor realizes the transformation
262 R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad
263 G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad
264 B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45}
267 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
268 in the constructor. If both source and target colors components are stored
269 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
271 <b> Traits defined:</b>
273 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
275 template <class From, class To = From>
276 class RGB2RGBPrimeFunctor
280 /** the functor's argument type
282 typedef TinyVector<From, 3> argument_type;
284 /** the functor's result type
286 typedef TinyVector<To, 3> result_type;
288 /** \deprecated use argument_type and result_type
290 typedef TinyVector<To, 3> value_type;
292 /** the result component's promote type
294 typedef typename NumericTraits<To>::RealPromote component_type;
296 /** Default constructor.
297 The maximum value for each RGB component defaults to 255
299 RGB2RGBPrimeFunctor()
304 \arg max - the maximum value for each RGB component
306 RGB2RGBPrimeFunctor(component_type max)
310 /** apply the transformation
313 result_type operator()(V const & rgb) const
315 return TinyVector<To, 3>(
316 detail::gammaCorrection<To>(rgb[0], 0.45, max_),
317 detail::gammaCorrection<To>(rgb[1], 0.45, max_),
318 detail::gammaCorrection<To>(rgb[2], 0.45, max_));
326 class RGB2RGBPrimeFunctor<unsigned char, unsigned char>
328 unsigned char lut_[256];
332 typedef TinyVector<unsigned char, 3> argument_type;
334 typedef TinyVector<unsigned char, 3> result_type;
336 typedef TinyVector<unsigned char, 3> value_type;
338 RGB2RGBPrimeFunctor()
340 for(int i=0; i<256; ++i)
342 lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, 255.0);
346 RGB2RGBPrimeFunctor(double max)
348 for(int i=0; i<256; ++i)
350 lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, max);
355 TinyVector<unsigned char, 3> operator()(V const & rgb) const
357 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
361 template <class From, class To>
362 class FunctorTraits<RGB2RGBPrimeFunctor<From, To> >
363 : public FunctorTraitsBase<RGB2RGBPrimeFunctor<From, To> >
366 typedef VigraTrueType isUnaryFunctor;
369 /** \brief Convert linear (raw) RGB into standardized sRGB.
371 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
374 The sRGB color space is a slight improvement over the R'G'B' space. It is now a widely accepted
375 international standard (IEC 61966-2.1) which is used by most consumer products
376 (digital cameras, printers, and screens). The functor realizes the transformation
379 C_{sRGB} = \left\{ \begin{array}{ll}
380 12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.0031308 \\
381 C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.055\right) & \textrm{ otherwise}
385 where C is any of the primaries R, G, and B. By default, \f$ C_{max} = 255 \f$ (this default can be
386 overridden in the constructor). If both source and target color components are stored
387 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
389 <b> Traits defined:</b>
391 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
393 template <class From, class To = From>
394 class RGB2sRGBFunctor
398 /** the functor's argument type
400 typedef TinyVector<From, 3> argument_type;
402 /** the functor's result type
404 typedef TinyVector<To, 3> result_type;
406 /** \deprecated use argument_type and result_type
408 typedef TinyVector<To, 3> value_type;
410 /** the result component's promote type
412 typedef typename NumericTraits<To>::RealPromote component_type;
414 /** Default constructor.
415 The maximum value for each RGB component defaults to 255
422 \arg max - the maximum value for each RGB component
424 RGB2sRGBFunctor(component_type max)
428 /** apply the transformation
431 result_type operator()(V const & rgb) const
433 return TinyVector<To, 3>(
434 detail::sRGBCorrection<To>(rgb[0], max_),
435 detail::sRGBCorrection<To>(rgb[1], max_),
436 detail::sRGBCorrection<To>(rgb[2], max_));
444 class RGB2sRGBFunctor<unsigned char, unsigned char>
446 unsigned char lut_[256];
450 typedef TinyVector<unsigned char, 3> argument_type;
452 typedef TinyVector<unsigned char, 3> result_type;
454 typedef TinyVector<unsigned char, 3> value_type;
458 for(int i=0; i<256; ++i)
460 lut_[i] = detail::sRGBCorrection<unsigned char>(i, 255.0);
464 RGB2sRGBFunctor(double max)
466 for(int i=0; i<256; ++i)
468 lut_[i] = detail::sRGBCorrection<unsigned char>(i, max);
473 TinyVector<unsigned char, 3> operator()(V const & rgb) const
475 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
479 template <class From, class To>
480 class FunctorTraits<RGB2sRGBFunctor<From, To> >
481 : public FunctorTraitsBase<RGB2sRGBFunctor<From, To> >
484 typedef VigraTrueType isUnaryFunctor;
487 /** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw) RGB.
489 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
492 The functor realizes the transformation
495 R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad
496 G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad
497 B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45}
500 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
501 in the constructor. If both source and target color components are stored
502 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
504 <b> Traits defined:</b>
506 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
508 template <class From, class To = From>
509 class RGBPrime2RGBFunctor
513 /** the functor's argument type
515 typedef TinyVector<From, 3> argument_type;
517 /** the functor's result type
519 typedef TinyVector<To, 3> result_type;
521 /** \deprecated use argument_type and result_type
523 typedef TinyVector<To, 3> value_type;
525 /** the result component's promote type
527 typedef typename NumericTraits<To>::RealPromote component_type;
529 /** Default constructor.
530 The maximum value for each RGB component defaults to 255.
532 RGBPrime2RGBFunctor()
533 : max_(255.0), gamma_(1.0/0.45)
537 \arg max - the maximum value for each RGB component
539 RGBPrime2RGBFunctor(component_type max)
540 : max_(max), gamma_(1.0/0.45)
543 /** apply the transformation
545 result_type operator()(argument_type const & rgb) const
547 return TinyVector<To, 3>(
548 detail::gammaCorrection<To>(rgb[0], gamma_, max_),
549 detail::gammaCorrection<To>(rgb[1], gamma_, max_),
550 detail::gammaCorrection<To>(rgb[2], gamma_, max_));
559 class RGBPrime2RGBFunctor<unsigned char, unsigned char>
561 unsigned char lut_[256];
565 typedef TinyVector<unsigned char, 3> argument_type;
567 typedef TinyVector<unsigned char, 3> result_type;
569 typedef TinyVector<unsigned char, 3> value_type;
571 RGBPrime2RGBFunctor()
573 for(int i=0; i<256; ++i)
575 lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, 255.0);
579 RGBPrime2RGBFunctor(double max)
581 for(int i=0; i<256; ++i)
583 lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, max);
588 TinyVector<unsigned char, 3> operator()(V const & rgb) const
590 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
594 template <class From, class To>
595 class FunctorTraits<RGBPrime2RGBFunctor<From, To> >
596 : public FunctorTraitsBase<RGBPrime2RGBFunctor<From, To> >
599 typedef VigraTrueType isUnaryFunctor;
602 /** \brief Convert standardized sRGB into non-linear (raw) RGB.
604 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
607 The sRGB color space is a slight improvement over the R'G'B' space. Is is now a widely accepted
608 international standard (IEC 61966-2.1) which is used by most consumer products
609 (digital cameras, printers, and screens). The functor realizes the transformation
612 C_{RGB} = \left\{\begin{array}{ll}
613 C_{sRGB} / 12.92 & \textrm{if }\frac{C_{sRGB}}{C_{max}} \le 0.04045 \\
614 C_{max}\left( \frac{C_{sRGB}/C_{max}+0.055}{1.055}\right)^{2.4} & \textrm{otherwise}
618 where C is one of the color channels R, G, or B, and \f$ C_{max}\f$ equals 255 by default (This default
619 can be overridden in the constructor). If both source and target color components are stored
620 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
622 <b> Traits defined:</b>
624 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
626 template <class From, class To = From>
627 class sRGB2RGBFunctor
631 /** the functor's argument type
633 typedef TinyVector<From, 3> argument_type;
635 /** the functor's result type
637 typedef TinyVector<To, 3> result_type;
639 /** \deprecated use argument_type and result_type
641 typedef TinyVector<To, 3> value_type;
643 /** the result component's promote type
645 typedef typename NumericTraits<To>::RealPromote component_type;
647 /** Default constructor.
648 The maximum value for each RGB component defaults to 255.
655 \arg max - the maximum value for each RGB component
657 sRGB2RGBFunctor(component_type max)
661 /** apply the transformation
663 result_type operator()(argument_type const & rgb) const
665 return TinyVector<To, 3>(
666 detail::inverse_sRGBCorrection<To>(rgb[0], max_),
667 detail::inverse_sRGBCorrection<To>(rgb[1], max_),
668 detail::inverse_sRGBCorrection<To>(rgb[2], max_));
676 class sRGB2RGBFunctor<unsigned char, unsigned char>
678 unsigned char lut_[256];
682 typedef TinyVector<unsigned char, 3> argument_type;
684 typedef TinyVector<unsigned char, 3> result_type;
686 typedef TinyVector<unsigned char, 3> value_type;
690 for(int i=0; i<256; ++i)
692 lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, 255.0);
696 sRGB2RGBFunctor(double max)
698 for(int i=0; i<256; ++i)
700 lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, max);
705 TinyVector<unsigned char, 3> operator()(V const & rgb) const
707 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
711 template <class From, class To>
712 class FunctorTraits<sRGB2RGBFunctor<From, To> >
713 : public FunctorTraitsBase<sRGB2RGBFunctor<From, To> >
716 typedef VigraTrueType isUnaryFunctor;
719 /** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ.
721 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
724 According to ITU-R Recommendation BT.709, the functor realizes the transformation
728 X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max} + 0.180423\enspace B / B_{max}\\
729 Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max} + 0.072169\enspace B / B_{max} \\
730 Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max} + 0.950227\enspace B / B_{max}
734 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
735 in the constructor. X, Y, and Z are always positive and reach their maximum for white.
736 The white point is obtained by transforming RGB(255, 255, 255). It corresponds to the
737 D65 illuminant. Y represents the <em>luminance</em> ("brightness") of the color. The above
738 transformation is officially defined in connection with the sRGB color space (i.e. when the RGB values
739 are obtained by inverse gamma correction of sRGB), other color spaces use slightly different numbers
740 or another standard illuminant (which gives raise to significantly different numbers).
742 <b> Traits defined:</b>
744 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
751 /** the result's component type
753 typedef typename NumericTraits<T>::RealPromote component_type;
755 /** the functor's argument type
757 typedef TinyVector<T, 3> argument_type;
759 /** the functor's result type
761 typedef TinyVector<component_type, 3> result_type;
763 /** \deprecated use argument_type and result_type
765 typedef TinyVector<component_type, 3> value_type;
767 /** default constructor.
768 The maximum value for each RGB component defaults to 255.
775 \arg max - the maximum value for each RGB component
777 RGB2XYZFunctor(component_type max)
781 /** apply the transformation
783 result_type operator()(argument_type const & rgb) const
785 typedef detail::RequiresExplicitCast<component_type> Convert;
786 component_type red = rgb[0] / max_;
787 component_type green = rgb[1] / max_;
788 component_type blue = rgb[2] / max_;
790 result[0] = Convert::cast(0.412453*red + 0.357580*green + 0.180423*blue);
791 result[1] = Convert::cast(0.212671*red + 0.715160*green + 0.072169*blue);
792 result[2] = Convert::cast(0.019334*red + 0.119193*green + 0.950227*blue);
801 class FunctorTraits<RGB2XYZFunctor<T> >
802 : public FunctorTraitsBase<RGB2XYZFunctor<T> >
805 typedef VigraTrueType isUnaryFunctor;
808 /** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tri-stimulus XYZ.
810 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
813 The functor realizes the transformation
816 R'G'B' \Rightarrow RGB \Rightarrow XYZ
819 See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a description of the two
822 <b> Traits defined:</b>
824 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
827 class RGBPrime2XYZFunctor
831 /** the result's component type
833 typedef typename NumericTraits<T>::RealPromote component_type;
835 /** the functor's argument type
837 typedef TinyVector<T, 3> argument_type;
839 /** the functor's result type
841 typedef TinyVector<component_type, 3> result_type;
843 /** \deprecated use argument_type and result_type
845 typedef TinyVector<component_type, 3> value_type;
847 /** default constructor
848 The maximum value for each RGB component defaults to 255.
850 RGBPrime2XYZFunctor()
851 : gamma_(1.0/ 0.45), max_(component_type(255.0))
855 \arg max - the maximum value for each RGB component
857 RGBPrime2XYZFunctor(component_type max)
858 : gamma_(1.0/ 0.45), max_(max)
861 /** apply the transformation
863 result_type operator()(argument_type const & rgb) const
865 typedef detail::RequiresExplicitCast<component_type> Convert;
866 component_type red = detail::gammaCorrection<component_type>(rgb[0]/max_, gamma_);
867 component_type green = detail::gammaCorrection<component_type>(rgb[1]/max_, gamma_);
868 component_type blue = detail::gammaCorrection<component_type>(rgb[2]/max_, gamma_);
870 result[0] = Convert::cast(0.412453*red + 0.357580*green + 0.180423*blue);
871 result[1] = Convert::cast(0.212671*red + 0.715160*green + 0.072169*blue);
872 result[2] = Convert::cast(0.019334*red + 0.119193*green + 0.950227*blue);
882 class FunctorTraits<RGBPrime2XYZFunctor<T> >
883 : public FunctorTraitsBase<RGBPrime2XYZFunctor<T> >
886 typedef VigraTrueType isUnaryFunctor;
889 /** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB.
891 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
894 According to ITU-R Recommendation BT.709, the functor realizes the transformation
898 R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y - 0.4985363262\enspace Z) \\
899 G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y + 0.0415559266\enspace Z) \\
900 B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y + 1.0573110696\enspace Z)
904 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
905 in the constructor. This is the inverse transform of vigra::RGB2XYZFunctor.
907 <b> Traits defined:</b>
909 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
914 typedef typename NumericTraits<T>::RealPromote component_type;
919 /** the functor's argument type. (Actually, the argument type
920 is more general: <TT>V</TT> with arbitrary
921 <TT>V</TT>. But this cannot be expressed in a typedef.)
923 typedef TinyVector<T, 3> argument_type;
925 /** the functor's result type
927 typedef TinyVector<T, 3> result_type;
929 /** \deprecated use argument_type and result_type
931 typedef TinyVector<T, 3> value_type;
933 /** default constructor.
934 The maximum value for each RGB component defaults to 255.
941 \arg max - the maximum value for each RGB component
943 XYZ2RGBFunctor(component_type max)
947 /** apply the transformation
950 result_type operator()(V const & xyz) const
952 typedef detail::RequiresExplicitCast<component_type> Convert;
953 component_type red = Convert::cast( 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]);
954 component_type green = Convert::cast(-0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]);
955 component_type blue = Convert::cast( 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]);
956 return value_type(NumericTraits<T>::fromRealPromote(red * max_),
957 NumericTraits<T>::fromRealPromote(green * max_),
958 NumericTraits<T>::fromRealPromote(blue * max_));
963 class FunctorTraits<XYZ2RGBFunctor<T> >
964 : public FunctorTraitsBase<XYZ2RGBFunctor<T> >
967 typedef VigraTrueType isUnaryFunctor;
970 /** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma corrected) R'G'B'.
972 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
975 The functor realizes the transformation
978 XYZ \Rightarrow RGB \Rightarrow R'G'B'
981 See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a description of the two
984 <b> Traits defined:</b>
986 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
989 class XYZ2RGBPrimeFunctor
991 typedef typename NumericTraits<T>::RealPromote component_type;
999 /** the functor's argument type. (actually, the argument type
1000 can be any vector type with the same interface.
1001 But this cannot be expressed in a typedef.)
1003 typedef TinyVector<T, 3> argument_type;
1005 /** the functor's result type
1007 typedef TinyVector<T, 3> result_type;
1009 /** \deprecated use argument_type and result_type
1011 typedef TinyVector<T, 3> value_type;
1013 /** default constructor.
1014 The maximum value for each RGB component defaults to 255.
1016 XYZ2RGBPrimeFunctor()
1017 : gamma_(0.45), max_(component_type(255.0))
1021 \arg max - the maximum value for each RGB component
1023 XYZ2RGBPrimeFunctor(component_type max)
1024 : gamma_(0.45), max_(max)
1027 /** apply the transformation
1030 result_type operator()(V const & xyz) const
1032 typedef detail::RequiresExplicitCast<component_type> Convert;
1033 component_type red = Convert::cast( 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]);
1034 component_type green = Convert::cast(-0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]);
1035 component_type blue = Convert::cast( 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]);
1036 return value_type(NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(red, gamma_) * max_),
1037 NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(green, gamma_) * max_),
1038 NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(blue, gamma_) * max_));
1043 class FunctorTraits<XYZ2RGBPrimeFunctor<T> >
1044 : public FunctorTraitsBase<XYZ2RGBPrimeFunctor<T> >
1047 typedef VigraTrueType isUnaryFunctor;
1050 /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*u*v*.
1052 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1055 The functor realizes the transformation
1059 L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\
1061 L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
1064 u' & = & \frac{4 X}{X+15 Y + 3 Z}, \quad
1065 v' = \frac{9 Y}{X+15 Y + 3 Z}\\
1067 u^{*} & = & 13 L^{*} (u' - u_n'), \quad v^{*} = 13 L^{*} (v' - v_n')
1071 where \f$(X_n, Y_n, Z_n) = (0.950456, 1.0, 1.088754)\f$ is the reference white point of standard illuminant D65,
1072 and \f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ calculated for this point.
1073 \f$L^{*}\f$ represents the <em>lightness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ code the
1074 chromaticity. (Instead of the rationals \f$\frac{216}{24389}\f$ and \f$\frac{24389}{27}\f$, the original standard gives the
1075 rounded values 0.008856 and 903.3. As <a href="http://www.brucelindbloom.com/index.html?LContinuity.html">Bruce Lindbloom</a>
1076 points out, the rounded values give raise to a discontinuity which is removed by the accurate rationals. This bug will be fixed
1077 in future versions of the CIE Luv standard.)
1079 <b> Traits defined:</b>
1081 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1084 class XYZ2LuvFunctor
1088 /** the result's component type
1090 typedef typename NumericTraits<T>::RealPromote component_type;
1092 /** the functor's argument type
1094 typedef TinyVector<T, 3> argument_type;
1096 /** the functor's result type
1098 typedef TinyVector<component_type, 3> result_type;
1100 /** \deprecated use argument_type and result_type
1102 typedef TinyVector<component_type, 3> value_type;
1106 kappa_(24389.0/27.0),
1107 epsilon_(216.0/24389.0)
1111 result_type operator()(V const & xyz) const
1114 if(xyz[1] == NumericTraits<T>::zero())
1116 result[0] = NumericTraits<component_type>::zero();
1117 result[1] = NumericTraits<component_type>::zero();
1118 result[2] = NumericTraits<component_type>::zero();
1122 typedef detail::RequiresExplicitCast<component_type> Convert;
1123 component_type L = Convert::cast(
1126 : 116.0 * VIGRA_CSTD::pow((double)xyz[1], gamma_) - 16.0);
1127 component_type denom = Convert::cast(xyz[0] + 15.0*xyz[1] + 3.0*xyz[2]);
1128 component_type uprime = Convert::cast(4.0 * xyz[0] / denom);
1129 component_type vprime = Convert::cast(9.0 * xyz[1] / denom);
1131 result[1] = Convert::cast(13.0*L*(uprime - 0.197839));
1132 result[2] = Convert::cast(13.0*L*(vprime - 0.468342));
1138 double gamma_, kappa_, epsilon_;
1142 class FunctorTraits<XYZ2LuvFunctor<T> >
1143 : public FunctorTraitsBase<XYZ2LuvFunctor<T> >
1146 typedef VigraTrueType isUnaryFunctor;
1149 /** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stimulus XYZ.
1151 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1154 The functor realizes the inverse of the transformation described in vigra::XYZ2LuvFunctor
1156 <b> Traits defined:</b>
1158 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1161 class Luv2XYZFunctor
1165 /** the result's component type
1167 typedef typename NumericTraits<T>::RealPromote component_type;
1169 /** the functor's argument type
1171 typedef TinyVector<T, 3> argument_type;
1173 /** the functor's result type
1175 typedef TinyVector<component_type, 3> result_type;
1177 /** \deprecated use argument_type and result_type
1179 typedef TinyVector<component_type, 3> value_type;
1183 ikappa_(27.0/24389.0)
1186 /** apply the transformation
1189 result_type operator()(V const & luv) const
1192 if(luv[0] == NumericTraits<T>::zero())
1194 result[0] = NumericTraits<component_type>::zero();
1195 result[1] = NumericTraits<component_type>::zero();
1196 result[2] = NumericTraits<component_type>::zero();
1200 typedef detail::RequiresExplicitCast<component_type> Convert;
1201 component_type uprime = Convert::cast(luv[1] / 13.0 / luv[0] + 0.197839);
1202 component_type vprime = Convert::cast(luv[2] / 13.0 / luv[0] + 0.468342);
1204 result[1] = Convert::cast(
1207 : VIGRA_CSTD::pow((luv[0] + 16.0) / 116.0, gamma_));
1208 result[0] = Convert::cast(9.0*uprime*result[1] / 4.0 / vprime);
1209 result[2] = Convert::cast(((9.0 / vprime - 15.0)*result[1] - result[0])/ 3.0);
1215 double gamma_, ikappa_;
1219 class FunctorTraits<Luv2XYZFunctor<T> >
1220 : public FunctorTraitsBase<Luv2XYZFunctor<T> >
1223 typedef VigraTrueType isUnaryFunctor;
1226 /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*a*b*.
1228 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1231 The functor realizes the transformation
1235 L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad \frac{216}{24389} < \frac{Y}{Y_n}\\
1237 L^{*} & = & \frac{24389}{27} \enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
1239 a^{*} & = & 500 \left[ \left( \frac{X}{X_n} \right)^\frac{1}{3} - \left( \frac{Y}{Y_n} \right)^\frac{1}{3} \right] \\
1241 b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\
1245 where \f$(X_n, Y_n, Z_n) = (0.950456, 1.0, 1.088754)\f$ is the reference white point of standard illuminant D65.
1246 \f$L^{*}\f$ represents the <em>lightness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ code the
1247 chromaticity. (Instead of the rationals \f$\frac{216}{24389}\f$ and \f$\frac{24389}{27}\f$, the original standard gives the
1248 rounded values 0.008856 and 903.3. As <a href="http://www.brucelindbloom.com/index.html?LContinuity.html">Bruce Lindbloom</a>
1249 points out, the rounded values give raise to a discontinuity which is removed by the accurate rationals. This bug will be fixed
1250 in future versions of the CIE Lab standard.)
1252 <b> Traits defined:</b>
1254 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1257 class XYZ2LabFunctor
1261 /** the result's component type
1263 typedef typename NumericTraits<T>::RealPromote component_type;
1265 /** the functor's argument type
1267 typedef TinyVector<T, 3> argument_type;
1269 /** the functor's result type
1271 typedef TinyVector<component_type, 3> result_type;
1273 /** \deprecated use argument_type and result_type
1275 typedef TinyVector<component_type, 3> value_type;
1279 kappa_(24389.0/27.0),
1280 epsilon_(216.0/24389.0)
1283 /** apply the transformation
1286 result_type operator()(V const & xyz) const
1288 typedef detail::RequiresExplicitCast<component_type> Convert;
1289 component_type xgamma = Convert::cast(std::pow(xyz[0] / 0.950456, gamma_));
1290 component_type ygamma = Convert::cast(std::pow((double)xyz[1], gamma_));
1291 component_type zgamma = Convert::cast(std::pow(xyz[2] / 1.088754, gamma_));
1292 component_type L = Convert::cast(
1295 : 116.0 * ygamma - 16.0);
1298 result[1] = Convert::cast(500.0*(xgamma - ygamma));
1299 result[2] = Convert::cast(200.0*(ygamma - zgamma));
1304 double gamma_, kappa_, epsilon_;
1308 class FunctorTraits<XYZ2LabFunctor<T> >
1309 : public FunctorTraitsBase<XYZ2LabFunctor<T> >
1312 typedef VigraTrueType isUnaryFunctor;
1315 /** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stimulus XYZ.
1317 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1320 The functor realizes the inverse of the transformation described in vigra::XYZ2LabFunctor
1322 <b> Traits defined:</b>
1324 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1327 class Lab2XYZFunctor
1331 /** the result's component type
1333 typedef typename NumericTraits<T>::RealPromote component_type;
1335 /** the functor's argument type
1337 typedef TinyVector<T, 3> argument_type;
1339 /** the functor's result type
1341 typedef TinyVector<component_type, 3> result_type;
1343 /** \deprecated use argument_type and result_type
1345 typedef TinyVector<component_type, 3> value_type;
1347 /** the functor's value type
1351 ikappa_(27.0/24389.0)
1354 /** apply the transformation
1357 result_type operator()(V const & lab) const
1359 typedef detail::RequiresExplicitCast<component_type> Convert;
1360 component_type Y = Convert::cast(
1363 : std::pow((lab[0] + 16.0) / 116.0, gamma_));
1364 component_type ygamma = Convert::cast(std::pow((double)Y, 1.0 / gamma_));
1365 component_type X = Convert::cast(std::pow(lab[1] / 500.0 + ygamma, gamma_) * 0.950456);
1366 component_type Z = Convert::cast(std::pow(-lab[2] / 200.0 + ygamma, gamma_) * 1.088754);
1375 double gamma_, ikappa_;
1379 class FunctorTraits<Lab2XYZFunctor<T> >
1380 : public FunctorTraitsBase<Lab2XYZFunctor<T> >
1383 typedef VigraTrueType isUnaryFunctor;
1386 /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*.
1388 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1391 The functor realizes the transformation
1394 RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
1397 See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the two
1398 steps. The resulting color components will have the following bounds:
1402 0 \leq & L^* & \leq 100 \\
1403 -83.077 \leq & u^* & \leq 175.015 \\
1404 -134.101 \leq & v^* & \leq 107.393
1408 <b> Traits defined:</b>
1410 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1413 class RGB2LuvFunctor
1417 u in [-83.077, 175.015]
1418 v in [-134.101, 107.393]
1419 maximum saturation: 179.04
1420 red = [53.2406, 175.015, 37.7522]
1424 /** the result's component type
1426 typedef typename NumericTraits<T>::RealPromote component_type;
1428 /** the functor's argument type
1430 typedef TinyVector<T, 3> argument_type;
1432 /** the functor's result type
1434 typedef typename XYZ2LuvFunctor<component_type>::result_type result_type;
1436 /** \deprecated use argument_type and result_type
1438 typedef typename XYZ2LuvFunctor<component_type>::result_type value_type;
1440 /** default constructor.
1441 The maximum value for each RGB component defaults to 255.
1448 \arg max - the maximum value for each RGB component
1450 RGB2LuvFunctor(component_type max)
1454 /** apply the transformation
1457 result_type operator()(V const & rgb) const
1459 return xyz2luv(rgb2xyz(rgb));
1463 RGB2XYZFunctor<T> rgb2xyz;
1464 XYZ2LuvFunctor<component_type> xyz2luv;
1468 class FunctorTraits<RGB2LuvFunctor<T> >
1469 : public FunctorTraitsBase<RGB2LuvFunctor<T> >
1472 typedef VigraTrueType isUnaryFunctor;
1475 /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*.
1477 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1480 The functor realizes the transformation
1483 RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
1486 See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the two
1487 steps. The resulting color components will have the following bounds:
1491 0 \leq & L^* & \leq 100 \\
1492 -86.1813 \leq & u^* & \leq 98.2352 \\
1493 -107.862 \leq & v^* & \leq 94.4758
1497 <b> Traits defined:</b>
1499 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1502 class RGB2LabFunctor
1506 a in [-86.1813, 98.2352]
1507 b in [-107.862, 94.4758]
1508 maximum saturation: 133.809
1509 red = [53.2406, 80.0942, 67.2015]
1513 /** the result's component type
1515 typedef typename NumericTraits<T>::RealPromote component_type;
1517 /** the functor's argument type
1519 typedef TinyVector<T, 3> argument_type;
1521 /** the functor's result type
1523 typedef typename XYZ2LabFunctor<component_type>::result_type result_type;
1525 /** \deprecated use argument_type and result_type
1527 typedef typename XYZ2LabFunctor<component_type>::result_type value_type;
1529 /** default constructor.
1530 The maximum value for each RGB component defaults to 255.
1537 \arg max - the maximum value for each RGB component
1539 RGB2LabFunctor(component_type max)
1543 /** apply the transformation
1546 result_type operator()(V const & rgb) const
1548 return xyz2lab(rgb2xyz(rgb));
1552 RGB2XYZFunctor<T> rgb2xyz;
1553 XYZ2LabFunctor<component_type> xyz2lab;
1557 class FunctorTraits<RGB2LabFunctor<T> >
1558 : public FunctorTraitsBase<RGB2LabFunctor<T> >
1561 typedef VigraTrueType isUnaryFunctor;
1564 /** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB.
1566 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1569 The functor realizes the inverse of the transformation described in vigra::RGB2LuvFunctor
1571 <b> Traits defined:</b>
1573 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1576 class Luv2RGBFunctor
1578 typedef typename NumericTraits<T>::RealPromote component_type;
1580 XYZ2RGBFunctor<T> xyz2rgb;
1581 Luv2XYZFunctor<component_type> luv2xyz;
1584 /** the functor's argument type. (Actually, the argument type
1585 can be any vector type with the same interface.
1586 But this cannot be expressed in a typedef.)
1588 typedef TinyVector<T, 3> argument_type;
1590 /** the functor's result type
1592 typedef typename XYZ2RGBFunctor<T>::result_type result_type;
1594 /** \deprecated use argument_type and result_type
1596 typedef typename XYZ2RGBFunctor<T>::result_type value_type;
1602 Luv2RGBFunctor(component_type max)
1606 /** apply the transformation
1609 result_type operator()(V const & luv) const
1611 return xyz2rgb(luv2xyz(luv));
1616 class FunctorTraits<Luv2RGBFunctor<T> >
1617 : public FunctorTraitsBase<Luv2RGBFunctor<T> >
1620 typedef VigraTrueType isUnaryFunctor;
1623 /** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB.
1625 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1628 The functor realizes the inverse of the transformation described in vigra::RGB2LabFunctor
1630 <b> Traits defined:</b>
1632 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1635 class Lab2RGBFunctor
1637 typedef typename NumericTraits<T>::RealPromote component_type;
1639 XYZ2RGBFunctor<T> xyz2rgb;
1640 Lab2XYZFunctor<component_type> lab2xyz;
1644 /** the functor's argument type. (Actually, the argument type
1645 can be any vector type with the same interface.
1646 But this cannot be expressed in a typedef.)
1648 typedef TinyVector<T, 3> argument_type;
1650 /** the functor's result type
1652 typedef typename XYZ2RGBFunctor<T>::result_type result_type;
1654 /** \deprecated use argument_type and result_type
1656 typedef typename XYZ2RGBFunctor<T>::result_type value_type;
1658 /** default constructor.
1659 The maximum value for each RGB component defaults to 255.
1666 \arg max - the maximum value for each RGB component
1668 Lab2RGBFunctor(component_type max)
1672 /** apply the transformation
1675 result_type operator()(V const & lab) const
1677 return xyz2rgb(lab2xyz(lab));
1682 class FunctorTraits<Lab2RGBFunctor<T> >
1683 : public FunctorTraitsBase<Lab2RGBFunctor<T> >
1686 typedef VigraTrueType isUnaryFunctor;
1689 /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*u*v*.
1691 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1694 The functor realizes the transformation
1697 R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
1700 See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the three
1701 steps. The resulting color components will have the following bounds:
1705 0 \leq & L^* & \leq 100 \\
1706 -83.077 \leq & u^* & \leq 175.015 \\
1707 -134.101 \leq & v^* & \leq 107.393
1711 <b> Traits defined:</b>
1713 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1716 class RGBPrime2LuvFunctor
1720 /** the result's component type
1722 typedef typename NumericTraits<T>::RealPromote component_type;
1724 /** the functor's argument type
1726 typedef TinyVector<T, 3> argument_type;
1728 /** the functor's result type
1730 typedef typename XYZ2LuvFunctor<component_type>::result_type result_type;
1732 /** \deprecated use argument_type and result_type
1734 typedef typename XYZ2LuvFunctor<component_type>::result_type value_type;
1736 /** default constructor.
1737 The maximum value for each RGB component defaults to 255.
1739 RGBPrime2LuvFunctor()
1744 \arg max - the maximum value for each RGB component
1746 RGBPrime2LuvFunctor(component_type max)
1750 /** apply the transformation
1753 result_type operator()(V const & rgb) const
1755 return xyz2luv(rgb2xyz(rgb));
1759 RGBPrime2XYZFunctor<T> rgb2xyz;
1760 XYZ2LuvFunctor<component_type> xyz2luv;
1764 class FunctorTraits<RGBPrime2LuvFunctor<T> >
1765 : public FunctorTraitsBase<RGBPrime2LuvFunctor<T> >
1768 typedef VigraTrueType isUnaryFunctor;
1771 /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*a*b*.
1773 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1776 The functor realizes the transformation
1779 R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
1782 See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the three
1783 steps. The resulting color components will have the following bounds:
1787 0 \leq & L^* & \leq 100 \\
1788 -86.1813 \leq & u^* & \leq 98.2352 \\
1789 -107.862 \leq & v^* & \leq 94.4758
1793 <b> Traits defined:</b>
1795 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1798 class RGBPrime2LabFunctor
1802 /** the result's component type
1804 typedef typename NumericTraits<T>::RealPromote component_type;
1806 /** the functor's argument type
1808 typedef TinyVector<T, 3> argument_type;
1810 /** the functor's result type
1812 typedef typename XYZ2LabFunctor<component_type>::result_type result_type;
1814 /** \deprecated use argument_type and result_type
1816 typedef typename XYZ2LabFunctor<component_type>::result_type value_type;
1818 /** default constructor.
1819 The maximum value for each RGB component defaults to 255.
1821 RGBPrime2LabFunctor()
1826 \arg max - the maximum value for each RGB component
1828 RGBPrime2LabFunctor(component_type max)
1832 /** apply the transformation
1835 result_type operator()(V const & rgb) const
1837 return xyz2lab(rgb2xyz(rgb));
1841 RGBPrime2XYZFunctor<T> rgb2xyz;
1842 XYZ2LabFunctor<component_type> xyz2lab;
1846 class FunctorTraits<RGBPrime2LabFunctor<T> >
1847 : public FunctorTraitsBase<RGBPrime2LabFunctor<T> >
1850 typedef VigraTrueType isUnaryFunctor;
1853 /** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma corrected) R'G'B'.
1855 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1858 The functor realizes the inverse of the transformation described in vigra::RGBPrime2LuvFunctor
1860 <b> Traits defined:</b>
1862 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1865 class Luv2RGBPrimeFunctor
1867 typedef typename NumericTraits<T>::RealPromote component_type;
1869 XYZ2RGBPrimeFunctor<T> xyz2rgb;
1870 Luv2XYZFunctor<component_type> luv2xyz;
1874 /** the functor's argument type. (Actually, the argument type
1875 can be any vector type with the same interface.
1876 But this cannot be expressed in a typedef.)
1878 typedef TinyVector<T, 3> argument_type;
1880 /** the functor's result type
1882 typedef typename XYZ2RGBFunctor<T>::result_type result_type;
1884 /** \deprecated use argument_type and result_type
1886 typedef typename XYZ2RGBFunctor<T>::result_type value_type;
1888 /** default constructor.
1889 The maximum value for each RGB component defaults to 255.
1891 Luv2RGBPrimeFunctor()
1896 \arg max - the maximum value for each RGB component
1898 Luv2RGBPrimeFunctor(component_type max)
1902 /** apply the transformation
1905 result_type operator()(V const & luv) const
1907 return xyz2rgb(luv2xyz(luv));
1912 class FunctorTraits<Luv2RGBPrimeFunctor<T> >
1913 : public FunctorTraitsBase<Luv2RGBPrimeFunctor<T> >
1916 typedef VigraTrueType isUnaryFunctor;
1919 /** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma corrected) R'G'B'.
1921 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1924 The functor realizes the inverse of the transformation described in vigra::RGBPrime2LabFunctor
1926 <b> Traits defined:</b>
1928 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1931 class Lab2RGBPrimeFunctor
1933 typedef typename NumericTraits<T>::RealPromote component_type;
1935 XYZ2RGBPrimeFunctor<T> xyz2rgb;
1936 Lab2XYZFunctor<component_type> lab2xyz;
1940 /** the functor's argument type. (Actually, the argument type
1941 can be any vector type with the same interface.
1942 But this cannot be expressed in a typedef.)
1944 typedef TinyVector<T, 3> argument_type;
1946 /** the functor's result type
1948 typedef typename XYZ2RGBFunctor<T>::result_type result_type;
1950 /** \deprecated use argument_type and result_type
1952 typedef typename XYZ2RGBFunctor<T>::result_type value_type;
1954 /** default constructor.
1955 The maximum value for each RGB component defaults to 255.
1957 Lab2RGBPrimeFunctor()
1962 \arg max - the maximum value for each RGB component
1964 Lab2RGBPrimeFunctor(component_type max)
1968 /** apply the transformation
1971 result_type operator()(V const & lab) const
1973 return xyz2rgb(lab2xyz(lab));
1978 class FunctorTraits<Lab2RGBPrimeFunctor<T> >
1979 : public FunctorTraitsBase<Lab2RGBPrimeFunctor<T> >
1982 typedef VigraTrueType isUnaryFunctor;
1985 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color difference components.
1987 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
1990 According to ITU-R Recommendation BT.601, the functor realizes the transformation
1994 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
1995 Pb & = & -0.1687358916\enspace R / R_{max} + 0.3312641084\enspace G / G_{max} + 0.5\enspace B / B_{max} \\
1996 Pr & = & 0.5\enspace R / R_{max} + 0.4186875892\enspace G / G_{max} + 0.0813124108\enspace B / B_{max}
2000 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
2001 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color, and
2002 Pb and Pr are the blue (B'-Y') and red (R'-Y') color difference components.
2003 The transformation is scaled so that the following bounds apply:
2007 0 \leq & Y' & \leq 1 \\
2008 -0.5 \leq & Pb & \leq 0.5 \\
2009 -0.5 \leq & Pr & \leq 0.5
2013 <b> Traits defined:</b>
2015 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2018 class RGBPrime2YPrimePbPrFunctor
2024 maximum saturation: 0.533887
2025 red = [0.299, -0.168736, 0.5]
2029 /** the result's component type
2031 typedef typename NumericTraits<T>::RealPromote component_type;
2033 /** the functor's argument type
2035 typedef TinyVector<T, 3> argument_type;
2037 /** the functor's result type
2039 typedef TinyVector<component_type, 3> result_type;
2041 /** \deprecated use argument_type and result_type
2043 typedef TinyVector<component_type, 3> value_type;
2045 /** default constructor.
2046 The maximum value for each RGB component defaults to 255.
2048 RGBPrime2YPrimePbPrFunctor()
2053 \arg max - the maximum value for each RGB component
2055 RGBPrime2YPrimePbPrFunctor(component_type max)
2059 /** apply the transformation
2062 result_type operator()(V const & rgb) const
2064 typedef detail::RequiresExplicitCast<component_type> Convert;
2065 component_type red = rgb[0] / max_;
2066 component_type green = rgb[1] / max_;
2067 component_type blue = rgb[2] / max_;
2070 result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
2071 result[1] = Convert::cast(-0.1687358916*red - 0.3312641084*green + 0.5*blue);
2072 result[2] = Convert::cast(0.5*red - 0.4186875892*green - 0.0813124108*blue);
2077 component_type max_;
2081 class FunctorTraits<RGBPrime2YPrimePbPrFunctor<T> >
2082 : public FunctorTraitsBase<RGBPrime2YPrimePbPrFunctor<T> >
2085 typedef VigraTrueType isUnaryFunctor;
2088 /** \brief Convert Y'PbPr color difference components into non-linear (gamma corrected) R'G'B'.
2090 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2093 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimePbPrFunctor
2095 <b> Traits defined:</b>
2097 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2100 class YPrimePbPr2RGBPrimeFunctor
2102 typedef typename NumericTraits<T>::RealPromote component_type;
2104 component_type max_;
2108 /** the functor's argument type. (Actually, the argument type
2109 can be any vector type with the same interface.
2110 But this cannot be expressed in a typedef.)
2112 typedef TinyVector<T, 3> argument_type;
2114 /** the functor's result type
2116 typedef TinyVector<T, 3> result_type;
2118 /** \deprecated use argument_type and result_type
2120 typedef TinyVector<T, 3> value_type;
2122 /** default constructor.
2123 The maximum value for each RGB component defaults to 255.
2125 YPrimePbPr2RGBPrimeFunctor()
2130 \arg max - the maximum value for each RGB component
2132 YPrimePbPr2RGBPrimeFunctor(component_type max)
2136 /** apply the transformation
2139 result_type operator()(V const & ypbpr) const
2141 typedef detail::RequiresExplicitCast<component_type> Convert;
2142 component_type nred = Convert::cast(ypbpr[0] + 1.402*ypbpr[2]);
2143 component_type ngreen = Convert::cast(ypbpr[0] - 0.3441362862*ypbpr[1] - 0.7141362862*ypbpr[2]);
2144 component_type nblue = Convert::cast(ypbpr[0] + 1.772*ypbpr[1]);
2145 return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
2146 NumericTraits<T>::fromRealPromote(ngreen * max_),
2147 NumericTraits<T>::fromRealPromote(nblue * max_));
2152 class FunctorTraits<YPrimePbPr2RGBPrimeFunctor<T> >
2153 : public FunctorTraitsBase<YPrimePbPr2RGBPrimeFunctor<T> >
2156 typedef VigraTrueType isUnaryFunctor;
2159 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components.
2161 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2164 According to the PAL analog videa standard, the functor realizes the transformation
2168 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
2169 I & = & 0.596\enspace R / R_{max} - 0.274\enspace G / G_{max} - 0.322\enspace B / B_{max} \\
2170 Q & = & 0.212\enspace R / R_{max} - 0.523\enspace G / G_{max} + 0.311\enspace B / B_{max}
2174 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
2175 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color.
2176 The transformation is scaled so that the following bounds apply:
2180 0 \leq & Y' & \leq 1 \\
2181 -0.596 \leq & I & \leq 0.596 \\
2182 -0.523 \leq & Q & \leq 0.523
2186 <b> Traits defined:</b>
2188 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2191 class RGBPrime2YPrimeIQFunctor
2195 I in [-0.596, 0.596]
2196 Q in [-0.523, 0.523]
2197 maximum saturation: 0.632582
2198 red = [0.299, 0.596, 0.212]
2202 /** the result's component type
2204 typedef typename NumericTraits<T>::RealPromote component_type;
2206 /** the functor's argument type
2208 typedef TinyVector<T, 3> argument_type;
2210 /** the functor's result type
2212 typedef TinyVector<component_type, 3> result_type;
2214 /** \deprecated use argument_type and result_type
2216 typedef TinyVector<component_type, 3> value_type;
2218 /** default constructor.
2219 The maximum value for each RGB component defaults to 255.
2221 RGBPrime2YPrimeIQFunctor()
2226 \arg max - the maximum value for each RGB component
2228 RGBPrime2YPrimeIQFunctor(component_type max)
2232 /** apply the transformation
2235 result_type operator()(V const & rgb) const
2237 typedef detail::RequiresExplicitCast<component_type> Convert;
2238 component_type red = rgb[0] / max_;
2239 component_type green = rgb[1] / max_;
2240 component_type blue = rgb[2] / max_;
2243 result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
2244 result[1] = Convert::cast(0.596*red - 0.274*green - 0.322*blue);
2245 result[2] = Convert::cast(0.212*red - 0.523*green + 0.311*blue);
2250 component_type max_;
2254 class FunctorTraits<RGBPrime2YPrimeIQFunctor<T> >
2255 : public FunctorTraitsBase<RGBPrime2YPrimeIQFunctor<T> >
2258 typedef VigraTrueType isUnaryFunctor;
2261 /** \brief Convert Y'IQ color components into non-linear (gamma corrected) R'G'B'.
2263 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2266 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeIQFunctor
2268 <b> Traits defined:</b>
2270 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2273 class YPrimeIQ2RGBPrimeFunctor
2275 typedef typename NumericTraits<T>::RealPromote component_type;
2277 component_type max_;
2281 /** the functor's argument type. (Actually, the argument type
2282 can be any vector type with the same interface.
2283 But this cannot be expressed in a typedef.)
2285 typedef TinyVector<T, 3> argument_type;
2287 /** the functor's result type
2289 typedef TinyVector<T, 3> result_type;
2291 /** \deprecated use argument_type and result_type
2293 typedef TinyVector<T, 3> value_type;
2295 /** default constructor.
2296 The maximum value for each RGB component defaults to 255.
2298 YPrimeIQ2RGBPrimeFunctor()
2303 \arg max - the maximum value for each RGB component
2305 YPrimeIQ2RGBPrimeFunctor(component_type max)
2309 /** apply the transformation
2312 result_type operator()(V const & yiq) const
2314 typedef detail::RequiresExplicitCast<component_type> Convert;
2315 component_type nred = Convert::cast(yiq[0] + 0.9548892043*yiq[1] + 0.6221039350*yiq[2]);
2316 component_type ngreen = Convert::cast(yiq[0] - 0.2713547827*yiq[1] - 0.6475120259*yiq[2]);
2317 component_type nblue = Convert::cast(yiq[0] - 1.1072510054*yiq[1] + 1.7024603738*yiq[2]);
2318 return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
2319 NumericTraits<T>::fromRealPromote(ngreen * max_),
2320 NumericTraits<T>::fromRealPromote(nblue * max_));
2325 class FunctorTraits<YPrimeIQ2RGBPrimeFunctor<T> >
2326 : public FunctorTraitsBase<YPrimeIQ2RGBPrimeFunctor<T> >
2329 typedef VigraTrueType isUnaryFunctor;
2332 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components.
2334 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2337 According to the NTSC analog videa standard, the functor realizes the transformation
2341 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
2342 U & = & -0.147\enspace R / R_{max} - 0.289\enspace G / G_{max} + 0.436\enspace B / B_{max} \\
2343 V & = & 0.615\enspace R / R_{max} - 0.515\enspace G / G_{max} - 0.100\enspace B / B_{max}
2347 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
2348 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color.
2349 The transformation is scaled so that the following bounds apply:
2353 0 \leq & Y' & \leq 1 \\
2354 -0.436 \leq & U & \leq 0.436 \\
2355 -0.615 \leq & V & \leq 0.615
2359 <b> Traits defined:</b>
2361 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2364 class RGBPrime2YPrimeUVFunctor
2368 U in [-0.436, 0.436]
2369 V in [-0.615, 0.615]
2370 maximum saturation: 0.632324
2371 red = [0.299, -0.147, 0.615]
2375 /** the result's component type
2377 typedef typename NumericTraits<T>::RealPromote component_type;
2379 /** the functor's argument type
2381 typedef TinyVector<T, 3> argument_type;
2383 /** the functor's result type
2385 typedef TinyVector<component_type, 3> result_type;
2387 /** \deprecated use argument_type and result_type
2389 typedef TinyVector<component_type, 3> value_type;
2391 /** default constructor.
2392 The maximum value for each RGB component defaults to 255.
2394 RGBPrime2YPrimeUVFunctor()
2399 \arg max - the maximum value for each RGB component
2401 RGBPrime2YPrimeUVFunctor(component_type max)
2405 /** apply the transformation
2408 result_type operator()(V const & rgb) const
2410 typedef detail::RequiresExplicitCast<component_type> Convert;
2411 component_type red = rgb[0] / max_;
2412 component_type green = rgb[1] / max_;
2413 component_type blue = rgb[2] / max_;
2416 result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
2417 result[1] = Convert::cast(-0.1471376975*red - 0.2888623025*green + 0.436*blue);
2418 result[2] = Convert::cast(0.6149122807*red - 0.5149122807*green - 0.100*blue);
2423 component_type max_;
2427 class FunctorTraits<RGBPrime2YPrimeUVFunctor<T> >
2428 : public FunctorTraitsBase<RGBPrime2YPrimeUVFunctor<T> >
2431 typedef VigraTrueType isUnaryFunctor;
2434 /** \brief Convert Y'UV color components into non-linear (gamma corrected) R'G'B'.
2436 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2439 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeUVFunctor
2441 <b> Traits defined:</b>
2443 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2446 class YPrimeUV2RGBPrimeFunctor
2448 typedef typename NumericTraits<T>::RealPromote component_type;
2450 component_type max_;
2454 /** the functor's argument type. (Actually, the argument type
2455 can be any vector type with the same interface.
2456 But this cannot be expressed in a typedef.)
2458 typedef TinyVector<T, 3> argument_type;
2460 /** the functor's result type
2462 typedef TinyVector<T, 3> result_type;
2464 /** \deprecated use argument_type and result_type
2466 typedef TinyVector<T, 3> value_type;
2468 /** default constructor.
2469 The maximum value for each RGB component defaults to 255.
2471 YPrimeUV2RGBPrimeFunctor()
2476 \arg max - the maximum value for each RGB component
2478 YPrimeUV2RGBPrimeFunctor(component_type max)
2482 /** apply the transformation
2485 result_type operator()(V const & yuv) const
2487 typedef detail::RequiresExplicitCast<component_type> Convert;
2488 component_type nred = Convert::cast(yuv[0] + 1.140*yuv[2]);
2489 component_type ngreen = Convert::cast(yuv[0] - 0.3946517044*yuv[1] - 0.580681431*yuv[2]);
2490 component_type nblue = Convert::cast(yuv[0] + 2.0321100920*yuv[1]);
2491 return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
2492 NumericTraits<T>::fromRealPromote(ngreen * max_),
2493 NumericTraits<T>::fromRealPromote(nblue * max_));
2498 class FunctorTraits<YPrimeUV2RGBPrimeFunctor<T> >
2499 : public FunctorTraitsBase<YPrimeUV2RGBPrimeFunctor<T> >
2502 typedef VigraTrueType isUnaryFunctor;
2505 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color difference components.
2507 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2510 This functor basically applies the same transformation as vigra::RGBPrime2YPrimePbPrFunctor
2511 but the color components are scaled so that they can be coded as 8 bit intergers with
2512 minimal loss of information:
2516 16\leq & Y' & \leq 235 \\
2517 16 \leq & Cb & \leq 240 \\
2518 16 \leq & Cr & \leq 240
2522 <b> Traits defined:</b>
2524 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2527 class RGBPrime2YPrimeCbCrFunctor
2533 maximum saturation: 119.591
2534 red = [81.481, 90.203, 240]
2538 /** the result's component type
2540 typedef typename NumericTraits<T>::RealPromote component_type;
2542 /** the functor's argument type
2544 typedef TinyVector<T, 3> argument_type;
2546 /** the functor's result type
2548 typedef TinyVector<component_type, 3> result_type;
2550 /** \deprecated use argument_type and result_type
2552 typedef TinyVector<component_type, 3> value_type;
2554 /** default constructor.
2555 The maximum value for each RGB component defaults to 255.
2557 RGBPrime2YPrimeCbCrFunctor()
2562 \arg max - the maximum value for each RGB component
2564 RGBPrime2YPrimeCbCrFunctor(component_type max)
2568 /** apply the transformation
2571 result_type operator()(V const & rgb) const
2573 typedef detail::RequiresExplicitCast<component_type> Convert;
2574 component_type red = rgb[0] / max_;
2575 component_type green = rgb[1] / max_;
2576 component_type blue = rgb[2] / max_;
2579 result[0] = Convert::cast(16.0 + 65.481*red + 128.553*green + 24.966*blue);
2580 result[1] = Convert::cast(128.0 - 37.79683972*red - 74.20316028*green + 112.0*blue);
2581 result[2] = Convert::cast(128.0 + 112.0*red - 93.78601998*green - 18.21398002*blue);
2586 component_type max_;
2590 class FunctorTraits<RGBPrime2YPrimeCbCrFunctor<T> >
2591 : public FunctorTraitsBase<RGBPrime2YPrimeCbCrFunctor<T> >
2594 typedef VigraTrueType isUnaryFunctor;
2597 /** \brief Convert Y'CbCr color difference components into non-linear (gamma corrected) R'G'B'.
2599 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2602 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeCbCrFunctor
2604 <b> Traits defined:</b>
2606 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2609 class YPrimeCbCr2RGBPrimeFunctor
2611 typedef typename NumericTraits<T>::RealPromote component_type;
2613 component_type max_;
2617 /** the functor's argument type. (Actually, the argument type
2618 can be any vector type with the same interface.
2619 But this cannot be expressed in a typedef.)
2621 typedef TinyVector<T, 3> argument_type;
2623 /** the functor's result type
2625 typedef TinyVector<T, 3> result_type;
2627 /** \deprecated use argument_type and result_type
2629 typedef TinyVector<T, 3> value_type;
2631 /** default constructor.
2632 The maximum value for each RGB component defaults to 255.
2634 YPrimeCbCr2RGBPrimeFunctor()
2639 \arg max - the maximum value for each RGB component
2641 YPrimeCbCr2RGBPrimeFunctor(component_type max)
2645 /** apply the transformation
2648 result_type operator()(V const & ycbcr) const
2650 typedef detail::RequiresExplicitCast<component_type> Convert;
2651 component_type y = Convert::cast(ycbcr[0] - 16.0);
2652 component_type cb = Convert::cast(ycbcr[1] - 128.0);
2653 component_type cr = Convert::cast(ycbcr[2] - 128.0);
2655 component_type nred = Convert::cast(0.00456621*y + 0.006258928571*cr);
2656 component_type ngreen = Convert::cast(0.00456621*y - 0.001536322706*cb - 0.003188108420*cr);
2657 component_type nblue = Convert::cast(0.00456621*y + 0.007910714286*cb);
2658 return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
2659 NumericTraits<T>::fromRealPromote(ngreen * max_),
2660 NumericTraits<T>::fromRealPromote(nblue * max_));
2665 class FunctorTraits<YPrimeCbCr2RGBPrimeFunctor<T> >
2666 : public FunctorTraitsBase<YPrimeCbCr2RGBPrimeFunctor<T> >
2669 typedef VigraTrueType isUnaryFunctor;
2675 Polar coordinates of standard colors:
2676 =====================================
2678 Lab: black = [320.002, 0, 0]
2679 Luv: black = [347.827, 0, 0]
2680 YPbPr: black = [341.352, 0, 0]
2681 YCbCr: black = [341.352, 0, 0]
2682 YIQ: black = [19.5807, 0, 0]
2683 YUV: black = [346.557, 0, 0]
2684 Lab: red = [1.20391e-05, 0.532406, 0.781353]
2685 Luv: red = [360, 0.532406, 1]
2686 YPbPr: red = [360, 0.299, 0.988419]
2687 YCbCr: red = [360, 0.299, 0.988417]
2688 YIQ: red = [360, 0.299, 1]
2689 YUV: red = [360, 0.299, 1]
2690 Lab: green = [96.0184, 0.877351, 0.895108]
2691 Luv: green = [115.552, 0.877351, 0.758352]
2692 YPbPr: green = [123.001, 0.587, 1]
2693 YCbCr: green = [123.001, 0.587, 0.999996]
2694 YIQ: green = [137.231, 0.587, 0.933362]
2695 YUV: green = [137.257, 0.587, 0.933931]
2696 Lab: blue = [266.287, 0.322957, 0.999997]
2697 Luv: blue = [253.7, 0.322957, 0.729883]
2698 YPbPr: blue = [242.115, 0.114, 0.948831]
2699 YCbCr: blue = [242.115, 0.114, 0.948829]
2700 YIQ: blue = [243.585, 0.114, 0.707681]
2701 YUV: blue = [243.639, 0.114, 0.707424]
2702 Lab: yellow = [62.8531, 0.971395, 0.724189]
2703 Luv: yellow = [73.7, 0.971395, 0.597953]
2704 YPbPr: yellow = [62.1151, 0.886, 0.948831]
2705 YCbCr: yellow = [62.1149, 0.886, 0.948829]
2706 YIQ: yellow = [63.5851, 0.886, 0.707681]
2707 YUV: yellow = [63.6393, 0.886, 0.707424]
2708 Lab: magenta = [288.237, 0.603235, 0.863482]
2709 Luv: magenta = [295.553, 0.603235, 0.767457]
2710 YPbPr: magenta = [303.001, 0.413, 1]
2711 YCbCr: magenta = [303.001, 0.413, 0.999996]
2712 YIQ: magenta = [317.231, 0.413, 0.933362]
2713 YUV: magenta = [317.257, 0.413, 0.933931]
2714 Lab: cyan = [156.378, 0.911133, 0.374577]
2715 Luv: cyan = [180, 0.911133, 0.402694]
2716 YPbPr: cyan = [180, 0.701, 0.988419]
2717 YCbCr: cyan = [180, 0.701, 0.988417]
2718 YIQ: cyan = [180, 0.701, 1]
2719 YUV: cyan = [180, 0.701, 1]
2720 Lab: white = [320.002, 1, 0]
2721 Luv: white = [14.3606, 1, 3.26357e-06]
2722 YPbPr: white = [341.352, 1, 0]
2723 YCbCr: white = [341.352, 1, 0]
2724 YIQ: white = [154.581, 1, 1.24102e-16]
2725 YUV: white = [229.992, 1, 9.81512e-17]
2729 /** \ingroup ColorConversions
2730 \defgroup PolarColors Polar Color Coordinates
2732 Transform colors from/to a polar representation (hue, brighness, saturation).
2733 In many situations, this is more inituitive than direct initialization in a
2734 particular color space. The polar coordinates are
2735 normalized so that a color angle of 0 degrees is always associated with red
2736 (green is at about 120 degrees, blue at about 240 degrees - exact values differ
2737 between color spaces). A saturation of 1 is the highest saturation that any RGB color
2738 gets after transformation into the respective color space, and saturation 0 corresponds to
2739 gray. Thus, different color spaces become somewhat comparable.
2742 /** \brief Init L*a*b* color triple from polar representation.
2744 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2747 <b> Declarations:</b>
2750 TinyVector<float, 3>
2751 polar2Lab(double color, double brightness, double saturation);
2753 TinyVector<float, 3>
2754 polar2Lab(TinyVector<float, 3> const & polar);
2757 \arg color - the color angle in degrees
2758 \arg brightness - between 0 and 1
2759 \arg saturation - between 0 and 1
2761 L*a*b* polar coordinates of some important colors:
2764 black = [*, 0, 0] * - arbitrary
2765 white = [*, 1, 0] * - arbitrary
2767 red = [ 0, 0.532406, 0.781353]
2768 yellow = [62.8531, 0.971395, 0.724189]
2769 green = [96.0184, 0.877351, 0.895108]
2770 cyan = [156.378, 0.911133, 0.374577]
2771 blue = [266.287, 0.322957, 0.999997]
2772 magenta = [288.237, 0.603235, 0.863482]
2775 inline TinyVector<float, 3>
2776 polar2Lab(double color, double brightness, double saturation)
2778 double angle = (color+39.9977)/180.0*M_PI;
2779 double normsat = saturation*133.809;
2781 TinyVector<float, 3> result;
2782 result[0] = float(100.0*brightness);
2783 result[1] = float(normsat*VIGRA_CSTD::cos(angle));
2784 result[2] = float(normsat*VIGRA_CSTD::sin(angle));
2790 TinyVector<float, 3>
2791 polar2Lab(V const & polar)
2793 return polar2Lab(polar[0], polar[1], polar[2]);
2796 /** \brief Create polar representation form L*a*b*
2798 <b> Declaration:</b>
2802 TinyVector<float, 3> lab2Polar(TinyVector<float, 3> const & lab);
2806 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2809 This realizes the inverse of the transformation described in
2813 TinyVector<float, 3>
2814 lab2Polar(V const & lab)
2816 TinyVector<float, 3> result;
2817 result[1] = float(lab[0]/100.0);
2818 double angle = (lab[1] == 0.0 && lab[2] == 0.0)
2820 : VIGRA_CSTD::atan2(lab[2], lab[1])/M_PI*180.0-39.9977;
2821 result[0] = angle < 0.0 ?
2822 float(angle + 360.0) :
2824 result[2] = float(VIGRA_CSTD::sqrt(lab[1]*lab[1] + lab[2]*lab[2])/133.809);
2828 /** \brief Init L*u*v* color triple from polar representation.
2830 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2833 <b> Declarations:</b>
2836 TinyVector<float, 3>
2837 polar2Luv(double color, double brightness, double saturation);
2839 TinyVector<float, 3>
2840 polar2Luv(TinyVector<float, 3> const & polar);
2843 \arg color - the color angle in degrees
2844 \arg brightness - between 0 and 1
2845 \arg saturation - between 0 and 1
2847 L*u*v* polar coordinates of some important colors:
2850 black = [*, 0, 0] * - arbitrary
2851 white = [*, 1, 0] * - arbitrary
2853 red = [ 0, 0.532406, 1]
2854 yellow = [ 73.7, 0.971395, 0.597953]
2855 green = [115.552, 0.877351, 0.758352]
2856 cyan = [ 180.0, 0.911133, 0.402694]
2857 blue = [ 253.7, 0.322957, 0.729883]
2858 magenta = [295.553, 0.603235, 0.767457]
2861 inline TinyVector<float, 3>
2862 polar2Luv(double color, double brightness, double saturation)
2864 double angle = (color+12.1727)/180.0*M_PI;
2865 double normsat = saturation*179.04;
2867 TinyVector<float, 3> result;
2868 result[0] = float(100.0*brightness);
2869 result[1] = float(normsat*VIGRA_CSTD::cos(angle));
2870 result[2] = float(normsat*VIGRA_CSTD::sin(angle));
2875 TinyVector<float, 3>
2876 polar2Luv(V const & polar)
2878 return polar2Luv(polar[0], polar[1], polar[2]);
2881 /** \brief Create polar representation form L*u*v*
2883 <b> Declaration:</b>
2887 TinyVector<float, 3> luv2Polar(TinyVector<float, 3> const & luv);
2891 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2894 This realizes the inverse of the transformation described in
2898 TinyVector<float, 3>
2899 luv2Polar(V const & luv)
2901 TinyVector<float, 3> result;
2902 result[1] = float(luv[0]/100.0);
2903 double angle = (luv[1] == 0.0 && luv[2] == 0.0)
2905 : VIGRA_CSTD::atan2(luv[2], luv[1])/M_PI*180.0-12.1727;
2906 result[0] = angle < 0.0 ?
2907 float(angle + 360.0) :
2909 result[2] = float(VIGRA_CSTD::sqrt(luv[1]*luv[1] + luv[2]*luv[2])/179.04);
2913 /** \brief Init Y'PbPr color triple from polar representation.
2915 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2918 <b> Declarations:</b>
2921 TinyVector<float, 3>
2922 polar2YPrimePbPr(double color, double brightness, double saturation);
2924 TinyVector<float, 3>
2925 polar2YPrimePbPr(TinyVector<float, 3> const & polar);
2928 \arg color - the color angle in degrees
2929 \arg brightness - between 0 and 1
2930 \arg saturation - between 0 and 1
2932 Y'PbPr polar coordinates of some important colors:
2935 black = [*, 0, 0] * - arbitrary
2936 white = [*, 1, 0] * - arbitrary
2938 red = [ 0, 0.299, 0.988419]
2939 yellow = [62.1151, 0.886, 0.948831]
2940 green = [123.001, 0.587, 1]
2941 cyan = [ 180.0, 0.701, 0.988419]
2942 blue = [242.115, 0.114, 0.948831]
2943 magenta = [303.001, 0.413, 1]
2946 inline TinyVector<float, 3>
2947 polar2YPrimePbPr(double color, double brightness, double saturation)
2949 double angle = (color+18.6481)/180.0*M_PI;
2950 double normsat = saturation*0.533887;
2952 TinyVector<float, 3> result;
2953 result[0] = float(brightness);
2954 result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
2955 result[2] = float(normsat*VIGRA_CSTD::cos(angle));
2960 TinyVector<float, 3>
2961 polar2YPrimePbPr(V const & polar)
2963 return polar2YPrimePbPr(polar[0], polar[1], polar[2]);
2966 /** \brief Create polar representation form Y'PbPr
2968 <b> Declaration:</b>
2972 TinyVector<float, 3> yPrimePbPr2Polar(TinyVector<float, 3> const & ypbpr);
2976 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
2979 This realizes the inverse of the transformation described in
2980 \ref polar2YPrimePbPr().
2983 TinyVector<float, 3>
2984 yPrimePbPr2Polar(V const & ypbpr)
2986 TinyVector<float, 3> result;
2987 result[1] = float(ypbpr[0]);
2988 double angle = (ypbpr[1] == 0.0 && ypbpr[2] == 0.0)
2990 : VIGRA_CSTD::atan2(-ypbpr[1], ypbpr[2])/M_PI*180.0-18.6481;
2991 result[0] = angle < 0.0 ?
2992 float(angle + 360.0) :
2994 result[2] = float(VIGRA_CSTD::sqrt(ypbpr[1]*ypbpr[1] + ypbpr[2]*ypbpr[2])/0.533887);
2998 /** \brief Init Y'CbCr color triple from polar representation.
3000 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
3003 <b> Declarations:</b>
3006 TinyVector<float, 3>
3007 polar2YPrimeCbCr(double color, double brightness, double saturation);
3009 TinyVector<float, 3>
3010 polar2YPrimeCbCr(TinyVector<float, 3> const & polar);
3013 \arg color - the color angle in degrees
3014 \arg brightness - between 0 and 1
3015 \arg saturation - between 0 and 1
3017 Y'CbCr polar coordinates of some important colors:
3020 black = [*, 0, 0] * - arbitrary
3021 white = [*, 1, 0] * - arbitrary
3023 red = [ 0, 0.299, 0.988419]
3024 yellow = [62.1151, 0.886, 0.948831]
3025 green = [123.001, 0.587, 1]
3026 cyan = [ 180.0, 0.701, 0.988419]
3027 blue = [242.115, 0.114, 0.948831]
3028 magenta = [303.001, 0.413, 1]
3031 inline TinyVector<float, 3>
3032 polar2YPrimeCbCr(double color, double brightness, double saturation)
3034 double angle = (color+18.6482)/180.0*M_PI;
3035 double normsat = saturation*119.591;
3037 TinyVector<float, 3> result;
3038 result[0] = float(brightness*219.0 + 16.0);
3039 result[1] = float(-normsat*VIGRA_CSTD::sin(angle)+128.0);
3040 result[2] = float(normsat*VIGRA_CSTD::cos(angle)+128.0);
3045 TinyVector<float, 3>
3046 polar2YPrimeCbCr(V const & polar)
3048 return polar2YPrimeCbCr(polar[0], polar[1], polar[2]);
3051 /** \brief Create polar representation form Y'CbCr
3053 <b> Declaration:</b>
3057 TinyVector<float, 3> yPrimeCbCr2Polar(TinyVector<float, 3> const & ycbcr);
3061 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
3064 This realizes the inverse of the transformation described in
3065 \ref polar2YPrimeCbCr().
3068 TinyVector<float, 3>
3069 yPrimeCbCr2Polar(V const & ycbcr)
3071 TinyVector<float, 3> result;
3072 result[1] = float((ycbcr[0]-16.0)/219.0);
3073 double cb = ycbcr[1]-128.0;
3074 double cr = ycbcr[2]-128.0;
3075 double angle = (cb == 0.0 && cr == 0.0)
3077 : VIGRA_CSTD::atan2(-cb, cr)/M_PI*180.0-18.6482;
3078 result[0] = angle < 0.0 ?
3079 float(angle + 360.0) :
3081 result[2] = float(VIGRA_CSTD::sqrt(cb*cb + cr*cr)/119.591);
3085 /** \brief Init Y'IQ color triple from polar representation.
3087 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
3090 <b> Declarations:</b>
3093 TinyVector<float, 3>
3094 polar2YPrimeIQ(double color, double brightness, double saturation);
3096 TinyVector<float, 3>
3097 polar2YPrimeIQ(TinyVector<float, 3> const & polar);
3100 \arg color - the color angle in degrees
3101 \arg brightness - between 0 and 1
3102 \arg saturation - between 0 and 1
3104 Y'IQ polar coordinates of some important colors:
3107 black = [*, 0, 0] * - arbitrary
3108 white = [*, 1, 0] * - arbitrary
3110 red = [ 0, 0.299, 1]
3111 yellow = [63.5851, 0.886, 0.707681]
3112 green = [137.231, 0.587, 0.933362]
3113 cyan = [ 180.0, 0.701, 1]
3114 blue = [243.585, 0.114, 0.707681]
3115 magenta = [317.231, 0.413, 0.933362]
3118 inline TinyVector<float, 3>
3119 polar2YPrimeIQ(double color, double brightness, double saturation)
3121 double angle = (color-19.5807)/180.0*M_PI;
3122 double normsat = saturation*0.632582;
3124 TinyVector<float, 3> result;
3125 result[0] = float(brightness);
3126 result[1] = float(normsat*VIGRA_CSTD::cos(angle));
3127 result[2] = float(-normsat*VIGRA_CSTD::sin(angle));
3132 TinyVector<float, 3>
3133 polar2YPrimeIQ(V const & polar)
3135 return polar2YPrimeIQ(polar[0], polar[1], polar[2]);
3138 /** \brief Create polar representation form Y'IQ
3140 <b> Declaration:</b>
3144 TinyVector<float, 3> yPrimeIQ2Polar(TinyVector<float, 3> const & yiq);
3148 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
3151 This realizes the inverse of the transformation described in
3152 \ref polar2YPrimeIQ().
3155 TinyVector<float, 3>
3156 yPrimeIQ2Polar(V const & yiq)
3158 TinyVector<float, 3> result;
3159 result[1] = float(yiq[0]);
3160 double angle = (yiq[1] == 0.0 && yiq[2] == 0.0)
3162 : VIGRA_CSTD::atan2(-yiq[2], yiq[1])/M_PI*180.0+19.5807;
3163 result[0] = angle < 0.0 ?
3164 float(angle + 360.0) :
3166 result[2] = float(VIGRA_CSTD::sqrt(yiq[1]*yiq[1] + yiq[2]*yiq[2])/0.632582);
3170 /** \brief Init Y'UV color triple from polar representation.
3172 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
3175 <b> Declarations:</b>
3178 TinyVector<float, 3>
3179 polar2YPrimeUV(double color, double brightness, double saturation);
3181 TinyVector<float, 3>
3182 polar2YPrimeUV(TinyVector<float, 3> const & polar);
3185 \arg color - the color angle in degrees
3186 \arg brightness - between 0 and 1
3187 \arg saturation - between 0 and 1
3189 Y'UV polar coordinates of some important colors:
3192 black = [*, 0, 0] * - arbitrary
3193 white = [*, 1, 0] * - arbitrary
3195 red = [ 0, 0.299, 1]
3196 yellow = [63.5851, 0.886, 0.707681]
3197 green = [137.231, 0.587, 0.933362]
3198 cyan = [ 180.0, 0.701, 1]
3199 blue = [243.585, 0.114, 0.707681]
3200 magenta = [317.231, 0.413, 0.933362]
3203 inline TinyVector<float, 3>
3204 polar2YPrimeUV(double color, double brightness, double saturation)
3206 double angle = (color+13.4569)/180.0*M_PI;
3207 double normsat = saturation*0.632324;
3209 TinyVector<float, 3> result;
3210 result[0] = float(brightness);
3211 result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
3212 result[2] = float(normsat*VIGRA_CSTD::cos(angle));
3217 TinyVector<float, 3>
3218 polar2YPrimeUV(V const & polar)
3220 return polar2YPrimeUV(polar[0], polar[1], polar[2]);
3223 /** \brief Create polar representation form Y'UV
3225 <b> Declaration:</b>
3229 TinyVector<float, 3> yPrimeUV2Polar(TinyVector<float, 3> const & yuv);
3233 <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
3236 This realizes the inverse of the transformation described in
3237 \ref polar2YPrimeUV().
3240 TinyVector<float, 3>
3241 yPrimeUV2Polar(V const & yuv)
3243 TinyVector<float, 3> result;
3244 result[1] = float(yuv[0]);
3245 double angle = (yuv[1] == 0.0 && yuv[2] == 0.0)
3247 : VIGRA_CSTD::atan2(-yuv[1], yuv[2])/M_PI*180.0-13.4569;
3248 result[0] = angle < 0.0 ?
3249 float(angle + 360.0) :
3251 result[2] = float(VIGRA_CSTD::sqrt(yuv[1]*yuv[1] + yuv[2]*yuv[2])/0.632324);
3257 } // namespace vigra
3259 #endif /* VIGRA_COLORCONVERSIONS_HXX */