|
koethe@1199
|
1 |
/************************************************************************/
|
|
koethe@1199
|
2 |
/* */
|
|
koethe@1199
|
3 |
/* Copyright 1998-2002 by Ullrich Koethe */
|
|
koethe@1199
|
4 |
/* */
|
|
koethe@1199
|
5 |
/* This file is part of the VIGRA computer vision library. */
|
|
koethe@1199
|
6 |
/* The VIGRA Website is */
|
|
ullrich@2466
|
7 |
/* http://hci.iwr.uni-heidelberg.de/vigra/ */
|
|
koethe@1199
|
8 |
/* Please direct questions, bug reports, and contributions to */
|
|
koethe@1714
|
9 |
/* ullrich.koethe@iwr.uni-heidelberg.de or */
|
|
koethe@1714
|
10 |
/* vigra@informatik.uni-hamburg.de */
|
|
koethe@1199
|
11 |
/* */
|
|
koethe@1199
|
12 |
/* Permission is hereby granted, free of charge, to any person */
|
|
koethe@1199
|
13 |
/* obtaining a copy of this software and associated documentation */
|
|
koethe@1199
|
14 |
/* files (the "Software"), to deal in the Software without */
|
|
koethe@1199
|
15 |
/* restriction, including without limitation the rights to use, */
|
|
koethe@1199
|
16 |
/* copy, modify, merge, publish, distribute, sublicense, and/or */
|
|
koethe@1199
|
17 |
/* sell copies of the Software, and to permit persons to whom the */
|
|
koethe@1199
|
18 |
/* Software is furnished to do so, subject to the following */
|
|
koethe@1199
|
19 |
/* conditions: */
|
|
koethe@1199
|
20 |
/* */
|
|
koethe@1199
|
21 |
/* The above copyright notice and this permission notice shall be */
|
|
koethe@1199
|
22 |
/* included in all copies or substantial portions of the */
|
|
koethe@1199
|
23 |
/* Software. */
|
|
koethe@1199
|
24 |
/* */
|
|
koethe@1199
|
25 |
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
|
|
koethe@1199
|
26 |
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
|
|
koethe@1199
|
27 |
/* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
|
|
koethe@1199
|
28 |
/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
|
|
koethe@1199
|
29 |
/* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
|
|
koethe@1199
|
30 |
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
|
|
koethe@1199
|
31 |
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
|
|
koethe@1199
|
32 |
/* OTHER DEALINGS IN THE SOFTWARE. */
|
|
koethe@1199
|
33 |
/* */
|
|
koethe@1199
|
34 |
/************************************************************************/
|
|
koethe@1199
|
35 |
|
|
koethe@1199
|
36 |
|
|
koethe@1199
|
37 |
#ifndef VIGRA_COLORCONVERSIONS_HXX
|
|
koethe@1199
|
38 |
#define VIGRA_COLORCONVERSIONS_HXX
|
|
koethe@1199
|
39 |
|
|
koethe@1199
|
40 |
#include <cmath>
|
|
meine@1364
|
41 |
#include "mathutil.hxx"
|
|
meine@1364
|
42 |
#include "rgbvalue.hxx"
|
|
meine@1364
|
43 |
#include "functortraits.hxx"
|
|
koethe@1199
|
44 |
|
|
koethe@1710
|
45 |
namespace vigra {
|
|
koethe@1710
|
46 |
|
|
koethe@1710
|
47 |
namespace detail
|
|
koethe@1710
|
48 |
{
|
|
koethe@1710
|
49 |
|
|
ullrich@2455
|
50 |
template<class ValueType>
|
|
ullrich@2455
|
51 |
inline ValueType gammaCorrection(double value, double gamma)
|
|
koethe@1710
|
52 |
{
|
|
ullrich@2455
|
53 |
typedef typename NumericTraits<ValueType>::RealPromote Promote;
|
|
ullrich@2455
|
54 |
return NumericTraits<ValueType>::fromRealPromote(
|
|
ullrich@2455
|
55 |
RequiresExplicitCast<Promote>::cast(
|
|
ullrich@2455
|
56 |
(value < 0.0)
|
|
ullrich@2455
|
57 |
? -std::pow(-value, gamma)
|
|
ullrich@2455
|
58 |
: std::pow(value, gamma)));
|
|
koethe@1710
|
59 |
}
|
|
koethe@1710
|
60 |
|
|
ullrich@2455
|
61 |
template<class ValueType>
|
|
ullrich@2455
|
62 |
inline ValueType gammaCorrection(double value, double gamma, double norm)
|
|
koethe@1710
|
63 |
{
|
|
ullrich@2455
|
64 |
typedef typename NumericTraits<ValueType>::RealPromote Promote;
|
|
ullrich@2455
|
65 |
return NumericTraits<ValueType>::fromRealPromote(
|
|
ullrich@2455
|
66 |
RequiresExplicitCast<Promote>::cast(
|
|
ullrich@2455
|
67 |
(value < 0.0)
|
|
ullrich@2455
|
68 |
? -norm*std::pow(-value/norm, gamma)
|
|
ullrich@2455
|
69 |
: norm*std::pow(value/norm, gamma)));
|
|
koethe@1710
|
70 |
}
|
|
koethe@1710
|
71 |
|
|
ullrich@2455
|
72 |
template<class ValueType>
|
|
ullrich@2455
|
73 |
inline ValueType sRGBCorrection(double value, double norm)
|
|
koethe@1710
|
74 |
{
|
|
koethe@1710
|
75 |
value /= norm;
|
|
ullrich@2455
|
76 |
typedef typename NumericTraits<ValueType>::RealPromote Promote;
|
|
ullrich@2455
|
77 |
return NumericTraits<ValueType>::fromRealPromote(
|
|
ullrich@2455
|
78 |
RequiresExplicitCast<ValueType>::cast(
|
|
ullrich@2455
|
79 |
(value <= 0.0031308)
|
|
ullrich@2455
|
80 |
? norm*12.92*value
|
|
ullrich@2455
|
81 |
: norm*(1.055*std::pow(value, 0.41666666666666667) - 0.055)));
|
|
koethe@1710
|
82 |
}
|
|
koethe@1710
|
83 |
|
|
ullrich@2455
|
84 |
template<class ValueType>
|
|
ullrich@2455
|
85 |
inline ValueType inverse_sRGBCorrection(double value, double norm)
|
|
koethe@1710
|
86 |
{
|
|
koethe@1710
|
87 |
value /= norm;
|
|
ullrich@2455
|
88 |
typedef typename NumericTraits<ValueType>::RealPromote Promote;
|
|
ullrich@2455
|
89 |
return NumericTraits<ValueType>::fromRealPromote(
|
|
ullrich@2455
|
90 |
RequiresExplicitCast<ValueType>::cast(
|
|
ullrich@2455
|
91 |
(value <= 0.04045)
|
|
ullrich@2455
|
92 |
? norm*value / 12.92
|
|
ullrich@2455
|
93 |
: norm*VIGRA_CSTD::pow((value + 0.055)/1.055, 2.4)));
|
|
koethe@1710
|
94 |
}
|
|
koethe@1710
|
95 |
|
|
koethe@1710
|
96 |
|
|
koethe@1710
|
97 |
} // namespace detail
|
|
koethe@1710
|
98 |
|
|
koethe@1713
|
99 |
/** \defgroup ColorConversions Color Space Conversions
|
|
koethe@1199
|
100 |
|
|
koethe@1432
|
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.
|
|
koethe@1199
|
102 |
|
|
koethe@1623
|
103 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
104 |
Namespace: vigra
|
|
koethe@1199
|
105 |
|
|
koethe@1199
|
106 |
<UL>
|
|
koethe@1432
|
107 |
<LI> <b>RGB/sRGB/R'G'B'</b><br>
|
|
koethe@1199
|
108 |
<em>linear and non-linear (gamma corrected) additive color</em>
|
|
koethe@1199
|
109 |
<p>
|
|
koethe@1623
|
110 |
<UL style="list-style-image:url(documents/bullet.gif)">
|
|
koethe@1623
|
111 |
<LI> \ref vigra::RGB2sRGBFunctor
|
|
koethe@1623
|
112 |
<LI> \ref vigra::sRGB2RGBFunctor
|
|
koethe@1623
|
113 |
<LI> \ref vigra::RGB2RGBPrimeFunctor
|
|
koethe@1623
|
114 |
<LI> \ref vigra::RGBPrime2RGBFunctor
|
|
koethe@1623
|
115 |
</UL><p>
|
|
koethe@1199
|
116 |
<LI> <b>XYZ</b><br>
|
|
koethe@1199
|
117 |
<em>device independent color representation
|
|
koethe@1199
|
118 |
(according to Publication CIE No 15.2 "Colorimetry"
|
|
koethe@1199
|
119 |
and ITU-R Recommendation BT.709)</em>
|
|
koethe@1199
|
120 |
<p>
|
|
koethe@1623
|
121 |
<UL style="list-style-image:url(documents/bullet.gif)">
|
|
koethe@1623
|
122 |
<LI> \ref vigra::RGB2XYZFunctor
|
|
koethe@1623
|
123 |
<LI> \ref vigra::RGBPrime2XYZFunctor
|
|
koethe@1623
|
124 |
<LI> \ref vigra::XYZ2RGBFunctor
|
|
koethe@1623
|
125 |
<LI> \ref vigra::XYZ2RGBPrimeFunctor
|
|
koethe@1623
|
126 |
</UL><p>
|
|
koethe@1199
|
127 |
<LI> <b>L*a*b* </b><br>
|
|
koethe@1199
|
128 |
<em>perceptually uniform color representation
|
|
koethe@1199
|
129 |
(according to Publication CIE No 15.2 "Colorimetry" and
|
|
koethe@1199
|
130 |
ITU-R Recommendation BT.709)</em>
|
|
koethe@1199
|
131 |
<p>
|
|
koethe@1623
|
132 |
<UL style="list-style-image:url(documents/bullet.gif)">
|
|
koethe@1623
|
133 |
<LI> \ref vigra::RGB2LabFunctor
|
|
koethe@1623
|
134 |
<LI> \ref vigra::RGBPrime2LabFunctor
|
|
koethe@1623
|
135 |
<LI> \ref vigra::XYZ2LabFunctor
|
|
koethe@1623
|
136 |
<LI> \ref vigra::Lab2RGBFunctor
|
|
koethe@1623
|
137 |
<LI> \ref vigra::Lab2RGBPrimeFunctor
|
|
koethe@1623
|
138 |
<LI> \ref vigra::Lab2XYZFunctor
|
|
koethe@1623
|
139 |
<LI> \ref polar2Lab()
|
|
koethe@1623
|
140 |
<LI> \ref lab2Polar()
|
|
koethe@1623
|
141 |
</UL><p>
|
|
koethe@1199
|
142 |
<LI> <b>L*u*v* </b><br>
|
|
koethe@1199
|
143 |
<em>perceptually uniform color representation
|
|
koethe@1199
|
144 |
(according to Publication CIE No 15.2 "Colorimetry" and
|
|
koethe@1199
|
145 |
ITU-R Recommendation BT.709)</em>
|
|
koethe@1199
|
146 |
<p>
|
|
koethe@1623
|
147 |
<UL style="list-style-image:url(documents/bullet.gif)">
|
|
koethe@1623
|
148 |
<LI> \ref vigra::RGB2LuvFunctor
|
|
koethe@1623
|
149 |
<LI> \ref vigra::RGBPrime2LuvFunctor
|
|
koethe@1623
|
150 |
<LI> \ref vigra::XYZ2LuvFunctor
|
|
koethe@1623
|
151 |
<LI> \ref vigra::Luv2RGBFunctor
|
|
koethe@1623
|
152 |
<LI> \ref vigra::Luv2RGBPrimeFunctor
|
|
koethe@1623
|
153 |
<LI> \ref vigra::Luv2XYZFunctor
|
|
koethe@1623
|
154 |
<LI> \ref polar2Luv()
|
|
koethe@1623
|
155 |
<LI> \ref luv2Polar()
|
|
koethe@1623
|
156 |
</UL><p>
|
|
koethe@1199
|
157 |
<LI> <b>Y'PbPr and Y'CbCr </b><br>
|
|
koethe@1199
|
158 |
<em>color difference coding
|
|
koethe@1199
|
159 |
(according to ITU-R Recommendation BT. 601)</em>
|
|
koethe@1199
|
160 |
<p>
|
|
koethe@1623
|
161 |
<UL style="list-style-image:url(documents/bullet.gif)">
|
|
koethe@1623
|
162 |
<LI> \ref vigra::RGBPrime2YPrimePbPrFunctor
|
|
koethe@1623
|
163 |
<LI> \ref vigra::YPrimePbPr2RGBPrimeFunctor
|
|
koethe@1623
|
164 |
<LI> \ref polar2YPrimePbPr()
|
|
koethe@1623
|
165 |
<LI> \ref yPrimePbPr2Polar()
|
|
koethe@1623
|
166 |
<LI> \ref vigra::RGBPrime2YPrimeCbCrFunctor
|
|
koethe@1623
|
167 |
<LI> \ref vigra::YPrimeCbCr2RGBPrimeFunctor
|
|
koethe@1623
|
168 |
<LI> \ref polar2YPrimeCbCr()
|
|
koethe@1623
|
169 |
<LI> \ref yPrimeCbCr2Polar()
|
|
koethe@1623
|
170 |
</UL><p>
|
|
koethe@1199
|
171 |
<LI> <b>Y'UV and Y'IQ </b><br>
|
|
koethe@1199
|
172 |
<em>analog video coding according to NTSC and PAL standards</em>
|
|
koethe@1199
|
173 |
<p>
|
|
koethe@1623
|
174 |
<UL style="list-style-image:url(documents/bullet.gif)">
|
|
koethe@1623
|
175 |
<LI> \ref vigra::RGBPrime2YPrimeUVFunctor
|
|
koethe@1623
|
176 |
<LI> \ref vigra::YPrimeUV2RGBPrimeFunctor
|
|
koethe@1623
|
177 |
<LI> \ref polar2YPrimeUV()
|
|
koethe@1623
|
178 |
<LI> \ref yPrimeUV2Polar()
|
|
koethe@1623
|
179 |
<LI> \ref vigra::RGBPrime2YPrimeIQFunctor
|
|
koethe@1623
|
180 |
<LI> \ref vigra::YPrimeIQ2RGBPrimeFunctor
|
|
koethe@1623
|
181 |
<LI> \ref polar2YPrimeIQ()
|
|
koethe@1623
|
182 |
<LI> \ref yPrimeIQ2Polar()
|
|
koethe@1623
|
183 |
</UL><p>
|
|
koethe@1199
|
184 |
</UL>
|
|
koethe@1199
|
185 |
|
|
koethe@1199
|
186 |
\anchor _details
|
|
koethe@1199
|
187 |
This module provides conversion from RGB/R'G'B' into more perceptually uniform
|
|
koethe@1199
|
188 |
color spaces. In image analysis, colors are usually converted into another color space
|
|
koethe@1199
|
189 |
in order to get good estimates of perceived color differences by just calculating
|
|
koethe@1199
|
190 |
Euclidean distances between the transformed colors. The L*a*b* and L*u*v* were
|
|
koethe@1199
|
191 |
designed with exactly this application in mind and thus give the best results. But these
|
|
koethe@1199
|
192 |
conversions are also the most computationally demanding. The Y'PbPr color difference
|
|
koethe@1432
|
193 |
space (designed for coding digital video) is computationally much cheaper, and
|
|
koethe@1199
|
194 |
almost as good. Y'CbCr represents esentially the same transformation, but the color values
|
|
koethe@1199
|
195 |
are scaled so that they can be stored with 8 bits per channel with minimal loss of
|
|
koethe@1199
|
196 |
information. The other transformations are of lesser interest here: XYZ is a device independent
|
|
koethe@1199
|
197 |
(but not perceptually uniform) color representation, and Y'IQ and Y'UV are the color
|
|
koethe@1199
|
198 |
spaces used by the PAL and NTSC analog video standards. Detailed information about
|
|
koethe@1199
|
199 |
these color spaces and their transformations can be found in
|
|
koethe@1199
|
200 |
<a href="http://www.poynton.com/ColorFAQ.html">Charles Poynton's Color FAQ</a>
|
|
koethe@1199
|
201 |
|
|
koethe@1199
|
202 |
When you want to perform a color conversion, you must first know in which
|
|
koethe@1199
|
203 |
color space the data are given. Although this sounds trivial, it is
|
|
koethe@1436
|
204 |
quite often done wrong, because the distinction between RGB and sRGB (still images) or R'G'B'
|
|
koethe@1436
|
205 |
(digital video) is frequently overlooked: nowadays, most still images are stored in
|
|
koethe@1432
|
206 |
sRGB space, and treating them as RGB leads to wrong results (although the color primaries
|
|
koethe@1432
|
207 |
are named the same). RGB and R'G'B' are related by a so called <em>gamma correction</em>:
|
|
koethe@1199
|
208 |
|
|
koethe@1199
|
209 |
\f[
|
|
koethe@1432
|
210 |
C' = C_{max} \left(\frac{C_{RGB}}{C_{max}} \right)^{0.45} \qquad
|
|
koethe@1199
|
211 |
\f]
|
|
koethe@1199
|
212 |
|
|
koethe@1432
|
213 |
where C represents one of the color channels R, G, and B, and \f$ C_{max} \f$ usually equals 255.
|
|
koethe@1432
|
214 |
The sRGB color space realizes a slight enhancement of this definition:
|
|
koethe@1432
|
215 |
|
|
koethe@1432
|
216 |
\f[
|
|
koethe@1623
|
217 |
C_{sRGB} = \left\{\begin{array}{ll}
|
|
koethe@1623
|
218 |
12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.00304 \\
|
|
koethe@1623
|
219 |
C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.055\right) & \textrm{ otherwise}
|
|
koethe@1623
|
220 |
\end{array} \right.
|
|
koethe@1432
|
221 |
\f]
|
|
koethe@1432
|
222 |
|
|
koethe@1433
|
223 |
sRGB has now become a widely accepted international standard (IEC 61966-2.1) which is used by most
|
|
koethe@1433
|
224 |
consumer products (digital cameras, printers, and screens). In practice, you can
|
|
koethe@1432
|
225 |
distinguish between linear and gamma-corrected red, green, and blue by displaying the images: if they look
|
|
koethe@1432
|
226 |
too dark, they are probably RGB, if they are OK, they are likely sRGB. (However, there are still a few older
|
|
koethe@1433
|
227 |
graphics cards and display programs which silently apply an additional gamma correction to every image,
|
|
koethe@1436
|
228 |
so that RGB appears correct and sRGB is too bright.) Whether or not the data are represented
|
|
koethe@1436
|
229 |
in the sRGB color space can also be seen in the color space tag of an image's EXIF data, if available.
|
|
koethe@1432
|
230 |
|
|
koethe@1199
|
231 |
The distinction between RGB and R'G'B' is important because some conversions start at
|
|
koethe@1199
|
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).
|
|
koethe@1199
|
233 |
The names of VIGRA's color conversion functors always make clear to which color space
|
|
koethe@1199
|
234 |
they must be applied.
|
|
koethe@1432
|
235 |
|
|
koethe@1713
|
236 |
In addition VIGRA provides a <em>\ref PolarColors "polar coordinate interface"</em>
|
|
koethe@1199
|
237 |
to several color spaces (L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV). This
|
|
koethe@1199
|
238 |
interface makes use of the fact that these color spaces are conceptually similar:
|
|
koethe@1199
|
239 |
they represent colors by a "brightness" coordinate (L* or Y') and a pair of
|
|
koethe@1199
|
240 |
"chromaticity" coordinates that span a plane of colors with equal brightness.
|
|
koethe@1199
|
241 |
The polar representation transforms chroma coordinates into a color "angle"
|
|
koethe@1199
|
242 |
(similar to hue in the HSV system) and a "saturation". The polar coordinates are
|
|
koethe@1199
|
243 |
normalized so that a color angle of 0 degrees is always associated with red
|
|
koethe@1199
|
244 |
(green is at about 120 degrees, blue at about 240 degrees - exact values differ
|
|
koethe@1199
|
245 |
between color spaces). A saturation of 1 is the highest saturation that any RGB color
|
|
koethe@1199
|
246 |
in the unit cube can have after transformation into the respective color space,
|
|
koethe@1199
|
247 |
and saturation 0 corresponds to gray. Polar coordinates provide a more intuitive
|
|
koethe@1199
|
248 |
interface to color specification by users and make different color spaces somewhat
|
|
koethe@1199
|
249 |
comparable.
|
|
koethe@1199
|
250 |
*/
|
|
koethe@1697
|
251 |
//@{
|
|
koethe@1199
|
252 |
|
|
koethe@1199
|
253 |
|
|
koethe@1199
|
254 |
/** \brief Convert linear (raw) RGB into non-linear (gamma corrected) R'G'B'.
|
|
koethe@1199
|
255 |
|
|
koethe@1623
|
256 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
257 |
Namespace: vigra
|
|
koethe@1199
|
258 |
|
|
koethe@1199
|
259 |
The functor realizes the transformation
|
|
koethe@1199
|
260 |
|
|
koethe@1199
|
261 |
\f[
|
|
koethe@1199
|
262 |
R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad
|
|
koethe@1199
|
263 |
G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad
|
|
koethe@1199
|
264 |
B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45}
|
|
koethe@1199
|
265 |
\f]
|
|
koethe@1199
|
266 |
|
|
koethe@1199
|
267 |
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
|
|
koethe@1199
|
268 |
in the constructor. If both source and target colors components are stored
|
|
koethe@1199
|
269 |
as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
|
|
koethe@1199
|
270 |
|
|
koethe@1199
|
271 |
<b> Traits defined:</b>
|
|
koethe@1199
|
272 |
|
|
koethe@1623
|
273 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
274 |
*/
|
|
koethe@1199
|
275 |
template <class From, class To = From>
|
|
koethe@1199
|
276 |
class RGB2RGBPrimeFunctor
|
|
koethe@1199
|
277 |
{
|
|
koethe@1199
|
278 |
public:
|
|
koethe@1199
|
279 |
|
|
koethe@1199
|
280 |
/** the functor's argument type
|
|
koethe@1199
|
281 |
*/
|
|
koethe@1199
|
282 |
typedef TinyVector<From, 3> argument_type;
|
|
koethe@1199
|
283 |
|
|
koethe@1199
|
284 |
/** the functor's result type
|
|
koethe@1199
|
285 |
*/
|
|
ullrich@2455
|
286 |
typedef TinyVector<To, 3> result_type;
|
|
koethe@1199
|
287 |
|
|
koethe@1199
|
288 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
289 |
*/
|
|
ullrich@2455
|
290 |
typedef TinyVector<To, 3> value_type;
|
|
koethe@1199
|
291 |
|
|
koethe@1199
|
292 |
/** the result component's promote type
|
|
koethe@1199
|
293 |
*/
|
|
koethe@1199
|
294 |
typedef typename NumericTraits<To>::RealPromote component_type;
|
|
koethe@1199
|
295 |
|
|
koethe@1199
|
296 |
/** Default constructor.
|
|
koethe@1199
|
297 |
The maximum value for each RGB component defaults to 255
|
|
koethe@1199
|
298 |
*/
|
|
koethe@1199
|
299 |
RGB2RGBPrimeFunctor()
|
|
koethe@1199
|
300 |
: max_(255.0)
|
|
koethe@1199
|
301 |
{}
|
|
koethe@1199
|
302 |
|
|
koethe@1199
|
303 |
/** constructor
|
|
koethe@1199
|
304 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
305 |
*/
|
|
koethe@1199
|
306 |
RGB2RGBPrimeFunctor(component_type max)
|
|
koethe@1199
|
307 |
: max_(max)
|
|
koethe@1199
|
308 |
{}
|
|
koethe@1199
|
309 |
|
|
koethe@1199
|
310 |
/** apply the transformation
|
|
koethe@1199
|
311 |
*/
|
|
koethe@1199
|
312 |
template <class V>
|
|
koethe@1199
|
313 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
314 |
{
|
|
ullrich@2455
|
315 |
return TinyVector<To, 3>(
|
|
ullrich@2455
|
316 |
detail::gammaCorrection<To>(rgb[0], 0.45, max_),
|
|
ullrich@2455
|
317 |
detail::gammaCorrection<To>(rgb[1], 0.45, max_),
|
|
ullrich@2455
|
318 |
detail::gammaCorrection<To>(rgb[2], 0.45, max_));
|
|
koethe@1199
|
319 |
}
|
|
koethe@1199
|
320 |
|
|
koethe@1199
|
321 |
private:
|
|
koethe@1199
|
322 |
component_type max_;
|
|
koethe@1199
|
323 |
};
|
|
koethe@1199
|
324 |
|
|
koethe@1199
|
325 |
template <>
|
|
koethe@1199
|
326 |
class RGB2RGBPrimeFunctor<unsigned char, unsigned char>
|
|
koethe@1199
|
327 |
{
|
|
koethe@1199
|
328 |
unsigned char lut_[256];
|
|
koethe@1199
|
329 |
|
|
koethe@1199
|
330 |
public:
|
|
koethe@1199
|
331 |
|
|
ullrich@2537
|
332 |
typedef TinyVector<unsigned char, 3> argument_type;
|
|
ullrich@2537
|
333 |
|
|
ullrich@2537
|
334 |
typedef TinyVector<unsigned char, 3> result_type;
|
|
ullrich@2537
|
335 |
|
|
ullrich@2455
|
336 |
typedef TinyVector<unsigned char, 3> value_type;
|
|
koethe@1199
|
337 |
|
|
koethe@1199
|
338 |
RGB2RGBPrimeFunctor()
|
|
koethe@1199
|
339 |
{
|
|
koethe@1199
|
340 |
for(int i=0; i<256; ++i)
|
|
koethe@1199
|
341 |
{
|
|
ullrich@2455
|
342 |
lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, 255.0);
|
|
koethe@1199
|
343 |
}
|
|
koethe@1199
|
344 |
}
|
|
koethe@1199
|
345 |
|
|
koethe@1199
|
346 |
RGB2RGBPrimeFunctor(double max)
|
|
koethe@1199
|
347 |
{
|
|
koethe@1199
|
348 |
for(int i=0; i<256; ++i)
|
|
koethe@1199
|
349 |
{
|
|
ullrich@2455
|
350 |
lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, max);
|
|
koethe@1199
|
351 |
}
|
|
koethe@1199
|
352 |
}
|
|
koethe@1199
|
353 |
|
|
koethe@1199
|
354 |
template <class V>
|
|
ullrich@2455
|
355 |
TinyVector<unsigned char, 3> operator()(V const & rgb) const
|
|
koethe@1199
|
356 |
{
|
|
ullrich@2455
|
357 |
return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
|
|
koethe@1199
|
358 |
}
|
|
koethe@1199
|
359 |
};
|
|
koethe@1199
|
360 |
|
|
koethe@1199
|
361 |
template <class From, class To>
|
|
koethe@1199
|
362 |
class FunctorTraits<RGB2RGBPrimeFunctor<From, To> >
|
|
koethe@1199
|
363 |
: public FunctorTraitsBase<RGB2RGBPrimeFunctor<From, To> >
|
|
koethe@1199
|
364 |
{
|
|
koethe@1199
|
365 |
public:
|
|
koethe@1199
|
366 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
367 |
};
|
|
koethe@1199
|
368 |
|
|
koethe@1432
|
369 |
/** \brief Convert linear (raw) RGB into standardized sRGB.
|
|
koethe@1432
|
370 |
|
|
koethe@1623
|
371 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1432
|
372 |
Namespace: vigra
|
|
koethe@1432
|
373 |
|
|
koethe@1697
|
374 |
The sRGB color space is a slight improvement over the R'G'B' space. It is now a widely accepted
|
|
koethe@1433
|
375 |
international standard (IEC 61966-2.1) which is used by most consumer products
|
|
koethe@1432
|
376 |
(digital cameras, printers, and screens). The functor realizes the transformation
|
|
koethe@1432
|
377 |
|
|
koethe@1432
|
378 |
\f[
|
|
koethe@1620
|
379 |
C_{sRGB} = \left\{ \begin{array}{ll}
|
|
ullrich@1792
|
380 |
12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.0031308 \\
|
|
koethe@1619
|
381 |
C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.055\right) & \textrm{ otherwise}
|
|
koethe@1619
|
382 |
\end{array} \right.
|
|
koethe@1432
|
383 |
\f]
|
|
koethe@1432
|
384 |
|
|
koethe@1621
|
385 |
where C is any of the primaries R, G, and B. By default, \f$ C_{max} = 255 \f$ (this default can be
|
|
koethe@1621
|
386 |
overridden in the constructor). If both source and target color components are stored
|
|
koethe@1432
|
387 |
as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
|
|
koethe@1432
|
388 |
|
|
koethe@1432
|
389 |
<b> Traits defined:</b>
|
|
koethe@1432
|
390 |
|
|
koethe@1623
|
391 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1432
|
392 |
*/
|
|
koethe@1432
|
393 |
template <class From, class To = From>
|
|
koethe@1432
|
394 |
class RGB2sRGBFunctor
|
|
koethe@1432
|
395 |
{
|
|
koethe@1432
|
396 |
public:
|
|
koethe@1432
|
397 |
|
|
koethe@1432
|
398 |
/** the functor's argument type
|
|
koethe@1432
|
399 |
*/
|
|
koethe@1432
|
400 |
typedef TinyVector<From, 3> argument_type;
|
|
koethe@1432
|
401 |
|
|
koethe@1432
|
402 |
/** the functor's result type
|
|
koethe@1432
|
403 |
*/
|
|
ullrich@2455
|
404 |
typedef TinyVector<To, 3> result_type;
|
|
koethe@1432
|
405 |
|
|
koethe@1432
|
406 |
/** \deprecated use argument_type and result_type
|
|
koethe@1432
|
407 |
*/
|
|
ullrich@2455
|
408 |
typedef TinyVector<To, 3> value_type;
|
|
koethe@1432
|
409 |
|
|
koethe@1432
|
410 |
/** the result component's promote type
|
|
koethe@1432
|
411 |
*/
|
|
koethe@1432
|
412 |
typedef typename NumericTraits<To>::RealPromote component_type;
|
|
koethe@1432
|
413 |
|
|
koethe@1432
|
414 |
/** Default constructor.
|
|
koethe@1432
|
415 |
The maximum value for each RGB component defaults to 255
|
|
koethe@1432
|
416 |
*/
|
|
koethe@1432
|
417 |
RGB2sRGBFunctor()
|
|
koethe@1432
|
418 |
: max_(255.0)
|
|
koethe@1432
|
419 |
{}
|
|
koethe@1432
|
420 |
|
|
koethe@1432
|
421 |
/** constructor
|
|
koethe@1432
|
422 |
\arg max - the maximum value for each RGB component
|
|
koethe@1432
|
423 |
*/
|
|
koethe@1432
|
424 |
RGB2sRGBFunctor(component_type max)
|
|
koethe@1432
|
425 |
: max_(max)
|
|
koethe@1432
|
426 |
{}
|
|
koethe@1432
|
427 |
|
|
koethe@1432
|
428 |
/** apply the transformation
|
|
koethe@1432
|
429 |
*/
|
|
koethe@1432
|
430 |
template <class V>
|
|
koethe@1432
|
431 |
result_type operator()(V const & rgb) const
|
|
koethe@1432
|
432 |
{
|
|
ullrich@2455
|
433 |
return TinyVector<To, 3>(
|
|
ullrich@2455
|
434 |
detail::sRGBCorrection<To>(rgb[0], max_),
|
|
ullrich@2455
|
435 |
detail::sRGBCorrection<To>(rgb[1], max_),
|
|
ullrich@2455
|
436 |
detail::sRGBCorrection<To>(rgb[2], max_));
|
|
koethe@1432
|
437 |
}
|
|
koethe@1432
|
438 |
|
|
koethe@1432
|
439 |
private:
|
|
koethe@1432
|
440 |
component_type max_;
|
|
koethe@1432
|
441 |
};
|
|
koethe@1432
|
442 |
|
|
koethe@1432
|
443 |
template <>
|
|
koethe@1432
|
444 |
class RGB2sRGBFunctor<unsigned char, unsigned char>
|
|
koethe@1432
|
445 |
{
|
|
koethe@1432
|
446 |
unsigned char lut_[256];
|
|
koethe@1432
|
447 |
|
|
koethe@1432
|
448 |
public:
|
|
koethe@1432
|
449 |
|
|
ullrich@2537
|
450 |
typedef TinyVector<unsigned char, 3> argument_type;
|
|
ullrich@2537
|
451 |
|
|
ullrich@2537
|
452 |
typedef TinyVector<unsigned char, 3> result_type;
|
|
ullrich@2537
|
453 |
|
|
ullrich@2455
|
454 |
typedef TinyVector<unsigned char, 3> value_type;
|
|
koethe@1432
|
455 |
|
|
koethe@1432
|
456 |
RGB2sRGBFunctor()
|
|
koethe@1432
|
457 |
{
|
|
koethe@1432
|
458 |
for(int i=0; i<256; ++i)
|
|
koethe@1432
|
459 |
{
|
|
ullrich@2455
|
460 |
lut_[i] = detail::sRGBCorrection<unsigned char>(i, 255.0);
|
|
koethe@1432
|
461 |
}
|
|
koethe@1432
|
462 |
}
|
|
koethe@1432
|
463 |
|
|
koethe@1432
|
464 |
RGB2sRGBFunctor(double max)
|
|
koethe@1432
|
465 |
{
|
|
koethe@1432
|
466 |
for(int i=0; i<256; ++i)
|
|
koethe@1432
|
467 |
{
|
|
ullrich@2455
|
468 |
lut_[i] = detail::sRGBCorrection<unsigned char>(i, max);
|
|
koethe@1432
|
469 |
}
|
|
koethe@1432
|
470 |
}
|
|
koethe@1432
|
471 |
|
|
koethe@1432
|
472 |
template <class V>
|
|
ullrich@2455
|
473 |
TinyVector<unsigned char, 3> operator()(V const & rgb) const
|
|
koethe@1432
|
474 |
{
|
|
ullrich@2455
|
475 |
return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
|
|
koethe@1432
|
476 |
}
|
|
koethe@1432
|
477 |
};
|
|
koethe@1432
|
478 |
|
|
koethe@1432
|
479 |
template <class From, class To>
|
|
koethe@1432
|
480 |
class FunctorTraits<RGB2sRGBFunctor<From, To> >
|
|
koethe@1432
|
481 |
: public FunctorTraitsBase<RGB2sRGBFunctor<From, To> >
|
|
koethe@1432
|
482 |
{
|
|
koethe@1432
|
483 |
public:
|
|
koethe@1432
|
484 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1432
|
485 |
};
|
|
koethe@1432
|
486 |
|
|
koethe@1199
|
487 |
/** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw) RGB.
|
|
koethe@1199
|
488 |
|
|
koethe@1623
|
489 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
490 |
Namespace: vigra
|
|
koethe@1199
|
491 |
|
|
koethe@1199
|
492 |
The functor realizes the transformation
|
|
koethe@1199
|
493 |
|
|
koethe@1199
|
494 |
\f[
|
|
koethe@1199
|
495 |
R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad
|
|
koethe@1199
|
496 |
G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad
|
|
koethe@1199
|
497 |
B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45}
|
|
koethe@1199
|
498 |
\f]
|
|
koethe@1199
|
499 |
|
|
koethe@1199
|
500 |
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
|
|
koethe@1432
|
501 |
in the constructor. If both source and target color components are stored
|
|
koethe@1199
|
502 |
as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
|
|
koethe@1199
|
503 |
|
|
koethe@1199
|
504 |
<b> Traits defined:</b>
|
|
koethe@1199
|
505 |
|
|
koethe@1623
|
506 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
507 |
*/
|
|
koethe@1199
|
508 |
template <class From, class To = From>
|
|
koethe@1199
|
509 |
class RGBPrime2RGBFunctor
|
|
koethe@1199
|
510 |
{
|
|
koethe@1199
|
511 |
public:
|
|
koethe@1199
|
512 |
|
|
koethe@1199
|
513 |
/** the functor's argument type
|
|
koethe@1199
|
514 |
*/
|
|
koethe@1199
|
515 |
typedef TinyVector<From, 3> argument_type;
|
|
koethe@1199
|
516 |
|
|
koethe@1199
|
517 |
/** the functor's result type
|
|
koethe@1199
|
518 |
*/
|
|
ullrich@2455
|
519 |
typedef TinyVector<To, 3> result_type;
|
|
koethe@1199
|
520 |
|
|
koethe@1199
|
521 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
522 |
*/
|
|
ullrich@2455
|
523 |
typedef TinyVector<To, 3> value_type;
|
|
koethe@1199
|
524 |
|
|
koethe@1199
|
525 |
/** the result component's promote type
|
|
koethe@1199
|
526 |
*/
|
|
koethe@1199
|
527 |
typedef typename NumericTraits<To>::RealPromote component_type;
|
|
koethe@1199
|
528 |
|
|
koethe@1199
|
529 |
/** Default constructor.
|
|
koethe@1199
|
530 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
531 |
*/
|
|
koethe@1199
|
532 |
RGBPrime2RGBFunctor()
|
|
koethe@1199
|
533 |
: max_(255.0), gamma_(1.0/0.45)
|
|
koethe@1199
|
534 |
{}
|
|
koethe@1199
|
535 |
|
|
koethe@1199
|
536 |
/** constructor
|
|
koethe@1199
|
537 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
538 |
*/
|
|
koethe@1199
|
539 |
RGBPrime2RGBFunctor(component_type max)
|
|
koethe@1199
|
540 |
: max_(max), gamma_(1.0/0.45)
|
|
koethe@1199
|
541 |
{}
|
|
koethe@1199
|
542 |
|
|
koethe@1199
|
543 |
/** apply the transformation
|
|
koethe@1199
|
544 |
*/
|
|
koethe@1199
|
545 |
result_type operator()(argument_type const & rgb) const
|
|
koethe@1199
|
546 |
{
|
|
ullrich@2455
|
547 |
return TinyVector<To, 3>(
|
|
ullrich@2455
|
548 |
detail::gammaCorrection<To>(rgb[0], gamma_, max_),
|
|
ullrich@2455
|
549 |
detail::gammaCorrection<To>(rgb[1], gamma_, max_),
|
|
ullrich@2455
|
550 |
detail::gammaCorrection<To>(rgb[2], gamma_, max_));
|
|
koethe@1199
|
551 |
}
|
|
koethe@1199
|
552 |
|
|
koethe@1199
|
553 |
private:
|
|
koethe@1199
|
554 |
component_type max_;
|
|
koethe@1199
|
555 |
double gamma_;
|
|
koethe@1199
|
556 |
};
|
|
koethe@1199
|
557 |
|
|
koethe@1199
|
558 |
template <>
|
|
koethe@1199
|
559 |
class RGBPrime2RGBFunctor<unsigned char, unsigned char>
|
|
koethe@1199
|
560 |
{
|
|
koethe@1199
|
561 |
unsigned char lut_[256];
|
|
koethe@1199
|
562 |
|
|
koethe@1199
|
563 |
public:
|
|
koethe@1199
|
564 |
|
|
ullrich@2537
|
565 |
typedef TinyVector<unsigned char, 3> argument_type;
|
|
ullrich@2537
|
566 |
|
|
ullrich@2537
|
567 |
typedef TinyVector<unsigned char, 3> result_type;
|
|
ullrich@2537
|
568 |
|
|
ullrich@2455
|
569 |
typedef TinyVector<unsigned char, 3> value_type;
|
|
koethe@1199
|
570 |
|
|
koethe@1199
|
571 |
RGBPrime2RGBFunctor()
|
|
koethe@1199
|
572 |
{
|
|
koethe@1199
|
573 |
for(int i=0; i<256; ++i)
|
|
koethe@1199
|
574 |
{
|
|
ullrich@2455
|
575 |
lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, 255.0);
|
|
koethe@1199
|
576 |
}
|
|
koethe@1199
|
577 |
}
|
|
koethe@1199
|
578 |
|
|
koethe@1199
|
579 |
RGBPrime2RGBFunctor(double max)
|
|
koethe@1199
|
580 |
{
|
|
koethe@1199
|
581 |
for(int i=0; i<256; ++i)
|
|
koethe@1199
|
582 |
{
|
|
ullrich@2455
|
583 |
lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, max);
|
|
koethe@1199
|
584 |
}
|
|
koethe@1199
|
585 |
}
|
|
koethe@1199
|
586 |
|
|
koethe@1199
|
587 |
template <class V>
|
|
ullrich@2455
|
588 |
TinyVector<unsigned char, 3> operator()(V const & rgb) const
|
|
koethe@1199
|
589 |
{
|
|
ullrich@2455
|
590 |
return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
|
|
koethe@1199
|
591 |
}
|
|
koethe@1199
|
592 |
};
|
|
koethe@1199
|
593 |
|
|
koethe@1199
|
594 |
template <class From, class To>
|
|
koethe@1199
|
595 |
class FunctorTraits<RGBPrime2RGBFunctor<From, To> >
|
|
koethe@1199
|
596 |
: public FunctorTraitsBase<RGBPrime2RGBFunctor<From, To> >
|
|
koethe@1199
|
597 |
{
|
|
koethe@1199
|
598 |
public:
|
|
koethe@1199
|
599 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
600 |
};
|
|
koethe@1199
|
601 |
|
|
koethe@1432
|
602 |
/** \brief Convert standardized sRGB into non-linear (raw) RGB.
|
|
koethe@1432
|
603 |
|
|
koethe@1623
|
604 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1432
|
605 |
Namespace: vigra
|
|
koethe@1432
|
606 |
|
|
koethe@1433
|
607 |
The sRGB color space is a slight improvement over the R'G'B' space. Is is now a widely accepted
|
|
koethe@1433
|
608 |
international standard (IEC 61966-2.1) which is used by most consumer products
|
|
koethe@1433
|
609 |
(digital cameras, printers, and screens). The functor realizes the transformation
|
|
koethe@1432
|
610 |
|
|
koethe@1432
|
611 |
\f[
|
|
koethe@1623
|
612 |
C_{RGB} = \left\{\begin{array}{ll}
|
|
ullrich@1792
|
613 |
C_{sRGB} / 12.92 & \textrm{if }\frac{C_{sRGB}}{C_{max}} \le 0.04045 \\
|
|
koethe@1432
|
614 |
C_{max}\left( \frac{C_{sRGB}/C_{max}+0.055}{1.055}\right)^{2.4} & \textrm{otherwise}
|
|
koethe@1623
|
615 |
\end{array}\right.
|
|
koethe@1432
|
616 |
\f]
|
|
koethe@1432
|
617 |
|
|
koethe@1433
|
618 |
where C is one of the color channels R, G, or B, and \f$ C_{max}\f$ equals 255 by default (This default
|
|
koethe@1433
|
619 |
can be overridden in the constructor). If both source and target color components are stored
|
|
koethe@1432
|
620 |
as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
|
|
koethe@1432
|
621 |
|
|
koethe@1432
|
622 |
<b> Traits defined:</b>
|
|
koethe@1432
|
623 |
|
|
koethe@1623
|
624 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1432
|
625 |
*/
|
|
koethe@1432
|
626 |
template <class From, class To = From>
|
|
koethe@1432
|
627 |
class sRGB2RGBFunctor
|
|
koethe@1432
|
628 |
{
|
|
koethe@1432
|
629 |
public:
|
|
koethe@1432
|
630 |
|
|
koethe@1432
|
631 |
/** the functor's argument type
|
|
koethe@1432
|
632 |
*/
|
|
koethe@1432
|
633 |
typedef TinyVector<From, 3> argument_type;
|
|
koethe@1432
|
634 |
|
|
koethe@1432
|
635 |
/** the functor's result type
|
|
koethe@1432
|
636 |
*/
|
|
ullrich@2455
|
637 |
typedef TinyVector<To, 3> result_type;
|
|
koethe@1432
|
638 |
|
|
koethe@1432
|
639 |
/** \deprecated use argument_type and result_type
|
|
koethe@1432
|
640 |
*/
|
|
ullrich@2455
|
641 |
typedef TinyVector<To, 3> value_type;
|
|
koethe@1432
|
642 |
|
|
koethe@1432
|
643 |
/** the result component's promote type
|
|
koethe@1432
|
644 |
*/
|
|
koethe@1432
|
645 |
typedef typename NumericTraits<To>::RealPromote component_type;
|
|
koethe@1432
|
646 |
|
|
koethe@1432
|
647 |
/** Default constructor.
|
|
koethe@1432
|
648 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1432
|
649 |
*/
|
|
koethe@1432
|
650 |
sRGB2RGBFunctor()
|
|
koethe@1432
|
651 |
: max_(255.0)
|
|
koethe@1432
|
652 |
{}
|
|
koethe@1432
|
653 |
|
|
koethe@1432
|
654 |
/** constructor
|
|
koethe@1432
|
655 |
\arg max - the maximum value for each RGB component
|
|
koethe@1432
|
656 |
*/
|
|
koethe@1432
|
657 |
sRGB2RGBFunctor(component_type max)
|
|
koethe@1432
|
658 |
: max_(max)
|
|
koethe@1432
|
659 |
{}
|
|
koethe@1432
|
660 |
|
|
koethe@1432
|
661 |
/** apply the transformation
|
|
koethe@1432
|
662 |
*/
|
|
koethe@1432
|
663 |
result_type operator()(argument_type const & rgb) const
|
|
koethe@1432
|
664 |
{
|
|
ullrich@2455
|
665 |
return TinyVector<To, 3>(
|
|
ullrich@2455
|
666 |
detail::inverse_sRGBCorrection<To>(rgb[0], max_),
|
|
ullrich@2455
|
667 |
detail::inverse_sRGBCorrection<To>(rgb[1], max_),
|
|
ullrich@2455
|
668 |
detail::inverse_sRGBCorrection<To>(rgb[2], max_));
|
|
koethe@1432
|
669 |
}
|
|
koethe@1432
|
670 |
|
|
koethe@1432
|
671 |
private:
|
|
koethe@1432
|
672 |
component_type max_;
|
|
koethe@1432
|
673 |
};
|
|
koethe@1432
|
674 |
|
|
koethe@1432
|
675 |
template <>
|
|
koethe@1432
|
676 |
class sRGB2RGBFunctor<unsigned char, unsigned char>
|
|
koethe@1432
|
677 |
{
|
|
koethe@1432
|
678 |
unsigned char lut_[256];
|
|
koethe@1432
|
679 |
|
|
koethe@1432
|
680 |
public:
|
|
koethe@1432
|
681 |
|
|
ullrich@2537
|
682 |
typedef TinyVector<unsigned char, 3> argument_type;
|
|
ullrich@2537
|
683 |
|
|
ullrich@2537
|
684 |
typedef TinyVector<unsigned char, 3> result_type;
|
|
ullrich@2537
|
685 |
|
|
ullrich@2455
|
686 |
typedef TinyVector<unsigned char, 3> value_type;
|
|
koethe@1432
|
687 |
|
|
koethe@1432
|
688 |
sRGB2RGBFunctor()
|
|
koethe@1432
|
689 |
{
|
|
koethe@1432
|
690 |
for(int i=0; i<256; ++i)
|
|
koethe@1432
|
691 |
{
|
|
ullrich@2455
|
692 |
lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, 255.0);
|
|
koethe@1432
|
693 |
}
|
|
koethe@1432
|
694 |
}
|
|
koethe@1432
|
695 |
|
|
koethe@1432
|
696 |
sRGB2RGBFunctor(double max)
|
|
koethe@1432
|
697 |
{
|
|
koethe@1432
|
698 |
for(int i=0; i<256; ++i)
|
|
koethe@1432
|
699 |
{
|
|
ullrich@2455
|
700 |
lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, max);
|
|
koethe@1432
|
701 |
}
|
|
koethe@1432
|
702 |
}
|
|
koethe@1432
|
703 |
|
|
koethe@1432
|
704 |
template <class V>
|
|
ullrich@2455
|
705 |
TinyVector<unsigned char, 3> operator()(V const & rgb) const
|
|
koethe@1432
|
706 |
{
|
|
ullrich@2455
|
707 |
return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
|
|
koethe@1432
|
708 |
}
|
|
koethe@1432
|
709 |
};
|
|
koethe@1432
|
710 |
|
|
koethe@1432
|
711 |
template <class From, class To>
|
|
koethe@1432
|
712 |
class FunctorTraits<sRGB2RGBFunctor<From, To> >
|
|
koethe@1432
|
713 |
: public FunctorTraitsBase<sRGB2RGBFunctor<From, To> >
|
|
koethe@1432
|
714 |
{
|
|
koethe@1432
|
715 |
public:
|
|
koethe@1432
|
716 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1432
|
717 |
};
|
|
koethe@1432
|
718 |
|
|
koethe@1199
|
719 |
/** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ.
|
|
koethe@1199
|
720 |
|
|
koethe@1623
|
721 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
722 |
Namespace: vigra
|
|
koethe@1199
|
723 |
|
|
koethe@1199
|
724 |
According to ITU-R Recommendation BT.709, the functor realizes the transformation
|
|
koethe@1199
|
725 |
|
|
koethe@1199
|
726 |
\f[
|
|
koethe@1199
|
727 |
\begin{array}{rcl}
|
|
koethe@1199
|
728 |
X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max} + 0.180423\enspace B / B_{max}\\
|
|
koethe@1199
|
729 |
Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max} + 0.072169\enspace B / B_{max} \\
|
|
koethe@1199
|
730 |
Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max} + 0.950227\enspace B / B_{max}
|
|
koethe@1199
|
731 |
\end{array}
|
|
koethe@1199
|
732 |
\f]
|
|
koethe@1199
|
733 |
|
|
koethe@1199
|
734 |
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
|
|
koethe@1199
|
735 |
in the constructor. X, Y, and Z are always positive and reach their maximum for white.
|
|
koethe@1199
|
736 |
The white point is obtained by transforming RGB(255, 255, 255). It corresponds to the
|
|
ullrich@1792
|
737 |
D65 illuminant. Y represents the <em>luminance</em> ("brightness") of the color. The above
|
|
ullrich@1792
|
738 |
transformation is officially defined in connection with the sRGB color space (i.e. when the RGB values
|
|
ullrich@1792
|
739 |
are obtained by inverse gamma correction of sRGB), other color spaces use slightly different numbers
|
|
ullrich@1792
|
740 |
or another standard illuminant (which gives raise to significantly different numbers).
|
|
koethe@1199
|
741 |
|
|
koethe@1199
|
742 |
<b> Traits defined:</b>
|
|
koethe@1199
|
743 |
|
|
koethe@1623
|
744 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
745 |
*/
|
|
koethe@1199
|
746 |
template <class T>
|
|
koethe@1199
|
747 |
class RGB2XYZFunctor
|
|
koethe@1199
|
748 |
{
|
|
koethe@1199
|
749 |
public:
|
|
koethe@1199
|
750 |
|
|
koethe@1199
|
751 |
/** the result's component type
|
|
koethe@1199
|
752 |
*/
|
|
koethe@1199
|
753 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
754 |
|
|
koethe@1199
|
755 |
/** the functor's argument type
|
|
koethe@1199
|
756 |
*/
|
|
koethe@1199
|
757 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
758 |
|
|
koethe@1199
|
759 |
/** the functor's result type
|
|
koethe@1199
|
760 |
*/
|
|
koethe@1199
|
761 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
762 |
|
|
koethe@1199
|
763 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
764 |
*/
|
|
koethe@1199
|
765 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
766 |
|
|
koethe@1199
|
767 |
/** default constructor.
|
|
koethe@1199
|
768 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
769 |
*/
|
|
koethe@1199
|
770 |
RGB2XYZFunctor()
|
|
koethe@1199
|
771 |
: max_(255.0)
|
|
koethe@1199
|
772 |
{}
|
|
koethe@1199
|
773 |
|
|
koethe@1199
|
774 |
/** constructor
|
|
koethe@1199
|
775 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
776 |
*/
|
|
koethe@1199
|
777 |
RGB2XYZFunctor(component_type max)
|
|
koethe@1199
|
778 |
: max_(max)
|
|
koethe@1199
|
779 |
{}
|
|
koethe@1199
|
780 |
|
|
koethe@1199
|
781 |
/** apply the transformation
|
|
koethe@1199
|
782 |
*/
|
|
koethe@1199
|
783 |
result_type operator()(argument_type const & rgb) const
|
|
koethe@1199
|
784 |
{
|
|
ullrich@2455
|
785 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
koethe@1199
|
786 |
component_type red = rgb[0] / max_;
|
|
koethe@1199
|
787 |
component_type green = rgb[1] / max_;
|
|
koethe@1199
|
788 |
component_type blue = rgb[2] / max_;
|
|
koethe@1199
|
789 |
result_type result;
|
|
ullrich@2455
|
790 |
result[0] = Convert::cast(0.412453*red + 0.357580*green + 0.180423*blue);
|
|
ullrich@2455
|
791 |
result[1] = Convert::cast(0.212671*red + 0.715160*green + 0.072169*blue);
|
|
ullrich@2455
|
792 |
result[2] = Convert::cast(0.019334*red + 0.119193*green + 0.950227*blue);
|
|
koethe@1199
|
793 |
return result;
|
|
koethe@1199
|
794 |
}
|
|
koethe@1199
|
795 |
|
|
koethe@1199
|
796 |
private:
|
|
koethe@1199
|
797 |
component_type max_;
|
|
koethe@1199
|
798 |
};
|
|
koethe@1199
|
799 |
|
|
koethe@1199
|
800 |
template <class T>
|
|
koethe@1199
|
801 |
class FunctorTraits<RGB2XYZFunctor<T> >
|
|
koethe@1199
|
802 |
: public FunctorTraitsBase<RGB2XYZFunctor<T> >
|
|
koethe@1199
|
803 |
{
|
|
koethe@1199
|
804 |
public:
|
|
koethe@1199
|
805 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
806 |
};
|
|
koethe@1199
|
807 |
|
|
koethe@1199
|
808 |
/** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tri-stimulus XYZ.
|
|
koethe@1199
|
809 |
|
|
koethe@1623
|
810 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
811 |
Namespace: vigra
|
|
koethe@1199
|
812 |
|
|
koethe@1199
|
813 |
The functor realizes the transformation
|
|
koethe@1199
|
814 |
|
|
koethe@1199
|
815 |
\f[
|
|
koethe@1199
|
816 |
R'G'B' \Rightarrow RGB \Rightarrow XYZ
|
|
koethe@1199
|
817 |
\f]
|
|
koethe@1199
|
818 |
|
|
koethe@1199
|
819 |
See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a description of the two
|
|
koethe@1199
|
820 |
steps.
|
|
koethe@1199
|
821 |
|
|
koethe@1199
|
822 |
<b> Traits defined:</b>
|
|
koethe@1199
|
823 |
|
|
koethe@1623
|
824 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
825 |
*/
|
|
koethe@1199
|
826 |
template <class T>
|
|
koethe@1199
|
827 |
class RGBPrime2XYZFunctor
|
|
koethe@1199
|
828 |
{
|
|
koethe@1199
|
829 |
public:
|
|
koethe@1199
|
830 |
|
|
koethe@1199
|
831 |
/** the result's component type
|
|
koethe@1199
|
832 |
*/
|
|
koethe@1199
|
833 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
834 |
|
|
koethe@1199
|
835 |
/** the functor's argument type
|
|
koethe@1199
|
836 |
*/
|
|
koethe@1199
|
837 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
838 |
|
|
koethe@1199
|
839 |
/** the functor's result type
|
|
koethe@1199
|
840 |
*/
|
|
koethe@1199
|
841 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
842 |
|
|
koethe@1199
|
843 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
844 |
*/
|
|
koethe@1199
|
845 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
846 |
|
|
koethe@1199
|
847 |
/** default constructor
|
|
koethe@1199
|
848 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
849 |
*/
|
|
koethe@1199
|
850 |
RGBPrime2XYZFunctor()
|
|
ullrich@2512
|
851 |
: gamma_(1.0/ 0.45), max_(component_type(255.0))
|
|
koethe@1199
|
852 |
{}
|
|
koethe@1199
|
853 |
|
|
koethe@1199
|
854 |
/** constructor
|
|
koethe@1199
|
855 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
856 |
*/
|
|
koethe@1199
|
857 |
RGBPrime2XYZFunctor(component_type max)
|
|
ullrich@2512
|
858 |
: gamma_(1.0/ 0.45), max_(max)
|
|
koethe@1199
|
859 |
{}
|
|
koethe@1199
|
860 |
|
|
koethe@1199
|
861 |
/** apply the transformation
|
|
koethe@1199
|
862 |
*/
|
|
koethe@1199
|
863 |
result_type operator()(argument_type const & rgb) const
|
|
koethe@1199
|
864 |
{
|
|
ullrich@2455
|
865 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
866 |
component_type red = detail::gammaCorrection<component_type>(rgb[0]/max_, gamma_);
|
|
ullrich@2455
|
867 |
component_type green = detail::gammaCorrection<component_type>(rgb[1]/max_, gamma_);
|
|
ullrich@2455
|
868 |
component_type blue = detail::gammaCorrection<component_type>(rgb[2]/max_, gamma_);
|
|
koethe@1199
|
869 |
result_type result;
|
|
ullrich@2455
|
870 |
result[0] = Convert::cast(0.412453*red + 0.357580*green + 0.180423*blue);
|
|
ullrich@2455
|
871 |
result[1] = Convert::cast(0.212671*red + 0.715160*green + 0.072169*blue);
|
|
ullrich@2455
|
872 |
result[2] = Convert::cast(0.019334*red + 0.119193*green + 0.950227*blue);
|
|
koethe@1199
|
873 |
return result;
|
|
koethe@1199
|
874 |
}
|
|
koethe@1199
|
875 |
|
|
koethe@1199
|
876 |
private:
|
|
ullrich@2455
|
877 |
double gamma_;
|
|
ullrich@2455
|
878 |
component_type max_;
|
|
koethe@1199
|
879 |
};
|
|
koethe@1199
|
880 |
|
|
koethe@1199
|
881 |
template <class T>
|
|
koethe@1199
|
882 |
class FunctorTraits<RGBPrime2XYZFunctor<T> >
|
|
koethe@1199
|
883 |
: public FunctorTraitsBase<RGBPrime2XYZFunctor<T> >
|
|
koethe@1199
|
884 |
{
|
|
koethe@1199
|
885 |
public:
|
|
koethe@1199
|
886 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
887 |
};
|
|
koethe@1199
|
888 |
|
|
koethe@1199
|
889 |
/** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB.
|
|
koethe@1199
|
890 |
|
|
koethe@1623
|
891 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
892 |
Namespace: vigra
|
|
koethe@1199
|
893 |
|
|
koethe@1199
|
894 |
According to ITU-R Recommendation BT.709, the functor realizes the transformation
|
|
koethe@1199
|
895 |
|
|
koethe@1199
|
896 |
\f[
|
|
koethe@1199
|
897 |
\begin{array}{rcl}
|
|
koethe@1199
|
898 |
R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y - 0.4985363262\enspace Z) \\
|
|
koethe@1199
|
899 |
G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y + 0.0415559266\enspace Z) \\
|
|
koethe@1199
|
900 |
B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y + 1.0573110696\enspace Z)
|
|
koethe@1199
|
901 |
\end{array}
|
|
koethe@1199
|
902 |
\f]
|
|
koethe@1199
|
903 |
|
|
koethe@1199
|
904 |
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
|
|
koethe@1199
|
905 |
in the constructor. This is the inverse transform of vigra::RGB2XYZFunctor.
|
|
koethe@1199
|
906 |
|
|
koethe@1199
|
907 |
<b> Traits defined:</b>
|
|
koethe@1199
|
908 |
|
|
koethe@1623
|
909 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
910 |
*/
|
|
koethe@1199
|
911 |
template <class T>
|
|
koethe@1199
|
912 |
class XYZ2RGBFunctor
|
|
koethe@1199
|
913 |
{
|
|
koethe@1199
|
914 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
915 |
|
|
koethe@1199
|
916 |
component_type max_;
|
|
koethe@1199
|
917 |
|
|
koethe@1199
|
918 |
public:
|
|
koethe@1199
|
919 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
920 |
is more general: <TT>V</TT> with arbitrary
|
|
koethe@1199
|
921 |
<TT>V</TT>. But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
922 |
*/
|
|
koethe@1199
|
923 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
924 |
|
|
koethe@1199
|
925 |
/** the functor's result type
|
|
koethe@1199
|
926 |
*/
|
|
ullrich@2455
|
927 |
typedef TinyVector<T, 3> result_type;
|
|
koethe@1199
|
928 |
|
|
koethe@1199
|
929 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
930 |
*/
|
|
ullrich@2455
|
931 |
typedef TinyVector<T, 3> value_type;
|
|
koethe@1199
|
932 |
|
|
koethe@1199
|
933 |
/** default constructor.
|
|
koethe@1199
|
934 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
935 |
*/
|
|
koethe@1199
|
936 |
XYZ2RGBFunctor()
|
|
koethe@1199
|
937 |
: max_(255.0)
|
|
koethe@1199
|
938 |
{}
|
|
koethe@1199
|
939 |
|
|
koethe@1199
|
940 |
/** constructor
|
|
koethe@1199
|
941 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
942 |
*/
|
|
koethe@1199
|
943 |
XYZ2RGBFunctor(component_type max)
|
|
koethe@1199
|
944 |
: max_(max)
|
|
koethe@1199
|
945 |
{}
|
|
koethe@1199
|
946 |
|
|
koethe@1199
|
947 |
/** apply the transformation
|
|
koethe@1199
|
948 |
*/
|
|
koethe@1199
|
949 |
template <class V>
|
|
koethe@1199
|
950 |
result_type operator()(V const & xyz) const
|
|
koethe@1199
|
951 |
{
|
|
ullrich@2455
|
952 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
953 |
component_type red = Convert::cast( 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]);
|
|
ullrich@2455
|
954 |
component_type green = Convert::cast(-0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]);
|
|
ullrich@2455
|
955 |
component_type blue = Convert::cast( 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]);
|
|
koethe@1199
|
956 |
return value_type(NumericTraits<T>::fromRealPromote(red * max_),
|
|
koethe@1199
|
957 |
NumericTraits<T>::fromRealPromote(green * max_),
|
|
koethe@1199
|
958 |
NumericTraits<T>::fromRealPromote(blue * max_));
|
|
koethe@1199
|
959 |
}
|
|
koethe@1199
|
960 |
};
|
|
koethe@1199
|
961 |
|
|
koethe@1199
|
962 |
template <class T>
|
|
koethe@1199
|
963 |
class FunctorTraits<XYZ2RGBFunctor<T> >
|
|
koethe@1199
|
964 |
: public FunctorTraitsBase<XYZ2RGBFunctor<T> >
|
|
koethe@1199
|
965 |
{
|
|
koethe@1199
|
966 |
public:
|
|
koethe@1199
|
967 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
968 |
};
|
|
koethe@1199
|
969 |
|
|
koethe@1199
|
970 |
/** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma corrected) R'G'B'.
|
|
koethe@1199
|
971 |
|
|
koethe@1623
|
972 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
973 |
Namespace: vigra
|
|
koethe@1199
|
974 |
|
|
koethe@1199
|
975 |
The functor realizes the transformation
|
|
koethe@1199
|
976 |
|
|
koethe@1199
|
977 |
\f[
|
|
koethe@1199
|
978 |
XYZ \Rightarrow RGB \Rightarrow R'G'B'
|
|
koethe@1199
|
979 |
\f]
|
|
koethe@1199
|
980 |
|
|
koethe@1199
|
981 |
See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a description of the two
|
|
koethe@1199
|
982 |
steps.
|
|
koethe@1199
|
983 |
|
|
koethe@1199
|
984 |
<b> Traits defined:</b>
|
|
koethe@1199
|
985 |
|
|
koethe@1623
|
986 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
987 |
*/
|
|
koethe@1199
|
988 |
template <class T>
|
|
koethe@1199
|
989 |
class XYZ2RGBPrimeFunctor
|
|
koethe@1199
|
990 |
{
|
|
koethe@1199
|
991 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
992 |
|
|
ullrich@2455
|
993 |
double gamma_;
|
|
ullrich@2455
|
994 |
component_type max_;
|
|
koethe@1199
|
995 |
|
|
koethe@1199
|
996 |
public:
|
|
koethe@1199
|
997 |
|
|
koethe@1199
|
998 |
public:
|
|
koethe@1199
|
999 |
/** the functor's argument type. (actually, the argument type
|
|
koethe@1199
|
1000 |
can be any vector type with the same interface.
|
|
koethe@1199
|
1001 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
1002 |
*/
|
|
koethe@1199
|
1003 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1004 |
|
|
koethe@1199
|
1005 |
/** the functor's result type
|
|
koethe@1199
|
1006 |
*/
|
|
ullrich@2455
|
1007 |
typedef TinyVector<T, 3> result_type;
|
|
koethe@1199
|
1008 |
|
|
koethe@1199
|
1009 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1010 |
*/
|
|
ullrich@2455
|
1011 |
typedef TinyVector<T, 3> value_type;
|
|
koethe@1199
|
1012 |
|
|
koethe@1199
|
1013 |
/** default constructor.
|
|
koethe@1199
|
1014 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
1015 |
*/
|
|
koethe@1199
|
1016 |
XYZ2RGBPrimeFunctor()
|
|
ullrich@2512
|
1017 |
: gamma_(0.45), max_(component_type(255.0))
|
|
koethe@1199
|
1018 |
{}
|
|
koethe@1199
|
1019 |
|
|
koethe@1199
|
1020 |
/** constructor
|
|
koethe@1199
|
1021 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
1022 |
*/
|
|
koethe@1199
|
1023 |
XYZ2RGBPrimeFunctor(component_type max)
|
|
ullrich@2512
|
1024 |
: gamma_(0.45), max_(max)
|
|
koethe@1199
|
1025 |
{}
|
|
koethe@1199
|
1026 |
|
|
koethe@1199
|
1027 |
/** apply the transformation
|
|
koethe@1199
|
1028 |
*/
|
|
koethe@1199
|
1029 |
template <class V>
|
|
koethe@1199
|
1030 |
result_type operator()(V const & xyz) const
|
|
koethe@1199
|
1031 |
{
|
|
ullrich@2455
|
1032 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
1033 |
component_type red = Convert::cast( 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]);
|
|
ullrich@2455
|
1034 |
component_type green = Convert::cast(-0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]);
|
|
ullrich@2455
|
1035 |
component_type blue = Convert::cast( 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]);
|
|
ullrich@2455
|
1036 |
return value_type(NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(red, gamma_) * max_),
|
|
ullrich@2455
|
1037 |
NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(green, gamma_) * max_),
|
|
ullrich@2455
|
1038 |
NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(blue, gamma_) * max_));
|
|
koethe@1199
|
1039 |
}
|
|
koethe@1199
|
1040 |
};
|
|
koethe@1199
|
1041 |
|
|
koethe@1199
|
1042 |
template <class T>
|
|
koethe@1199
|
1043 |
class FunctorTraits<XYZ2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
1044 |
: public FunctorTraitsBase<XYZ2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
1045 |
{
|
|
koethe@1199
|
1046 |
public:
|
|
koethe@1199
|
1047 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1048 |
};
|
|
koethe@1199
|
1049 |
|
|
koethe@1199
|
1050 |
/** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*u*v*.
|
|
koethe@1199
|
1051 |
|
|
koethe@1623
|
1052 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1053 |
Namespace: vigra
|
|
koethe@1199
|
1054 |
|
|
koethe@1199
|
1055 |
The functor realizes the transformation
|
|
koethe@1199
|
1056 |
|
|
koethe@1199
|
1057 |
\f[
|
|
koethe@1199
|
1058 |
\begin{array}{rcl}
|
|
koethe@1199
|
1059 |
L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\
|
|
koethe@1199
|
1060 |
& & \\
|
|
koethe@1199
|
1061 |
L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
|
|
koethe@1199
|
1062 |
& & \\
|
|
koethe@1199
|
1063 |
|
|
koethe@1199
|
1064 |
u' & = & \frac{4 X}{X+15 Y + 3 Z}, \quad
|
|
koethe@1199
|
1065 |
v' = \frac{9 Y}{X+15 Y + 3 Z}\\
|
|
koethe@1199
|
1066 |
& & \\
|
|
koethe@1199
|
1067 |
u^{*} & = & 13 L^{*} (u' - u_n'), \quad v^{*} = 13 L^{*} (v' - v_n')
|
|
koethe@1199
|
1068 |
\end{array}
|
|
koethe@1199
|
1069 |
\f]
|
|
koethe@1199
|
1070 |
|
|
ullrich@1792
|
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,
|
|
ullrich@1792
|
1072 |
and \f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ calculated for this point.
|
|
ullrich@1793
|
1073 |
\f$L^{*}\f$ represents the <em>lightness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ code the
|
|
ullrich@1792
|
1074 |
chromaticity. (Instead of the rationals \f$\frac{216}{24389}\f$ and \f$\frac{24389}{27}\f$, the original standard gives the
|
|
ullrich@1792
|
1075 |
rounded values 0.008856 and 903.3. As <a href="http://www.brucelindbloom.com/index.html?LContinuity.html">Bruce Lindbloom</a>
|
|
ullrich@1792
|
1076 |
points out, the rounded values give raise to a discontinuity which is removed by the accurate rationals. This bug will be fixed
|
|
ullrich@1792
|
1077 |
in future versions of the CIE Luv standard.)
|
|
koethe@1199
|
1078 |
|
|
koethe@1199
|
1079 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1080 |
|
|
koethe@1623
|
1081 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1082 |
*/
|
|
koethe@1199
|
1083 |
template <class T>
|
|
koethe@1199
|
1084 |
class XYZ2LuvFunctor
|
|
koethe@1199
|
1085 |
{
|
|
koethe@1199
|
1086 |
public:
|
|
koethe@1199
|
1087 |
|
|
koethe@1199
|
1088 |
/** the result's component type
|
|
koethe@1199
|
1089 |
*/
|
|
koethe@1199
|
1090 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1091 |
|
|
koethe@1199
|
1092 |
/** the functor's argument type
|
|
koethe@1199
|
1093 |
*/
|
|
koethe@1199
|
1094 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1095 |
|
|
koethe@1199
|
1096 |
/** the functor's result type
|
|
koethe@1199
|
1097 |
*/
|
|
koethe@1199
|
1098 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
1099 |
|
|
koethe@1199
|
1100 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1101 |
*/
|
|
koethe@1199
|
1102 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
1103 |
|
|
koethe@1199
|
1104 |
XYZ2LuvFunctor()
|
|
ullrich@1792
|
1105 |
: gamma_(1.0/3.0),
|
|
ullrich@1792
|
1106 |
kappa_(24389.0/27.0),
|
|
ullrich@1792
|
1107 |
epsilon_(216.0/24389.0)
|
|
koethe@1199
|
1108 |
{}
|
|
koethe@1199
|
1109 |
|
|
koethe@1199
|
1110 |
template <class V>
|
|
koethe@1199
|
1111 |
result_type operator()(V const & xyz) const
|
|
koethe@1199
|
1112 |
{
|
|
koethe@1199
|
1113 |
result_type result;
|
|
koethe@1199
|
1114 |
if(xyz[1] == NumericTraits<T>::zero())
|
|
koethe@1199
|
1115 |
{
|
|
koethe@1199
|
1116 |
result[0] = NumericTraits<component_type>::zero();
|
|
koethe@1199
|
1117 |
result[1] = NumericTraits<component_type>::zero();
|
|
koethe@1199
|
1118 |
result[2] = NumericTraits<component_type>::zero();
|
|
koethe@1199
|
1119 |
}
|
|
koethe@1199
|
1120 |
else
|
|
koethe@1199
|
1121 |
{
|
|
ullrich@2455
|
1122 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
1123 |
component_type L = Convert::cast(
|
|
ullrich@2455
|
1124 |
xyz[1] < epsilon_
|
|
ullrich@2455
|
1125 |
? kappa_ * xyz[1]
|
|
ullrich@2455
|
1126 |
: 116.0 * VIGRA_CSTD::pow((double)xyz[1], gamma_) - 16.0);
|
|
ullrich@2455
|
1127 |
component_type denom = Convert::cast(xyz[0] + 15.0*xyz[1] + 3.0*xyz[2]);
|
|
ullrich@2455
|
1128 |
component_type uprime = Convert::cast(4.0 * xyz[0] / denom);
|
|
ullrich@2455
|
1129 |
component_type vprime = Convert::cast(9.0 * xyz[1] / denom);
|
|
koethe@1199
|
1130 |
result[0] = L;
|
|
ullrich@2455
|
1131 |
result[1] = Convert::cast(13.0*L*(uprime - 0.197839));
|
|
ullrich@2455
|
1132 |
result[2] = Convert::cast(13.0*L*(vprime - 0.468342));
|
|
koethe@1199
|
1133 |
}
|
|
koethe@1199
|
1134 |
return result;
|
|
koethe@1199
|
1135 |
}
|
|
koethe@1199
|
1136 |
|
|
koethe@1199
|
1137 |
private:
|
|
ullrich@1792
|
1138 |
double gamma_, kappa_, epsilon_;
|
|
koethe@1199
|
1139 |
};
|
|
koethe@1199
|
1140 |
|
|
koethe@1199
|
1141 |
template <class T>
|
|
koethe@1199
|
1142 |
class FunctorTraits<XYZ2LuvFunctor<T> >
|
|
koethe@1199
|
1143 |
: public FunctorTraitsBase<XYZ2LuvFunctor<T> >
|
|
koethe@1199
|
1144 |
{
|
|
koethe@1199
|
1145 |
public:
|
|
koethe@1199
|
1146 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1147 |
};
|
|
koethe@1199
|
1148 |
|
|
koethe@1199
|
1149 |
/** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stimulus XYZ.
|
|
koethe@1199
|
1150 |
|
|
koethe@1623
|
1151 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1152 |
Namespace: vigra
|
|
koethe@1199
|
1153 |
|
|
koethe@1199
|
1154 |
The functor realizes the inverse of the transformation described in vigra::XYZ2LuvFunctor
|
|
koethe@1199
|
1155 |
|
|
koethe@1199
|
1156 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1157 |
|
|
koethe@1623
|
1158 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1159 |
*/
|
|
koethe@1199
|
1160 |
template <class T>
|
|
koethe@1199
|
1161 |
class Luv2XYZFunctor
|
|
koethe@1199
|
1162 |
{
|
|
koethe@1199
|
1163 |
public:
|
|
koethe@1199
|
1164 |
|
|
koethe@1199
|
1165 |
/** the result's component type
|
|
koethe@1199
|
1166 |
*/
|
|
koethe@1199
|
1167 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1168 |
|
|
koethe@1199
|
1169 |
/** the functor's argument type
|
|
koethe@1199
|
1170 |
*/
|
|
koethe@1199
|
1171 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1172 |
|
|
koethe@1199
|
1173 |
/** the functor's result type
|
|
koethe@1199
|
1174 |
*/
|
|
koethe@1199
|
1175 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
1176 |
|
|
koethe@1199
|
1177 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1178 |
*/
|
|
koethe@1199
|
1179 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
1180 |
|
|
koethe@1199
|
1181 |
Luv2XYZFunctor()
|
|
ullrich@1792
|
1182 |
: gamma_(3.0),
|
|
ullrich@1792
|
1183 |
ikappa_(27.0/24389.0)
|
|
koethe@1199
|
1184 |
{}
|
|
koethe@1199
|
1185 |
|
|
koethe@1199
|
1186 |
/** apply the transformation
|
|
koethe@1199
|
1187 |
*/
|
|
koethe@1199
|
1188 |
template <class V>
|
|
koethe@1199
|
1189 |
result_type operator()(V const & luv) const
|
|
koethe@1199
|
1190 |
{
|
|
koethe@1199
|
1191 |
result_type result;
|
|
koethe@1199
|
1192 |
if(luv[0] == NumericTraits<T>::zero())
|
|
koethe@1199
|
1193 |
{
|
|
koethe@1199
|
1194 |
result[0] = NumericTraits<component_type>::zero();
|
|
koethe@1199
|
1195 |
result[1] = NumericTraits<component_type>::zero();
|
|
koethe@1199
|
1196 |
result[2] = NumericTraits<component_type>::zero();
|
|
koethe@1199
|
1197 |
}
|
|
koethe@1199
|
1198 |
else
|
|
koethe@1199
|
1199 |
{
|
|
ullrich@2455
|
1200 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
1201 |
component_type uprime = Convert::cast(luv[1] / 13.0 / luv[0] + 0.197839);
|
|
ullrich@2455
|
1202 |
component_type vprime = Convert::cast(luv[2] / 13.0 / luv[0] + 0.468342);
|
|
koethe@1199
|
1203 |
|
|
ullrich@2455
|
1204 |
result[1] = Convert::cast(
|
|
ullrich@2455
|
1205 |
luv[0] < 8.0
|
|
ullrich@2455
|
1206 |
? luv[0] * ikappa_
|
|
ullrich@2455
|
1207 |
: VIGRA_CSTD::pow((luv[0] + 16.0) / 116.0, gamma_));
|
|
ullrich@2455
|
1208 |
result[0] = Convert::cast(9.0*uprime*result[1] / 4.0 / vprime);
|
|
ullrich@2455
|
1209 |
result[2] = Convert::cast(((9.0 / vprime - 15.0)*result[1] - result[0])/ 3.0);
|
|
koethe@1199
|
1210 |
}
|
|
koethe@1199
|
1211 |
return result;
|
|
koethe@1199
|
1212 |
}
|
|
koethe@1199
|
1213 |
|
|
koethe@1199
|
1214 |
private:
|
|
ullrich@1792
|
1215 |
double gamma_, ikappa_;
|
|
koethe@1199
|
1216 |
};
|
|
koethe@1199
|
1217 |
|
|
koethe@1199
|
1218 |
template <class T>
|
|
koethe@1199
|
1219 |
class FunctorTraits<Luv2XYZFunctor<T> >
|
|
koethe@1199
|
1220 |
: public FunctorTraitsBase<Luv2XYZFunctor<T> >
|
|
koethe@1199
|
1221 |
{
|
|
koethe@1199
|
1222 |
public:
|
|
koethe@1199
|
1223 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1224 |
};
|
|
koethe@1199
|
1225 |
|
|
koethe@1199
|
1226 |
/** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*a*b*.
|
|
koethe@1199
|
1227 |
|
|
koethe@1623
|
1228 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1229 |
Namespace: vigra
|
|
koethe@1199
|
1230 |
|
|
koethe@1199
|
1231 |
The functor realizes the transformation
|
|
koethe@1199
|
1232 |
|
|
koethe@1199
|
1233 |
\f[
|
|
koethe@1199
|
1234 |
\begin{array}{rcl}
|
|
ullrich@1792
|
1235 |
L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad \frac{216}{24389} < \frac{Y}{Y_n}\\
|
|
koethe@1199
|
1236 |
& & \\
|
|
ullrich@1792
|
1237 |
L^{*} & = & \frac{24389}{27} \enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
|
|
koethe@1199
|
1238 |
& & \\
|
|
koethe@1199
|
1239 |
a^{*} & = & 500 \left[ \left( \frac{X}{X_n} \right)^\frac{1}{3} - \left( \frac{Y}{Y_n} \right)^\frac{1}{3} \right] \\
|
|
koethe@1199
|
1240 |
& & \\
|
|
koethe@1199
|
1241 |
b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\
|
|
koethe@1199
|
1242 |
\end{array}
|
|
koethe@1199
|
1243 |
\f]
|
|
koethe@1199
|
1244 |
|
|
ullrich@1792
|
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.
|
|
ullrich@1793
|
1246 |
\f$L^{*}\f$ represents the <em>lightness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ code the
|
|
ullrich@1792
|
1247 |
chromaticity. (Instead of the rationals \f$\frac{216}{24389}\f$ and \f$\frac{24389}{27}\f$, the original standard gives the
|
|
ullrich@1792
|
1248 |
rounded values 0.008856 and 903.3. As <a href="http://www.brucelindbloom.com/index.html?LContinuity.html">Bruce Lindbloom</a>
|
|
ullrich@1792
|
1249 |
points out, the rounded values give raise to a discontinuity which is removed by the accurate rationals. This bug will be fixed
|
|
ullrich@1792
|
1250 |
in future versions of the CIE Lab standard.)
|
|
koethe@1199
|
1251 |
|
|
koethe@1199
|
1252 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1253 |
|
|
koethe@1623
|
1254 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1255 |
*/
|
|
koethe@1199
|
1256 |
template <class T>
|
|
koethe@1199
|
1257 |
class XYZ2LabFunctor
|
|
koethe@1199
|
1258 |
{
|
|
koethe@1199
|
1259 |
public:
|
|
koethe@1199
|
1260 |
|
|
koethe@1199
|
1261 |
/** the result's component type
|
|
koethe@1199
|
1262 |
*/
|
|
koethe@1199
|
1263 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1264 |
|
|
koethe@1199
|
1265 |
/** the functor's argument type
|
|
koethe@1199
|
1266 |
*/
|
|
koethe@1199
|
1267 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1268 |
|
|
koethe@1199
|
1269 |
/** the functor's result type
|
|
koethe@1199
|
1270 |
*/
|
|
koethe@1199
|
1271 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
1272 |
|
|
koethe@1199
|
1273 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1274 |
*/
|
|
koethe@1199
|
1275 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
1276 |
|
|
koethe@1199
|
1277 |
XYZ2LabFunctor()
|
|
ullrich@1792
|
1278 |
: gamma_(1.0/3.0),
|
|
ullrich@1792
|
1279 |
kappa_(24389.0/27.0),
|
|
ullrich@1792
|
1280 |
epsilon_(216.0/24389.0)
|
|
koethe@1199
|
1281 |
{}
|
|
koethe@1199
|
1282 |
|
|
koethe@1199
|
1283 |
/** apply the transformation
|
|
koethe@1199
|
1284 |
*/
|
|
koethe@1199
|
1285 |
template <class V>
|
|
koethe@1199
|
1286 |
result_type operator()(V const & xyz) const
|
|
koethe@1199
|
1287 |
{
|
|
ullrich@2455
|
1288 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
1289 |
component_type xgamma = Convert::cast(std::pow(xyz[0] / 0.950456, gamma_));
|
|
ullrich@2455
|
1290 |
component_type ygamma = Convert::cast(std::pow((double)xyz[1], gamma_));
|
|
ullrich@2455
|
1291 |
component_type zgamma = Convert::cast(std::pow(xyz[2] / 1.088754, gamma_));
|
|
ullrich@2455
|
1292 |
component_type L = Convert::cast(
|
|
ullrich@2455
|
1293 |
xyz[1] < epsilon_
|
|
ullrich@2455
|
1294 |
? kappa_ * xyz[1]
|
|
ullrich@2455
|
1295 |
: 116.0 * ygamma - 16.0);
|
|
koethe@1199
|
1296 |
result_type result;
|
|
koethe@1199
|
1297 |
result[0] = L;
|
|
ullrich@2455
|
1298 |
result[1] = Convert::cast(500.0*(xgamma - ygamma));
|
|
ullrich@2455
|
1299 |
result[2] = Convert::cast(200.0*(ygamma - zgamma));
|
|
koethe@1199
|
1300 |
return result;
|
|
koethe@1199
|
1301 |
}
|
|
koethe@1199
|
1302 |
|
|
koethe@1199
|
1303 |
private:
|
|
ullrich@1792
|
1304 |
double gamma_, kappa_, epsilon_;
|
|
koethe@1199
|
1305 |
};
|
|
koethe@1199
|
1306 |
|
|
koethe@1199
|
1307 |
template <class T>
|
|
koethe@1199
|
1308 |
class FunctorTraits<XYZ2LabFunctor<T> >
|
|
koethe@1199
|
1309 |
: public FunctorTraitsBase<XYZ2LabFunctor<T> >
|
|
koethe@1199
|
1310 |
{
|
|
koethe@1199
|
1311 |
public:
|
|
koethe@1199
|
1312 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1313 |
};
|
|
koethe@1199
|
1314 |
|
|
koethe@1199
|
1315 |
/** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stimulus XYZ.
|
|
koethe@1199
|
1316 |
|
|
koethe@1623
|
1317 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1318 |
Namespace: vigra
|
|
koethe@1199
|
1319 |
|
|
koethe@1199
|
1320 |
The functor realizes the inverse of the transformation described in vigra::XYZ2LabFunctor
|
|
koethe@1199
|
1321 |
|
|
koethe@1199
|
1322 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1323 |
|
|
koethe@1623
|
1324 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1325 |
*/
|
|
koethe@1199
|
1326 |
template <class T>
|
|
koethe@1199
|
1327 |
class Lab2XYZFunctor
|
|
koethe@1199
|
1328 |
{
|
|
koethe@1199
|
1329 |
public:
|
|
koethe@1199
|
1330 |
|
|
koethe@1199
|
1331 |
/** the result's component type
|
|
koethe@1199
|
1332 |
*/
|
|
koethe@1199
|
1333 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1334 |
|
|
koethe@1199
|
1335 |
/** the functor's argument type
|
|
koethe@1199
|
1336 |
*/
|
|
koethe@1199
|
1337 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1338 |
|
|
koethe@1199
|
1339 |
/** the functor's result type
|
|
koethe@1199
|
1340 |
*/
|
|
koethe@1199
|
1341 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
1342 |
|
|
koethe@1199
|
1343 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1344 |
*/
|
|
koethe@1199
|
1345 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
1346 |
|
|
koethe@1199
|
1347 |
/** the functor's value type
|
|
koethe@1199
|
1348 |
*/
|
|
koethe@1199
|
1349 |
Lab2XYZFunctor()
|
|
ullrich@1792
|
1350 |
: gamma_(3.0),
|
|
ullrich@1792
|
1351 |
ikappa_(27.0/24389.0)
|
|
koethe@1199
|
1352 |
{}
|
|
koethe@1199
|
1353 |
|
|
koethe@1199
|
1354 |
/** apply the transformation
|
|
koethe@1199
|
1355 |
*/
|
|
koethe@1199
|
1356 |
template <class V>
|
|
koethe@1199
|
1357 |
result_type operator()(V const & lab) const
|
|
koethe@1199
|
1358 |
{
|
|
ullrich@2455
|
1359 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
1360 |
component_type Y = Convert::cast(
|
|
ullrich@2455
|
1361 |
lab[0] < 8.0
|
|
ullrich@2455
|
1362 |
? lab[0] * ikappa_
|
|
ullrich@2455
|
1363 |
: std::pow((lab[0] + 16.0) / 116.0, gamma_));
|
|
ullrich@2455
|
1364 |
component_type ygamma = Convert::cast(std::pow((double)Y, 1.0 / gamma_));
|
|
ullrich@2455
|
1365 |
component_type X = Convert::cast(std::pow(lab[1] / 500.0 + ygamma, gamma_) * 0.950456);
|
|
ullrich@2455
|
1366 |
component_type Z = Convert::cast(std::pow(-lab[2] / 200.0 + ygamma, gamma_) * 1.088754);
|
|
koethe@1199
|
1367 |
result_type result;
|
|
koethe@1199
|
1368 |
result[0] = X;
|
|
koethe@1199
|
1369 |
result[1] = Y;
|
|
koethe@1199
|
1370 |
result[2] = Z;
|
|
koethe@1199
|
1371 |
return result;
|
|
koethe@1199
|
1372 |
}
|
|
koethe@1199
|
1373 |
|
|
koethe@1199
|
1374 |
private:
|
|
ullrich@1792
|
1375 |
double gamma_, ikappa_;
|
|
koethe@1199
|
1376 |
};
|
|
koethe@1199
|
1377 |
|
|
koethe@1199
|
1378 |
template <class T>
|
|
koethe@1199
|
1379 |
class FunctorTraits<Lab2XYZFunctor<T> >
|
|
koethe@1199
|
1380 |
: public FunctorTraitsBase<Lab2XYZFunctor<T> >
|
|
koethe@1199
|
1381 |
{
|
|
koethe@1199
|
1382 |
public:
|
|
koethe@1199
|
1383 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1384 |
};
|
|
koethe@1199
|
1385 |
|
|
koethe@1199
|
1386 |
/** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*.
|
|
koethe@1199
|
1387 |
|
|
koethe@1623
|
1388 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1389 |
Namespace: vigra
|
|
koethe@1199
|
1390 |
|
|
koethe@1199
|
1391 |
The functor realizes the transformation
|
|
koethe@1199
|
1392 |
|
|
koethe@1199
|
1393 |
\f[
|
|
koethe@1199
|
1394 |
RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
|
|
koethe@1199
|
1395 |
\f]
|
|
koethe@1199
|
1396 |
|
|
koethe@1199
|
1397 |
See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the two
|
|
koethe@1199
|
1398 |
steps. The resulting color components will have the following bounds:
|
|
koethe@1199
|
1399 |
|
|
koethe@1199
|
1400 |
\f[
|
|
koethe@1199
|
1401 |
\begin{array}{rcl}
|
|
koethe@1199
|
1402 |
0 \leq & L^* & \leq 100 \\
|
|
koethe@1199
|
1403 |
-83.077 \leq & u^* & \leq 175.015 \\
|
|
koethe@1199
|
1404 |
-134.101 \leq & v^* & \leq 107.393
|
|
koethe@1199
|
1405 |
\end{array}
|
|
koethe@1199
|
1406 |
\f]
|
|
koethe@1199
|
1407 |
|
|
koethe@1199
|
1408 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1409 |
|
|
koethe@1623
|
1410 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1411 |
*/
|
|
koethe@1199
|
1412 |
template <class T>
|
|
koethe@1199
|
1413 |
class RGB2LuvFunctor
|
|
koethe@1199
|
1414 |
{
|
|
koethe@1199
|
1415 |
/*
|
|
koethe@1199
|
1416 |
L in [0, 100]
|
|
koethe@1199
|
1417 |
u in [-83.077, 175.015]
|
|
koethe@1199
|
1418 |
v in [-134.101, 107.393]
|
|
koethe@1199
|
1419 |
maximum saturation: 179.04
|
|
koethe@1199
|
1420 |
red = [53.2406, 175.015, 37.7522]
|
|
koethe@1199
|
1421 |
*/
|
|
koethe@1199
|
1422 |
public:
|
|
koethe@1199
|
1423 |
|
|
koethe@1199
|
1424 |
/** the result's component type
|
|
koethe@1199
|
1425 |
*/
|
|
koethe@1199
|
1426 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1427 |
|
|
koethe@1199
|
1428 |
/** the functor's argument type
|
|
koethe@1199
|
1429 |
*/
|
|
koethe@1199
|
1430 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1431 |
|
|
koethe@1199
|
1432 |
/** the functor's result type
|
|
koethe@1199
|
1433 |
*/
|
|
koethe@1199
|
1434 |
typedef typename XYZ2LuvFunctor<component_type>::result_type result_type;
|
|
koethe@1199
|
1435 |
|
|
koethe@1199
|
1436 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1437 |
*/
|
|
koethe@1199
|
1438 |
typedef typename XYZ2LuvFunctor<component_type>::result_type value_type;
|
|
koethe@1199
|
1439 |
|
|
koethe@1199
|
1440 |
/** default constructor.
|
|
koethe@1199
|
1441 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
1442 |
*/
|
|
koethe@1199
|
1443 |
RGB2LuvFunctor()
|
|
koethe@1199
|
1444 |
: rgb2xyz(255.0)
|
|
koethe@1199
|
1445 |
{}
|
|
koethe@1199
|
1446 |
|
|
koethe@1199
|
1447 |
/** constructor
|
|
koethe@1199
|
1448 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
1449 |
*/
|
|
koethe@1199
|
1450 |
RGB2LuvFunctor(component_type max)
|
|
koethe@1199
|
1451 |
: rgb2xyz(max)
|
|
koethe@1199
|
1452 |
{}
|
|
koethe@1199
|
1453 |
|
|
koethe@1199
|
1454 |
/** apply the transformation
|
|
koethe@1199
|
1455 |
*/
|
|
koethe@1199
|
1456 |
template <class V>
|
|
koethe@1199
|
1457 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
1458 |
{
|
|
koethe@1199
|
1459 |
return xyz2luv(rgb2xyz(rgb));
|
|
koethe@1199
|
1460 |
}
|
|
koethe@1199
|
1461 |
|
|
koethe@1199
|
1462 |
private:
|
|
koethe@1199
|
1463 |
RGB2XYZFunctor<T> rgb2xyz;
|
|
koethe@1199
|
1464 |
XYZ2LuvFunctor<component_type> xyz2luv;
|
|
koethe@1199
|
1465 |
};
|
|
koethe@1199
|
1466 |
|
|
koethe@1199
|
1467 |
template <class T>
|
|
koethe@1199
|
1468 |
class FunctorTraits<RGB2LuvFunctor<T> >
|
|
koethe@1199
|
1469 |
: public FunctorTraitsBase<RGB2LuvFunctor<T> >
|
|
koethe@1199
|
1470 |
{
|
|
koethe@1199
|
1471 |
public:
|
|
koethe@1199
|
1472 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1473 |
};
|
|
koethe@1199
|
1474 |
|
|
koethe@1199
|
1475 |
/** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*.
|
|
koethe@1199
|
1476 |
|
|
koethe@1623
|
1477 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1478 |
Namespace: vigra
|
|
koethe@1199
|
1479 |
|
|
koethe@1199
|
1480 |
The functor realizes the transformation
|
|
koethe@1199
|
1481 |
|
|
koethe@1199
|
1482 |
\f[
|
|
koethe@1199
|
1483 |
RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
|
|
koethe@1199
|
1484 |
\f]
|
|
koethe@1199
|
1485 |
|
|
koethe@1199
|
1486 |
See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the two
|
|
koethe@1199
|
1487 |
steps. The resulting color components will have the following bounds:
|
|
koethe@1199
|
1488 |
|
|
koethe@1199
|
1489 |
\f[
|
|
koethe@1199
|
1490 |
\begin{array}{rcl}
|
|
koethe@1199
|
1491 |
0 \leq & L^* & \leq 100 \\
|
|
koethe@1199
|
1492 |
-86.1813 \leq & u^* & \leq 98.2352 \\
|
|
koethe@1199
|
1493 |
-107.862 \leq & v^* & \leq 94.4758
|
|
koethe@1199
|
1494 |
\end{array}
|
|
koethe@1199
|
1495 |
\f]
|
|
koethe@1199
|
1496 |
|
|
koethe@1199
|
1497 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1498 |
|
|
koethe@1623
|
1499 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1500 |
*/
|
|
koethe@1199
|
1501 |
template <class T>
|
|
koethe@1199
|
1502 |
class RGB2LabFunctor
|
|
koethe@1199
|
1503 |
{
|
|
koethe@1199
|
1504 |
/*
|
|
koethe@1199
|
1505 |
L in [0, 100]
|
|
koethe@1199
|
1506 |
a in [-86.1813, 98.2352]
|
|
koethe@1199
|
1507 |
b in [-107.862, 94.4758]
|
|
koethe@1199
|
1508 |
maximum saturation: 133.809
|
|
koethe@1199
|
1509 |
red = [53.2406, 80.0942, 67.2015]
|
|
koethe@1199
|
1510 |
*/
|
|
koethe@1199
|
1511 |
public:
|
|
koethe@1199
|
1512 |
|
|
koethe@1199
|
1513 |
/** the result's component type
|
|
koethe@1199
|
1514 |
*/
|
|
koethe@1199
|
1515 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1516 |
|
|
koethe@1199
|
1517 |
/** the functor's argument type
|
|
koethe@1199
|
1518 |
*/
|
|
koethe@1199
|
1519 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1520 |
|
|
koethe@1199
|
1521 |
/** the functor's result type
|
|
koethe@1199
|
1522 |
*/
|
|
koethe@1199
|
1523 |
typedef typename XYZ2LabFunctor<component_type>::result_type result_type;
|
|
koethe@1199
|
1524 |
|
|
koethe@1199
|
1525 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1526 |
*/
|
|
koethe@1199
|
1527 |
typedef typename XYZ2LabFunctor<component_type>::result_type value_type;
|
|
koethe@1199
|
1528 |
|
|
koethe@1199
|
1529 |
/** default constructor.
|
|
koethe@1199
|
1530 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
1531 |
*/
|
|
koethe@1199
|
1532 |
RGB2LabFunctor()
|
|
koethe@1199
|
1533 |
: rgb2xyz(255.0)
|
|
koethe@1199
|
1534 |
{}
|
|
koethe@1199
|
1535 |
|
|
koethe@1199
|
1536 |
/** constructor
|
|
koethe@1199
|
1537 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
1538 |
*/
|
|
koethe@1199
|
1539 |
RGB2LabFunctor(component_type max)
|
|
koethe@1199
|
1540 |
: rgb2xyz(max)
|
|
koethe@1199
|
1541 |
{}
|
|
koethe@1199
|
1542 |
|
|
koethe@1199
|
1543 |
/** apply the transformation
|
|
koethe@1199
|
1544 |
*/
|
|
koethe@1199
|
1545 |
template <class V>
|
|
koethe@1199
|
1546 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
1547 |
{
|
|
koethe@1199
|
1548 |
return xyz2lab(rgb2xyz(rgb));
|
|
koethe@1199
|
1549 |
}
|
|
koethe@1199
|
1550 |
|
|
koethe@1199
|
1551 |
private:
|
|
koethe@1199
|
1552 |
RGB2XYZFunctor<T> rgb2xyz;
|
|
koethe@1199
|
1553 |
XYZ2LabFunctor<component_type> xyz2lab;
|
|
koethe@1199
|
1554 |
};
|
|
koethe@1199
|
1555 |
|
|
koethe@1199
|
1556 |
template <class T>
|
|
koethe@1199
|
1557 |
class FunctorTraits<RGB2LabFunctor<T> >
|
|
koethe@1199
|
1558 |
: public FunctorTraitsBase<RGB2LabFunctor<T> >
|
|
koethe@1199
|
1559 |
{
|
|
koethe@1199
|
1560 |
public:
|
|
koethe@1199
|
1561 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1562 |
};
|
|
koethe@1199
|
1563 |
|
|
koethe@1199
|
1564 |
/** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB.
|
|
koethe@1199
|
1565 |
|
|
koethe@1623
|
1566 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1567 |
Namespace: vigra
|
|
koethe@1199
|
1568 |
|
|
koethe@1199
|
1569 |
The functor realizes the inverse of the transformation described in vigra::RGB2LuvFunctor
|
|
koethe@1199
|
1570 |
|
|
koethe@1199
|
1571 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1572 |
|
|
koethe@1623
|
1573 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1574 |
*/
|
|
koethe@1199
|
1575 |
template <class T>
|
|
koethe@1199
|
1576 |
class Luv2RGBFunctor
|
|
koethe@1199
|
1577 |
{
|
|
koethe@1199
|
1578 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1579 |
|
|
koethe@1199
|
1580 |
XYZ2RGBFunctor<T> xyz2rgb;
|
|
koethe@1199
|
1581 |
Luv2XYZFunctor<component_type> luv2xyz;
|
|
koethe@1199
|
1582 |
|
|
koethe@1199
|
1583 |
public:
|
|
koethe@1199
|
1584 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
1585 |
can be any vector type with the same interface.
|
|
koethe@1199
|
1586 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
1587 |
*/
|
|
koethe@1199
|
1588 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1589 |
|
|
koethe@1199
|
1590 |
/** the functor's result type
|
|
koethe@1199
|
1591 |
*/
|
|
koethe@1199
|
1592 |
typedef typename XYZ2RGBFunctor<T>::result_type result_type;
|
|
koethe@1199
|
1593 |
|
|
koethe@1199
|
1594 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1595 |
*/
|
|
koethe@1199
|
1596 |
typedef typename XYZ2RGBFunctor<T>::result_type value_type;
|
|
koethe@1199
|
1597 |
|
|
koethe@1199
|
1598 |
Luv2RGBFunctor()
|
|
koethe@1199
|
1599 |
: xyz2rgb(255.0)
|
|
koethe@1199
|
1600 |
{}
|
|
koethe@1199
|
1601 |
|
|
koethe@1199
|
1602 |
Luv2RGBFunctor(component_type max)
|
|
koethe@1199
|
1603 |
: xyz2rgb(max)
|
|
koethe@1199
|
1604 |
{}
|
|
koethe@1199
|
1605 |
|
|
koethe@1199
|
1606 |
/** apply the transformation
|
|
koethe@1199
|
1607 |
*/
|
|
koethe@1199
|
1608 |
template <class V>
|
|
koethe@1199
|
1609 |
result_type operator()(V const & luv) const
|
|
koethe@1199
|
1610 |
{
|
|
koethe@1199
|
1611 |
return xyz2rgb(luv2xyz(luv));
|
|
koethe@1199
|
1612 |
}
|
|
koethe@1199
|
1613 |
};
|
|
koethe@1199
|
1614 |
|
|
koethe@1199
|
1615 |
template <class T>
|
|
koethe@1199
|
1616 |
class FunctorTraits<Luv2RGBFunctor<T> >
|
|
koethe@1199
|
1617 |
: public FunctorTraitsBase<Luv2RGBFunctor<T> >
|
|
koethe@1199
|
1618 |
{
|
|
koethe@1199
|
1619 |
public:
|
|
koethe@1199
|
1620 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1621 |
};
|
|
koethe@1199
|
1622 |
|
|
koethe@1199
|
1623 |
/** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB.
|
|
koethe@1199
|
1624 |
|
|
koethe@1623
|
1625 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1626 |
Namespace: vigra
|
|
koethe@1199
|
1627 |
|
|
koethe@1199
|
1628 |
The functor realizes the inverse of the transformation described in vigra::RGB2LabFunctor
|
|
koethe@1199
|
1629 |
|
|
koethe@1199
|
1630 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1631 |
|
|
koethe@1623
|
1632 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1633 |
*/
|
|
koethe@1199
|
1634 |
template <class T>
|
|
koethe@1199
|
1635 |
class Lab2RGBFunctor
|
|
koethe@1199
|
1636 |
{
|
|
koethe@1199
|
1637 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1638 |
|
|
koethe@1199
|
1639 |
XYZ2RGBFunctor<T> xyz2rgb;
|
|
koethe@1199
|
1640 |
Lab2XYZFunctor<component_type> lab2xyz;
|
|
koethe@1199
|
1641 |
|
|
koethe@1199
|
1642 |
public:
|
|
koethe@1199
|
1643 |
|
|
koethe@1199
|
1644 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
1645 |
can be any vector type with the same interface.
|
|
koethe@1199
|
1646 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
1647 |
*/
|
|
koethe@1199
|
1648 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1649 |
|
|
koethe@1199
|
1650 |
/** the functor's result type
|
|
koethe@1199
|
1651 |
*/
|
|
koethe@1199
|
1652 |
typedef typename XYZ2RGBFunctor<T>::result_type result_type;
|
|
koethe@1199
|
1653 |
|
|
koethe@1199
|
1654 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1655 |
*/
|
|
koethe@1199
|
1656 |
typedef typename XYZ2RGBFunctor<T>::result_type value_type;
|
|
koethe@1199
|
1657 |
|
|
koethe@1199
|
1658 |
/** default constructor.
|
|
koethe@1199
|
1659 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
1660 |
*/
|
|
koethe@1199
|
1661 |
Lab2RGBFunctor()
|
|
koethe@1199
|
1662 |
: xyz2rgb(255.0)
|
|
koethe@1199
|
1663 |
{}
|
|
koethe@1199
|
1664 |
|
|
koethe@1199
|
1665 |
/** constructor
|
|
koethe@1199
|
1666 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
1667 |
*/
|
|
koethe@1199
|
1668 |
Lab2RGBFunctor(component_type max)
|
|
koethe@1199
|
1669 |
: xyz2rgb(max)
|
|
koethe@1199
|
1670 |
{}
|
|
koethe@1199
|
1671 |
|
|
koethe@1199
|
1672 |
/** apply the transformation
|
|
koethe@1199
|
1673 |
*/
|
|
koethe@1199
|
1674 |
template <class V>
|
|
koethe@1199
|
1675 |
result_type operator()(V const & lab) const
|
|
koethe@1199
|
1676 |
{
|
|
koethe@1199
|
1677 |
return xyz2rgb(lab2xyz(lab));
|
|
koethe@1199
|
1678 |
}
|
|
koethe@1199
|
1679 |
};
|
|
koethe@1199
|
1680 |
|
|
koethe@1199
|
1681 |
template <class T>
|
|
koethe@1199
|
1682 |
class FunctorTraits<Lab2RGBFunctor<T> >
|
|
koethe@1199
|
1683 |
: public FunctorTraitsBase<Lab2RGBFunctor<T> >
|
|
koethe@1199
|
1684 |
{
|
|
koethe@1199
|
1685 |
public:
|
|
koethe@1199
|
1686 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1687 |
};
|
|
koethe@1199
|
1688 |
|
|
koethe@1199
|
1689 |
/** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*u*v*.
|
|
koethe@1199
|
1690 |
|
|
koethe@1623
|
1691 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1692 |
Namespace: vigra
|
|
koethe@1199
|
1693 |
|
|
koethe@1199
|
1694 |
The functor realizes the transformation
|
|
koethe@1199
|
1695 |
|
|
koethe@1199
|
1696 |
\f[
|
|
koethe@1199
|
1697 |
R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
|
|
koethe@1199
|
1698 |
\f]
|
|
koethe@1199
|
1699 |
|
|
koethe@1199
|
1700 |
See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the three
|
|
koethe@1199
|
1701 |
steps. The resulting color components will have the following bounds:
|
|
koethe@1199
|
1702 |
|
|
koethe@1199
|
1703 |
\f[
|
|
koethe@1199
|
1704 |
\begin{array}{rcl}
|
|
koethe@1199
|
1705 |
0 \leq & L^* & \leq 100 \\
|
|
koethe@1199
|
1706 |
-83.077 \leq & u^* & \leq 175.015 \\
|
|
koethe@1199
|
1707 |
-134.101 \leq & v^* & \leq 107.393
|
|
koethe@1199
|
1708 |
\end{array}
|
|
koethe@1199
|
1709 |
\f]
|
|
koethe@1199
|
1710 |
|
|
koethe@1199
|
1711 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1712 |
|
|
koethe@1623
|
1713 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1714 |
*/
|
|
koethe@1199
|
1715 |
template <class T>
|
|
koethe@1199
|
1716 |
class RGBPrime2LuvFunctor
|
|
koethe@1199
|
1717 |
{
|
|
koethe@1199
|
1718 |
public:
|
|
koethe@1199
|
1719 |
|
|
koethe@1199
|
1720 |
/** the result's component type
|
|
koethe@1199
|
1721 |
*/
|
|
koethe@1199
|
1722 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1723 |
|
|
koethe@1199
|
1724 |
/** the functor's argument type
|
|
koethe@1199
|
1725 |
*/
|
|
koethe@1199
|
1726 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1727 |
|
|
koethe@1199
|
1728 |
/** the functor's result type
|
|
koethe@1199
|
1729 |
*/
|
|
koethe@1199
|
1730 |
typedef typename XYZ2LuvFunctor<component_type>::result_type result_type;
|
|
koethe@1199
|
1731 |
|
|
koethe@1199
|
1732 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1733 |
*/
|
|
koethe@1199
|
1734 |
typedef typename XYZ2LuvFunctor<component_type>::result_type value_type;
|
|
koethe@1199
|
1735 |
|
|
koethe@1199
|
1736 |
/** default constructor.
|
|
koethe@1199
|
1737 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
1738 |
*/
|
|
koethe@1199
|
1739 |
RGBPrime2LuvFunctor()
|
|
koethe@1199
|
1740 |
: rgb2xyz(255.0)
|
|
koethe@1199
|
1741 |
{}
|
|
koethe@1199
|
1742 |
|
|
koethe@1199
|
1743 |
/** constructor
|
|
koethe@1199
|
1744 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
1745 |
*/
|
|
koethe@1199
|
1746 |
RGBPrime2LuvFunctor(component_type max)
|
|
koethe@1199
|
1747 |
: rgb2xyz(max)
|
|
koethe@1199
|
1748 |
{}
|
|
koethe@1199
|
1749 |
|
|
koethe@1199
|
1750 |
/** apply the transformation
|
|
koethe@1199
|
1751 |
*/
|
|
koethe@1199
|
1752 |
template <class V>
|
|
koethe@1199
|
1753 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
1754 |
{
|
|
koethe@1199
|
1755 |
return xyz2luv(rgb2xyz(rgb));
|
|
koethe@1199
|
1756 |
}
|
|
koethe@1199
|
1757 |
|
|
koethe@1199
|
1758 |
private:
|
|
koethe@1199
|
1759 |
RGBPrime2XYZFunctor<T> rgb2xyz;
|
|
koethe@1199
|
1760 |
XYZ2LuvFunctor<component_type> xyz2luv;
|
|
koethe@1199
|
1761 |
};
|
|
koethe@1199
|
1762 |
|
|
koethe@1199
|
1763 |
template <class T>
|
|
koethe@1199
|
1764 |
class FunctorTraits<RGBPrime2LuvFunctor<T> >
|
|
koethe@1199
|
1765 |
: public FunctorTraitsBase<RGBPrime2LuvFunctor<T> >
|
|
koethe@1199
|
1766 |
{
|
|
koethe@1199
|
1767 |
public:
|
|
koethe@1199
|
1768 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1769 |
};
|
|
koethe@1199
|
1770 |
|
|
koethe@1199
|
1771 |
/** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*a*b*.
|
|
koethe@1199
|
1772 |
|
|
koethe@1623
|
1773 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1774 |
Namespace: vigra
|
|
koethe@1199
|
1775 |
|
|
koethe@1199
|
1776 |
The functor realizes the transformation
|
|
koethe@1199
|
1777 |
|
|
koethe@1199
|
1778 |
\f[
|
|
koethe@1199
|
1779 |
R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
|
|
koethe@1199
|
1780 |
\f]
|
|
koethe@1199
|
1781 |
|
|
koethe@1199
|
1782 |
See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the three
|
|
koethe@1199
|
1783 |
steps. The resulting color components will have the following bounds:
|
|
koethe@1199
|
1784 |
|
|
koethe@1199
|
1785 |
\f[
|
|
koethe@1199
|
1786 |
\begin{array}{rcl}
|
|
koethe@1199
|
1787 |
0 \leq & L^* & \leq 100 \\
|
|
koethe@1199
|
1788 |
-86.1813 \leq & u^* & \leq 98.2352 \\
|
|
koethe@1199
|
1789 |
-107.862 \leq & v^* & \leq 94.4758
|
|
koethe@1199
|
1790 |
\end{array}
|
|
koethe@1199
|
1791 |
\f]
|
|
koethe@1199
|
1792 |
|
|
koethe@1199
|
1793 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1794 |
|
|
koethe@1623
|
1795 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1796 |
*/
|
|
koethe@1199
|
1797 |
template <class T>
|
|
koethe@1199
|
1798 |
class RGBPrime2LabFunctor
|
|
koethe@1199
|
1799 |
{
|
|
koethe@1199
|
1800 |
public:
|
|
koethe@1199
|
1801 |
|
|
koethe@1199
|
1802 |
/** the result's component type
|
|
koethe@1199
|
1803 |
*/
|
|
koethe@1199
|
1804 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1805 |
|
|
koethe@1199
|
1806 |
/** the functor's argument type
|
|
koethe@1199
|
1807 |
*/
|
|
koethe@1199
|
1808 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1809 |
|
|
koethe@1199
|
1810 |
/** the functor's result type
|
|
koethe@1199
|
1811 |
*/
|
|
koethe@1199
|
1812 |
typedef typename XYZ2LabFunctor<component_type>::result_type result_type;
|
|
koethe@1199
|
1813 |
|
|
koethe@1199
|
1814 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1815 |
*/
|
|
koethe@1199
|
1816 |
typedef typename XYZ2LabFunctor<component_type>::result_type value_type;
|
|
koethe@1199
|
1817 |
|
|
koethe@1199
|
1818 |
/** default constructor.
|
|
koethe@1199
|
1819 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
1820 |
*/
|
|
koethe@1199
|
1821 |
RGBPrime2LabFunctor()
|
|
koethe@1199
|
1822 |
: rgb2xyz(255.0)
|
|
koethe@1199
|
1823 |
{}
|
|
koethe@1199
|
1824 |
|
|
koethe@1199
|
1825 |
/** constructor
|
|
koethe@1199
|
1826 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
1827 |
*/
|
|
koethe@1199
|
1828 |
RGBPrime2LabFunctor(component_type max)
|
|
koethe@1199
|
1829 |
: rgb2xyz(max)
|
|
koethe@1199
|
1830 |
{}
|
|
koethe@1199
|
1831 |
|
|
koethe@1199
|
1832 |
/** apply the transformation
|
|
koethe@1199
|
1833 |
*/
|
|
koethe@1199
|
1834 |
template <class V>
|
|
koethe@1199
|
1835 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
1836 |
{
|
|
koethe@1199
|
1837 |
return xyz2lab(rgb2xyz(rgb));
|
|
koethe@1199
|
1838 |
}
|
|
koethe@1199
|
1839 |
|
|
koethe@1199
|
1840 |
private:
|
|
koethe@1199
|
1841 |
RGBPrime2XYZFunctor<T> rgb2xyz;
|
|
koethe@1199
|
1842 |
XYZ2LabFunctor<component_type> xyz2lab;
|
|
koethe@1199
|
1843 |
};
|
|
koethe@1199
|
1844 |
|
|
koethe@1199
|
1845 |
template <class T>
|
|
koethe@1199
|
1846 |
class FunctorTraits<RGBPrime2LabFunctor<T> >
|
|
koethe@1199
|
1847 |
: public FunctorTraitsBase<RGBPrime2LabFunctor<T> >
|
|
koethe@1199
|
1848 |
{
|
|
koethe@1199
|
1849 |
public:
|
|
koethe@1199
|
1850 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1851 |
};
|
|
koethe@1199
|
1852 |
|
|
koethe@1199
|
1853 |
/** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma corrected) R'G'B'.
|
|
koethe@1199
|
1854 |
|
|
koethe@1623
|
1855 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1856 |
Namespace: vigra
|
|
koethe@1199
|
1857 |
|
|
koethe@1199
|
1858 |
The functor realizes the inverse of the transformation described in vigra::RGBPrime2LuvFunctor
|
|
koethe@1199
|
1859 |
|
|
koethe@1199
|
1860 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1861 |
|
|
koethe@1623
|
1862 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1863 |
*/
|
|
koethe@1199
|
1864 |
template <class T>
|
|
koethe@1199
|
1865 |
class Luv2RGBPrimeFunctor
|
|
koethe@1199
|
1866 |
{
|
|
koethe@1199
|
1867 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1868 |
|
|
koethe@1199
|
1869 |
XYZ2RGBPrimeFunctor<T> xyz2rgb;
|
|
koethe@1199
|
1870 |
Luv2XYZFunctor<component_type> luv2xyz;
|
|
koethe@1199
|
1871 |
|
|
koethe@1199
|
1872 |
public:
|
|
koethe@1199
|
1873 |
|
|
koethe@1199
|
1874 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
1875 |
can be any vector type with the same interface.
|
|
koethe@1199
|
1876 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
1877 |
*/
|
|
koethe@1199
|
1878 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1879 |
|
|
koethe@1199
|
1880 |
/** the functor's result type
|
|
koethe@1199
|
1881 |
*/
|
|
koethe@1199
|
1882 |
typedef typename XYZ2RGBFunctor<T>::result_type result_type;
|
|
koethe@1199
|
1883 |
|
|
koethe@1199
|
1884 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1885 |
*/
|
|
koethe@1199
|
1886 |
typedef typename XYZ2RGBFunctor<T>::result_type value_type;
|
|
koethe@1199
|
1887 |
|
|
koethe@1199
|
1888 |
/** default constructor.
|
|
koethe@1199
|
1889 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
1890 |
*/
|
|
koethe@1199
|
1891 |
Luv2RGBPrimeFunctor()
|
|
koethe@1199
|
1892 |
: xyz2rgb(255.0)
|
|
koethe@1199
|
1893 |
{}
|
|
koethe@1199
|
1894 |
|
|
koethe@1199
|
1895 |
/** constructor
|
|
koethe@1199
|
1896 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
1897 |
*/
|
|
koethe@1199
|
1898 |
Luv2RGBPrimeFunctor(component_type max)
|
|
koethe@1199
|
1899 |
: xyz2rgb(max)
|
|
koethe@1199
|
1900 |
{}
|
|
koethe@1199
|
1901 |
|
|
koethe@1199
|
1902 |
/** apply the transformation
|
|
koethe@1199
|
1903 |
*/
|
|
koethe@1199
|
1904 |
template <class V>
|
|
koethe@1199
|
1905 |
result_type operator()(V const & luv) const
|
|
koethe@1199
|
1906 |
{
|
|
koethe@1199
|
1907 |
return xyz2rgb(luv2xyz(luv));
|
|
koethe@1199
|
1908 |
}
|
|
koethe@1199
|
1909 |
};
|
|
koethe@1199
|
1910 |
|
|
koethe@1199
|
1911 |
template <class T>
|
|
koethe@1199
|
1912 |
class FunctorTraits<Luv2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
1913 |
: public FunctorTraitsBase<Luv2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
1914 |
{
|
|
koethe@1199
|
1915 |
public:
|
|
koethe@1199
|
1916 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1917 |
};
|
|
koethe@1199
|
1918 |
|
|
koethe@1199
|
1919 |
/** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma corrected) R'G'B'.
|
|
koethe@1199
|
1920 |
|
|
koethe@1623
|
1921 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1922 |
Namespace: vigra
|
|
koethe@1199
|
1923 |
|
|
koethe@1199
|
1924 |
The functor realizes the inverse of the transformation described in vigra::RGBPrime2LabFunctor
|
|
koethe@1199
|
1925 |
|
|
koethe@1199
|
1926 |
<b> Traits defined:</b>
|
|
koethe@1199
|
1927 |
|
|
koethe@1623
|
1928 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
1929 |
*/
|
|
koethe@1199
|
1930 |
template <class T>
|
|
koethe@1199
|
1931 |
class Lab2RGBPrimeFunctor
|
|
koethe@1199
|
1932 |
{
|
|
koethe@1199
|
1933 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
1934 |
|
|
koethe@1199
|
1935 |
XYZ2RGBPrimeFunctor<T> xyz2rgb;
|
|
koethe@1199
|
1936 |
Lab2XYZFunctor<component_type> lab2xyz;
|
|
koethe@1199
|
1937 |
|
|
koethe@1199
|
1938 |
public:
|
|
koethe@1199
|
1939 |
|
|
koethe@1199
|
1940 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
1941 |
can be any vector type with the same interface.
|
|
koethe@1199
|
1942 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
1943 |
*/
|
|
koethe@1199
|
1944 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
1945 |
|
|
koethe@1199
|
1946 |
/** the functor's result type
|
|
koethe@1199
|
1947 |
*/
|
|
koethe@1199
|
1948 |
typedef typename XYZ2RGBFunctor<T>::result_type result_type;
|
|
koethe@1199
|
1949 |
|
|
koethe@1199
|
1950 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
1951 |
*/
|
|
koethe@1199
|
1952 |
typedef typename XYZ2RGBFunctor<T>::result_type value_type;
|
|
koethe@1199
|
1953 |
|
|
koethe@1199
|
1954 |
/** default constructor.
|
|
koethe@1199
|
1955 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
1956 |
*/
|
|
koethe@1199
|
1957 |
Lab2RGBPrimeFunctor()
|
|
koethe@1199
|
1958 |
: xyz2rgb(255.0)
|
|
koethe@1199
|
1959 |
{}
|
|
koethe@1199
|
1960 |
|
|
koethe@1199
|
1961 |
/** constructor
|
|
koethe@1199
|
1962 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
1963 |
*/
|
|
koethe@1199
|
1964 |
Lab2RGBPrimeFunctor(component_type max)
|
|
koethe@1199
|
1965 |
: xyz2rgb(max)
|
|
koethe@1199
|
1966 |
{}
|
|
koethe@1199
|
1967 |
|
|
koethe@1199
|
1968 |
/** apply the transformation
|
|
koethe@1199
|
1969 |
*/
|
|
koethe@1199
|
1970 |
template <class V>
|
|
koethe@1199
|
1971 |
result_type operator()(V const & lab) const
|
|
koethe@1199
|
1972 |
{
|
|
koethe@1199
|
1973 |
return xyz2rgb(lab2xyz(lab));
|
|
koethe@1199
|
1974 |
}
|
|
koethe@1199
|
1975 |
};
|
|
koethe@1199
|
1976 |
|
|
koethe@1199
|
1977 |
template <class T>
|
|
koethe@1199
|
1978 |
class FunctorTraits<Lab2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
1979 |
: public FunctorTraitsBase<Lab2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
1980 |
{
|
|
koethe@1199
|
1981 |
public:
|
|
koethe@1199
|
1982 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
1983 |
};
|
|
koethe@1199
|
1984 |
|
|
koethe@1199
|
1985 |
/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color difference components.
|
|
koethe@1199
|
1986 |
|
|
koethe@1623
|
1987 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
1988 |
Namespace: vigra
|
|
koethe@1199
|
1989 |
|
|
koethe@1199
|
1990 |
According to ITU-R Recommendation BT.601, the functor realizes the transformation
|
|
koethe@1199
|
1991 |
|
|
koethe@1199
|
1992 |
\f[
|
|
koethe@1199
|
1993 |
\begin{array}{rcl}
|
|
koethe@1199
|
1994 |
Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
|
|
koethe@1199
|
1995 |
Pb & = & -0.1687358916\enspace R / R_{max} + 0.3312641084\enspace G / G_{max} + 0.5\enspace B / B_{max} \\
|
|
koethe@1199
|
1996 |
Pr & = & 0.5\enspace R / R_{max} + 0.4186875892\enspace G / G_{max} + 0.0813124108\enspace B / B_{max}
|
|
koethe@1199
|
1997 |
\end{array}
|
|
koethe@1199
|
1998 |
\f]
|
|
koethe@1199
|
1999 |
|
|
koethe@1199
|
2000 |
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
|
|
koethe@1199
|
2001 |
in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color, and
|
|
koethe@1199
|
2002 |
Pb and Pr are the blue (B'-Y') and red (R'-Y') color difference components.
|
|
koethe@1199
|
2003 |
The transformation is scaled so that the following bounds apply:
|
|
koethe@1199
|
2004 |
|
|
koethe@1199
|
2005 |
\f[
|
|
koethe@1199
|
2006 |
\begin{array}{rcl}
|
|
koethe@1199
|
2007 |
0 \leq & Y' & \leq 1 \\
|
|
koethe@1199
|
2008 |
-0.5 \leq & Pb & \leq 0.5 \\
|
|
koethe@1199
|
2009 |
-0.5 \leq & Pr & \leq 0.5
|
|
koethe@1199
|
2010 |
\end{array}
|
|
koethe@1199
|
2011 |
\f]
|
|
koethe@1199
|
2012 |
|
|
koethe@1199
|
2013 |
<b> Traits defined:</b>
|
|
koethe@1199
|
2014 |
|
|
koethe@1623
|
2015 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
2016 |
*/
|
|
koethe@1199
|
2017 |
template <class T>
|
|
koethe@1199
|
2018 |
class RGBPrime2YPrimePbPrFunctor
|
|
koethe@1199
|
2019 |
{
|
|
koethe@1199
|
2020 |
/*
|
|
koethe@1199
|
2021 |
Y in [0, 1]
|
|
koethe@1199
|
2022 |
Pb in [-0.5, 0.5]
|
|
koethe@1199
|
2023 |
Pr in [-0.5, 0.5]
|
|
koethe@1199
|
2024 |
maximum saturation: 0.533887
|
|
koethe@1199
|
2025 |
red = [0.299, -0.168736, 0.5]
|
|
koethe@1199
|
2026 |
*/
|
|
koethe@1199
|
2027 |
public:
|
|
koethe@1199
|
2028 |
|
|
koethe@1199
|
2029 |
/** the result's component type
|
|
koethe@1199
|
2030 |
*/
|
|
koethe@1199
|
2031 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
2032 |
|
|
koethe@1199
|
2033 |
/** the functor's argument type
|
|
koethe@1199
|
2034 |
*/
|
|
koethe@1199
|
2035 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
2036 |
|
|
koethe@1199
|
2037 |
/** the functor's result type
|
|
koethe@1199
|
2038 |
*/
|
|
koethe@1199
|
2039 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
2040 |
|
|
koethe@1199
|
2041 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
2042 |
*/
|
|
koethe@1199
|
2043 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
2044 |
|
|
koethe@1199
|
2045 |
/** default constructor.
|
|
koethe@1199
|
2046 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
2047 |
*/
|
|
koethe@1199
|
2048 |
RGBPrime2YPrimePbPrFunctor()
|
|
koethe@1199
|
2049 |
: max_(255.0)
|
|
koethe@1199
|
2050 |
{}
|
|
koethe@1199
|
2051 |
|
|
koethe@1199
|
2052 |
/** constructor
|
|
koethe@1199
|
2053 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
2054 |
*/
|
|
koethe@1199
|
2055 |
RGBPrime2YPrimePbPrFunctor(component_type max)
|
|
koethe@1199
|
2056 |
: max_(max)
|
|
koethe@1199
|
2057 |
{}
|
|
koethe@1199
|
2058 |
|
|
koethe@1199
|
2059 |
/** apply the transformation
|
|
koethe@1199
|
2060 |
*/
|
|
koethe@1199
|
2061 |
template <class V>
|
|
koethe@1199
|
2062 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
2063 |
{
|
|
ullrich@2455
|
2064 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
koethe@1199
|
2065 |
component_type red = rgb[0] / max_;
|
|
koethe@1199
|
2066 |
component_type green = rgb[1] / max_;
|
|
koethe@1199
|
2067 |
component_type blue = rgb[2] / max_;
|
|
koethe@1199
|
2068 |
|
|
koethe@1199
|
2069 |
result_type result;
|
|
ullrich@2455
|
2070 |
result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
|
|
ullrich@2455
|
2071 |
result[1] = Convert::cast(-0.1687358916*red - 0.3312641084*green + 0.5*blue);
|
|
ullrich@2455
|
2072 |
result[2] = Convert::cast(0.5*red - 0.4186875892*green - 0.0813124108*blue);
|
|
koethe@1199
|
2073 |
return result;
|
|
koethe@1199
|
2074 |
}
|
|
koethe@1199
|
2075 |
|
|
koethe@1199
|
2076 |
private:
|
|
koethe@1199
|
2077 |
component_type max_;
|
|
koethe@1199
|
2078 |
};
|
|
koethe@1199
|
2079 |
|
|
koethe@1199
|
2080 |
template <class T>
|
|
koethe@1199
|
2081 |
class FunctorTraits<RGBPrime2YPrimePbPrFunctor<T> >
|
|
koethe@1199
|
2082 |
: public FunctorTraitsBase<RGBPrime2YPrimePbPrFunctor<T> >
|
|
koethe@1199
|
2083 |
{
|
|
koethe@1199
|
2084 |
public:
|
|
koethe@1199
|
2085 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
2086 |
};
|
|
koethe@1199
|
2087 |
|
|
koethe@1199
|
2088 |
/** \brief Convert Y'PbPr color difference components into non-linear (gamma corrected) R'G'B'.
|
|
koethe@1199
|
2089 |
|
|
koethe@1623
|
2090 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2091 |
Namespace: vigra
|
|
koethe@1199
|
2092 |
|
|
koethe@1199
|
2093 |
The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimePbPrFunctor
|
|
koethe@1199
|
2094 |
|
|
koethe@1199
|
2095 |
<b> Traits defined:</b>
|
|
koethe@1199
|
2096 |
|
|
koethe@1623
|
2097 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
2098 |
*/
|
|
koethe@1199
|
2099 |
template <class T>
|
|
koethe@1199
|
2100 |
class YPrimePbPr2RGBPrimeFunctor
|
|
koethe@1199
|
2101 |
{
|
|
koethe@1199
|
2102 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
2103 |
|
|
koethe@1199
|
2104 |
component_type max_;
|
|
koethe@1199
|
2105 |
|
|
koethe@1199
|
2106 |
public:
|
|
koethe@1199
|
2107 |
|
|
koethe@1199
|
2108 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
2109 |
can be any vector type with the same interface.
|
|
koethe@1199
|
2110 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
2111 |
*/
|
|
koethe@1199
|
2112 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
2113 |
|
|
koethe@1199
|
2114 |
/** the functor's result type
|
|
koethe@1199
|
2115 |
*/
|
|
ullrich@2455
|
2116 |
typedef TinyVector<T, 3> result_type;
|
|
koethe@1199
|
2117 |
|
|
koethe@1199
|
2118 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
2119 |
*/
|
|
ullrich@2455
|
2120 |
typedef TinyVector<T, 3> value_type;
|
|
koethe@1199
|
2121 |
|
|
koethe@1199
|
2122 |
/** default constructor.
|
|
koethe@1199
|
2123 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
2124 |
*/
|
|
koethe@1199
|
2125 |
YPrimePbPr2RGBPrimeFunctor()
|
|
koethe@1199
|
2126 |
: max_(255.0)
|
|
koethe@1199
|
2127 |
{}
|
|
koethe@1199
|
2128 |
|
|
koethe@1199
|
2129 |
/** constructor
|
|
koethe@1199
|
2130 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
2131 |
*/
|
|
koethe@1199
|
2132 |
YPrimePbPr2RGBPrimeFunctor(component_type max)
|
|
koethe@1199
|
2133 |
: max_(max)
|
|
koethe@1199
|
2134 |
{}
|
|
koethe@1199
|
2135 |
|
|
koethe@1199
|
2136 |
/** apply the transformation
|
|
koethe@1199
|
2137 |
*/
|
|
koethe@1199
|
2138 |
template <class V>
|
|
koethe@1199
|
2139 |
result_type operator()(V const & ypbpr) const
|
|
koethe@1199
|
2140 |
{
|
|
ullrich@2455
|
2141 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
2142 |
component_type nred = Convert::cast(ypbpr[0] + 1.402*ypbpr[2]);
|
|
ullrich@2455
|
2143 |
component_type ngreen = Convert::cast(ypbpr[0] - 0.3441362862*ypbpr[1] - 0.7141362862*ypbpr[2]);
|
|
ullrich@2455
|
2144 |
component_type nblue = Convert::cast(ypbpr[0] + 1.772*ypbpr[1]);
|
|
koethe@1199
|
2145 |
return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
|
|
koethe@1199
|
2146 |
NumericTraits<T>::fromRealPromote(ngreen * max_),
|
|
koethe@1199
|
2147 |
NumericTraits<T>::fromRealPromote(nblue * max_));
|
|
koethe@1199
|
2148 |
}
|
|
koethe@1199
|
2149 |
};
|
|
koethe@1199
|
2150 |
|
|
koethe@1199
|
2151 |
template <class T>
|
|
koethe@1199
|
2152 |
class FunctorTraits<YPrimePbPr2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
2153 |
: public FunctorTraitsBase<YPrimePbPr2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
2154 |
{
|
|
koethe@1199
|
2155 |
public:
|
|
koethe@1199
|
2156 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
2157 |
};
|
|
koethe@1199
|
2158 |
|
|
koethe@1199
|
2159 |
/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components.
|
|
koethe@1199
|
2160 |
|
|
koethe@1623
|
2161 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2162 |
Namespace: vigra
|
|
koethe@1199
|
2163 |
|
|
koethe@1199
|
2164 |
According to the PAL analog videa standard, the functor realizes the transformation
|
|
koethe@1199
|
2165 |
|
|
koethe@1199
|
2166 |
\f[
|
|
koethe@1199
|
2167 |
\begin{array}{rcl}
|
|
koethe@1199
|
2168 |
Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
|
|
koethe@1199
|
2169 |
I & = & 0.596\enspace R / R_{max} - 0.274\enspace G / G_{max} - 0.322\enspace B / B_{max} \\
|
|
koethe@1199
|
2170 |
Q & = & 0.212\enspace R / R_{max} - 0.523\enspace G / G_{max} + 0.311\enspace B / B_{max}
|
|
koethe@1199
|
2171 |
\end{array}
|
|
koethe@1199
|
2172 |
\f]
|
|
koethe@1199
|
2173 |
|
|
koethe@1199
|
2174 |
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
|
|
koethe@1199
|
2175 |
in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color.
|
|
koethe@1199
|
2176 |
The transformation is scaled so that the following bounds apply:
|
|
koethe@1199
|
2177 |
|
|
koethe@1199
|
2178 |
\f[
|
|
koethe@1199
|
2179 |
\begin{array}{rcl}
|
|
koethe@1199
|
2180 |
0 \leq & Y' & \leq 1 \\
|
|
koethe@1199
|
2181 |
-0.596 \leq & I & \leq 0.596 \\
|
|
koethe@1199
|
2182 |
-0.523 \leq & Q & \leq 0.523
|
|
koethe@1199
|
2183 |
\end{array}
|
|
koethe@1199
|
2184 |
\f]
|
|
koethe@1199
|
2185 |
|
|
koethe@1199
|
2186 |
<b> Traits defined:</b>
|
|
koethe@1199
|
2187 |
|
|
koethe@1623
|
2188 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
2189 |
*/
|
|
koethe@1199
|
2190 |
template <class T>
|
|
koethe@1199
|
2191 |
class RGBPrime2YPrimeIQFunctor
|
|
koethe@1199
|
2192 |
{
|
|
koethe@1199
|
2193 |
/*
|
|
koethe@1199
|
2194 |
Y in [0, 1]
|
|
koethe@1199
|
2195 |
I in [-0.596, 0.596]
|
|
koethe@1199
|
2196 |
Q in [-0.523, 0.523]
|
|
koethe@1199
|
2197 |
maximum saturation: 0.632582
|
|
koethe@1199
|
2198 |
red = [0.299, 0.596, 0.212]
|
|
koethe@1199
|
2199 |
*/
|
|
koethe@1199
|
2200 |
public:
|
|
koethe@1199
|
2201 |
|
|
koethe@1199
|
2202 |
/** the result's component type
|
|
koethe@1199
|
2203 |
*/
|
|
koethe@1199
|
2204 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
2205 |
|
|
koethe@1199
|
2206 |
/** the functor's argument type
|
|
koethe@1199
|
2207 |
*/
|
|
koethe@1199
|
2208 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
2209 |
|
|
koethe@1199
|
2210 |
/** the functor's result type
|
|
koethe@1199
|
2211 |
*/
|
|
koethe@1199
|
2212 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
2213 |
|
|
koethe@1199
|
2214 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
2215 |
*/
|
|
koethe@1199
|
2216 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
2217 |
|
|
koethe@1199
|
2218 |
/** default constructor.
|
|
koethe@1199
|
2219 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
2220 |
*/
|
|
koethe@1199
|
2221 |
RGBPrime2YPrimeIQFunctor()
|
|
koethe@1199
|
2222 |
: max_(255.0)
|
|
koethe@1199
|
2223 |
{}
|
|
koethe@1199
|
2224 |
|
|
koethe@1199
|
2225 |
/** constructor
|
|
koethe@1199
|
2226 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
2227 |
*/
|
|
koethe@1199
|
2228 |
RGBPrime2YPrimeIQFunctor(component_type max)
|
|
koethe@1199
|
2229 |
: max_(max)
|
|
koethe@1199
|
2230 |
{}
|
|
koethe@1199
|
2231 |
|
|
koethe@1199
|
2232 |
/** apply the transformation
|
|
koethe@1199
|
2233 |
*/
|
|
koethe@1199
|
2234 |
template <class V>
|
|
koethe@1199
|
2235 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
2236 |
{
|
|
ullrich@2455
|
2237 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
koethe@1199
|
2238 |
component_type red = rgb[0] / max_;
|
|
koethe@1199
|
2239 |
component_type green = rgb[1] / max_;
|
|
koethe@1199
|
2240 |
component_type blue = rgb[2] / max_;
|
|
koethe@1199
|
2241 |
|
|
koethe@1199
|
2242 |
result_type result;
|
|
ullrich@2455
|
2243 |
result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
|
|
ullrich@2455
|
2244 |
result[1] = Convert::cast(0.596*red - 0.274*green - 0.322*blue);
|
|
ullrich@2455
|
2245 |
result[2] = Convert::cast(0.212*red - 0.523*green + 0.311*blue);
|
|
koethe@1199
|
2246 |
return result;
|
|
koethe@1199
|
2247 |
}
|
|
koethe@1199
|
2248 |
|
|
koethe@1199
|
2249 |
private:
|
|
koethe@1199
|
2250 |
component_type max_;
|
|
koethe@1199
|
2251 |
};
|
|
koethe@1199
|
2252 |
|
|
koethe@1199
|
2253 |
template <class T>
|
|
koethe@1199
|
2254 |
class FunctorTraits<RGBPrime2YPrimeIQFunctor<T> >
|
|
koethe@1199
|
2255 |
: public FunctorTraitsBase<RGBPrime2YPrimeIQFunctor<T> >
|
|
koethe@1199
|
2256 |
{
|
|
koethe@1199
|
2257 |
public:
|
|
koethe@1199
|
2258 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
2259 |
};
|
|
koethe@1199
|
2260 |
|
|
koethe@1199
|
2261 |
/** \brief Convert Y'IQ color components into non-linear (gamma corrected) R'G'B'.
|
|
koethe@1199
|
2262 |
|
|
koethe@1623
|
2263 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2264 |
Namespace: vigra
|
|
koethe@1199
|
2265 |
|
|
koethe@1199
|
2266 |
The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeIQFunctor
|
|
koethe@1199
|
2267 |
|
|
koethe@1199
|
2268 |
<b> Traits defined:</b>
|
|
koethe@1199
|
2269 |
|
|
koethe@1623
|
2270 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
2271 |
*/
|
|
koethe@1199
|
2272 |
template <class T>
|
|
koethe@1199
|
2273 |
class YPrimeIQ2RGBPrimeFunctor
|
|
koethe@1199
|
2274 |
{
|
|
koethe@1199
|
2275 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
2276 |
|
|
koethe@1199
|
2277 |
component_type max_;
|
|
koethe@1199
|
2278 |
|
|
koethe@1199
|
2279 |
public:
|
|
koethe@1199
|
2280 |
|
|
koethe@1199
|
2281 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
2282 |
can be any vector type with the same interface.
|
|
koethe@1199
|
2283 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
2284 |
*/
|
|
koethe@1199
|
2285 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
2286 |
|
|
koethe@1199
|
2287 |
/** the functor's result type
|
|
koethe@1199
|
2288 |
*/
|
|
ullrich@2455
|
2289 |
typedef TinyVector<T, 3> result_type;
|
|
koethe@1199
|
2290 |
|
|
koethe@1199
|
2291 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
2292 |
*/
|
|
ullrich@2455
|
2293 |
typedef TinyVector<T, 3> value_type;
|
|
koethe@1199
|
2294 |
|
|
koethe@1199
|
2295 |
/** default constructor.
|
|
koethe@1199
|
2296 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
2297 |
*/
|
|
koethe@1199
|
2298 |
YPrimeIQ2RGBPrimeFunctor()
|
|
koethe@1199
|
2299 |
: max_(255.0)
|
|
koethe@1199
|
2300 |
{}
|
|
koethe@1199
|
2301 |
|
|
koethe@1199
|
2302 |
/** constructor
|
|
koethe@1199
|
2303 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
2304 |
*/
|
|
koethe@1199
|
2305 |
YPrimeIQ2RGBPrimeFunctor(component_type max)
|
|
koethe@1199
|
2306 |
: max_(max)
|
|
koethe@1199
|
2307 |
{}
|
|
koethe@1199
|
2308 |
|
|
koethe@1199
|
2309 |
/** apply the transformation
|
|
koethe@1199
|
2310 |
*/
|
|
koethe@1199
|
2311 |
template <class V>
|
|
koethe@1199
|
2312 |
result_type operator()(V const & yiq) const
|
|
koethe@1199
|
2313 |
{
|
|
ullrich@2455
|
2314 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
2315 |
component_type nred = Convert::cast(yiq[0] + 0.9548892043*yiq[1] + 0.6221039350*yiq[2]);
|
|
ullrich@2455
|
2316 |
component_type ngreen = Convert::cast(yiq[0] - 0.2713547827*yiq[1] - 0.6475120259*yiq[2]);
|
|
ullrich@2455
|
2317 |
component_type nblue = Convert::cast(yiq[0] - 1.1072510054*yiq[1] + 1.7024603738*yiq[2]);
|
|
koethe@1199
|
2318 |
return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
|
|
koethe@1199
|
2319 |
NumericTraits<T>::fromRealPromote(ngreen * max_),
|
|
koethe@1199
|
2320 |
NumericTraits<T>::fromRealPromote(nblue * max_));
|
|
koethe@1199
|
2321 |
}
|
|
koethe@1199
|
2322 |
};
|
|
koethe@1199
|
2323 |
|
|
koethe@1199
|
2324 |
template <class T>
|
|
koethe@1199
|
2325 |
class FunctorTraits<YPrimeIQ2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
2326 |
: public FunctorTraitsBase<YPrimeIQ2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
2327 |
{
|
|
koethe@1199
|
2328 |
public:
|
|
koethe@1199
|
2329 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
2330 |
};
|
|
koethe@1199
|
2331 |
|
|
koethe@1199
|
2332 |
/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components.
|
|
koethe@1199
|
2333 |
|
|
koethe@1623
|
2334 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2335 |
Namespace: vigra
|
|
koethe@1199
|
2336 |
|
|
koethe@1199
|
2337 |
According to the NTSC analog videa standard, the functor realizes the transformation
|
|
koethe@1199
|
2338 |
|
|
koethe@1199
|
2339 |
\f[
|
|
koethe@1199
|
2340 |
\begin{array}{rcl}
|
|
koethe@1199
|
2341 |
Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
|
|
koethe@1199
|
2342 |
U & = & -0.147\enspace R / R_{max} - 0.289\enspace G / G_{max} + 0.436\enspace B / B_{max} \\
|
|
koethe@1199
|
2343 |
V & = & 0.615\enspace R / R_{max} - 0.515\enspace G / G_{max} - 0.100\enspace B / B_{max}
|
|
koethe@1199
|
2344 |
\end{array}
|
|
koethe@1199
|
2345 |
\f]
|
|
koethe@1199
|
2346 |
|
|
koethe@1199
|
2347 |
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
|
|
koethe@1199
|
2348 |
in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color.
|
|
koethe@1199
|
2349 |
The transformation is scaled so that the following bounds apply:
|
|
koethe@1199
|
2350 |
|
|
koethe@1199
|
2351 |
\f[
|
|
koethe@1199
|
2352 |
\begin{array}{rcl}
|
|
koethe@1199
|
2353 |
0 \leq & Y' & \leq 1 \\
|
|
koethe@1199
|
2354 |
-0.436 \leq & U & \leq 0.436 \\
|
|
koethe@1199
|
2355 |
-0.615 \leq & V & \leq 0.615
|
|
koethe@1199
|
2356 |
\end{array}
|
|
koethe@1199
|
2357 |
\f]
|
|
koethe@1199
|
2358 |
|
|
koethe@1199
|
2359 |
<b> Traits defined:</b>
|
|
koethe@1199
|
2360 |
|
|
koethe@1623
|
2361 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
2362 |
*/
|
|
koethe@1199
|
2363 |
template <class T>
|
|
koethe@1199
|
2364 |
class RGBPrime2YPrimeUVFunctor
|
|
koethe@1199
|
2365 |
{
|
|
koethe@1199
|
2366 |
/*
|
|
koethe@1199
|
2367 |
Y in [0, 1]
|
|
koethe@1199
|
2368 |
U in [-0.436, 0.436]
|
|
koethe@1199
|
2369 |
V in [-0.615, 0.615]
|
|
koethe@1199
|
2370 |
maximum saturation: 0.632324
|
|
koethe@1199
|
2371 |
red = [0.299, -0.147, 0.615]
|
|
koethe@1199
|
2372 |
*/
|
|
koethe@1199
|
2373 |
public:
|
|
koethe@1199
|
2374 |
|
|
koethe@1199
|
2375 |
/** the result's component type
|
|
koethe@1199
|
2376 |
*/
|
|
koethe@1199
|
2377 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
2378 |
|
|
koethe@1199
|
2379 |
/** the functor's argument type
|
|
koethe@1199
|
2380 |
*/
|
|
koethe@1199
|
2381 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
2382 |
|
|
koethe@1199
|
2383 |
/** the functor's result type
|
|
koethe@1199
|
2384 |
*/
|
|
koethe@1199
|
2385 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
2386 |
|
|
koethe@1199
|
2387 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
2388 |
*/
|
|
koethe@1199
|
2389 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
2390 |
|
|
koethe@1199
|
2391 |
/** default constructor.
|
|
koethe@1199
|
2392 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
2393 |
*/
|
|
koethe@1199
|
2394 |
RGBPrime2YPrimeUVFunctor()
|
|
koethe@1199
|
2395 |
: max_(255.0)
|
|
koethe@1199
|
2396 |
{}
|
|
koethe@1199
|
2397 |
|
|
koethe@1199
|
2398 |
/** constructor
|
|
koethe@1199
|
2399 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
2400 |
*/
|
|
koethe@1199
|
2401 |
RGBPrime2YPrimeUVFunctor(component_type max)
|
|
koethe@1199
|
2402 |
: max_(max)
|
|
koethe@1199
|
2403 |
{}
|
|
koethe@1199
|
2404 |
|
|
koethe@1199
|
2405 |
/** apply the transformation
|
|
koethe@1199
|
2406 |
*/
|
|
koethe@1199
|
2407 |
template <class V>
|
|
koethe@1199
|
2408 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
2409 |
{
|
|
ullrich@2455
|
2410 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
koethe@1199
|
2411 |
component_type red = rgb[0] / max_;
|
|
koethe@1199
|
2412 |
component_type green = rgb[1] / max_;
|
|
koethe@1199
|
2413 |
component_type blue = rgb[2] / max_;
|
|
koethe@1199
|
2414 |
|
|
koethe@1199
|
2415 |
result_type result;
|
|
ullrich@2455
|
2416 |
result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
|
|
ullrich@2455
|
2417 |
result[1] = Convert::cast(-0.1471376975*red - 0.2888623025*green + 0.436*blue);
|
|
ullrich@2455
|
2418 |
result[2] = Convert::cast(0.6149122807*red - 0.5149122807*green - 0.100*blue);
|
|
koethe@1199
|
2419 |
return result;
|
|
koethe@1199
|
2420 |
}
|
|
koethe@1199
|
2421 |
|
|
koethe@1199
|
2422 |
private:
|
|
koethe@1199
|
2423 |
component_type max_;
|
|
koethe@1199
|
2424 |
};
|
|
koethe@1199
|
2425 |
|
|
koethe@1199
|
2426 |
template <class T>
|
|
koethe@1199
|
2427 |
class FunctorTraits<RGBPrime2YPrimeUVFunctor<T> >
|
|
koethe@1199
|
2428 |
: public FunctorTraitsBase<RGBPrime2YPrimeUVFunctor<T> >
|
|
koethe@1199
|
2429 |
{
|
|
koethe@1199
|
2430 |
public:
|
|
koethe@1199
|
2431 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
2432 |
};
|
|
koethe@1199
|
2433 |
|
|
koethe@1199
|
2434 |
/** \brief Convert Y'UV color components into non-linear (gamma corrected) R'G'B'.
|
|
koethe@1199
|
2435 |
|
|
koethe@1623
|
2436 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2437 |
Namespace: vigra
|
|
koethe@1199
|
2438 |
|
|
koethe@1199
|
2439 |
The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeUVFunctor
|
|
koethe@1199
|
2440 |
|
|
koethe@1199
|
2441 |
<b> Traits defined:</b>
|
|
koethe@1199
|
2442 |
|
|
koethe@1623
|
2443 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
2444 |
*/
|
|
koethe@1199
|
2445 |
template <class T>
|
|
koethe@1199
|
2446 |
class YPrimeUV2RGBPrimeFunctor
|
|
koethe@1199
|
2447 |
{
|
|
koethe@1199
|
2448 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
2449 |
|
|
koethe@1199
|
2450 |
component_type max_;
|
|
koethe@1199
|
2451 |
|
|
koethe@1199
|
2452 |
public:
|
|
koethe@1199
|
2453 |
|
|
koethe@1199
|
2454 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
2455 |
can be any vector type with the same interface.
|
|
koethe@1199
|
2456 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
2457 |
*/
|
|
koethe@1199
|
2458 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
2459 |
|
|
koethe@1199
|
2460 |
/** the functor's result type
|
|
koethe@1199
|
2461 |
*/
|
|
ullrich@2455
|
2462 |
typedef TinyVector<T, 3> result_type;
|
|
koethe@1199
|
2463 |
|
|
koethe@1199
|
2464 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
2465 |
*/
|
|
ullrich@2455
|
2466 |
typedef TinyVector<T, 3> value_type;
|
|
koethe@1199
|
2467 |
|
|
koethe@1199
|
2468 |
/** default constructor.
|
|
koethe@1199
|
2469 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
2470 |
*/
|
|
koethe@1199
|
2471 |
YPrimeUV2RGBPrimeFunctor()
|
|
koethe@1199
|
2472 |
: max_(255.0)
|
|
koethe@1199
|
2473 |
{}
|
|
koethe@1199
|
2474 |
|
|
koethe@1199
|
2475 |
/** constructor
|
|
koethe@1199
|
2476 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
2477 |
*/
|
|
koethe@1199
|
2478 |
YPrimeUV2RGBPrimeFunctor(component_type max)
|
|
koethe@1199
|
2479 |
: max_(max)
|
|
koethe@1199
|
2480 |
{}
|
|
koethe@1199
|
2481 |
|
|
koethe@1199
|
2482 |
/** apply the transformation
|
|
koethe@1199
|
2483 |
*/
|
|
koethe@1199
|
2484 |
template <class V>
|
|
koethe@1199
|
2485 |
result_type operator()(V const & yuv) const
|
|
koethe@1199
|
2486 |
{
|
|
ullrich@2455
|
2487 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
2488 |
component_type nred = Convert::cast(yuv[0] + 1.140*yuv[2]);
|
|
ullrich@2455
|
2489 |
component_type ngreen = Convert::cast(yuv[0] - 0.3946517044*yuv[1] - 0.580681431*yuv[2]);
|
|
ullrich@2455
|
2490 |
component_type nblue = Convert::cast(yuv[0] + 2.0321100920*yuv[1]);
|
|
koethe@1199
|
2491 |
return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
|
|
koethe@1199
|
2492 |
NumericTraits<T>::fromRealPromote(ngreen * max_),
|
|
koethe@1199
|
2493 |
NumericTraits<T>::fromRealPromote(nblue * max_));
|
|
koethe@1199
|
2494 |
}
|
|
koethe@1199
|
2495 |
};
|
|
koethe@1199
|
2496 |
|
|
koethe@1199
|
2497 |
template <class T>
|
|
koethe@1199
|
2498 |
class FunctorTraits<YPrimeUV2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
2499 |
: public FunctorTraitsBase<YPrimeUV2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
2500 |
{
|
|
koethe@1199
|
2501 |
public:
|
|
koethe@1199
|
2502 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
2503 |
};
|
|
koethe@1199
|
2504 |
|
|
koethe@1199
|
2505 |
/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color difference components.
|
|
koethe@1199
|
2506 |
|
|
koethe@1623
|
2507 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2508 |
Namespace: vigra
|
|
koethe@1199
|
2509 |
|
|
koethe@1199
|
2510 |
This functor basically applies the same transformation as vigra::RGBPrime2YPrimePbPrFunctor
|
|
koethe@1199
|
2511 |
but the color components are scaled so that they can be coded as 8 bit intergers with
|
|
koethe@1199
|
2512 |
minimal loss of information:
|
|
koethe@1199
|
2513 |
|
|
koethe@1199
|
2514 |
\f[
|
|
koethe@1199
|
2515 |
\begin{array}{rcl}
|
|
koethe@1199
|
2516 |
16\leq & Y' & \leq 235 \\
|
|
koethe@1199
|
2517 |
16 \leq & Cb & \leq 240 \\
|
|
koethe@1199
|
2518 |
16 \leq & Cr & \leq 240
|
|
koethe@1199
|
2519 |
\end{array}
|
|
koethe@1199
|
2520 |
\f]
|
|
koethe@1199
|
2521 |
|
|
koethe@1199
|
2522 |
<b> Traits defined:</b>
|
|
koethe@1199
|
2523 |
|
|
koethe@1623
|
2524 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
2525 |
*/
|
|
koethe@1199
|
2526 |
template <class T>
|
|
koethe@1199
|
2527 |
class RGBPrime2YPrimeCbCrFunctor
|
|
koethe@1199
|
2528 |
{
|
|
koethe@1199
|
2529 |
/*
|
|
koethe@1199
|
2530 |
Y in [16, 235]
|
|
koethe@1199
|
2531 |
Cb in [16, 240]
|
|
koethe@1199
|
2532 |
Cr in [16, 240]
|
|
koethe@1199
|
2533 |
maximum saturation: 119.591
|
|
koethe@1199
|
2534 |
red = [81.481, 90.203, 240]
|
|
koethe@1199
|
2535 |
*/
|
|
koethe@1199
|
2536 |
public:
|
|
koethe@1199
|
2537 |
|
|
koethe@1199
|
2538 |
/** the result's component type
|
|
koethe@1199
|
2539 |
*/
|
|
koethe@1199
|
2540 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
2541 |
|
|
koethe@1199
|
2542 |
/** the functor's argument type
|
|
koethe@1199
|
2543 |
*/
|
|
koethe@1199
|
2544 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
2545 |
|
|
koethe@1199
|
2546 |
/** the functor's result type
|
|
koethe@1199
|
2547 |
*/
|
|
koethe@1199
|
2548 |
typedef TinyVector<component_type, 3> result_type;
|
|
koethe@1199
|
2549 |
|
|
koethe@1199
|
2550 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
2551 |
*/
|
|
koethe@1199
|
2552 |
typedef TinyVector<component_type, 3> value_type;
|
|
koethe@1199
|
2553 |
|
|
koethe@1199
|
2554 |
/** default constructor.
|
|
koethe@1199
|
2555 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
2556 |
*/
|
|
koethe@1199
|
2557 |
RGBPrime2YPrimeCbCrFunctor()
|
|
koethe@1199
|
2558 |
: max_(255.0)
|
|
koethe@1199
|
2559 |
{}
|
|
koethe@1199
|
2560 |
|
|
koethe@1199
|
2561 |
/** constructor
|
|
koethe@1199
|
2562 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
2563 |
*/
|
|
koethe@1199
|
2564 |
RGBPrime2YPrimeCbCrFunctor(component_type max)
|
|
koethe@1199
|
2565 |
: max_(max)
|
|
koethe@1199
|
2566 |
{}
|
|
koethe@1199
|
2567 |
|
|
koethe@1199
|
2568 |
/** apply the transformation
|
|
koethe@1199
|
2569 |
*/
|
|
koethe@1199
|
2570 |
template <class V>
|
|
koethe@1199
|
2571 |
result_type operator()(V const & rgb) const
|
|
koethe@1199
|
2572 |
{
|
|
ullrich@2455
|
2573 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
koethe@1199
|
2574 |
component_type red = rgb[0] / max_;
|
|
koethe@1199
|
2575 |
component_type green = rgb[1] / max_;
|
|
koethe@1199
|
2576 |
component_type blue = rgb[2] / max_;
|
|
koethe@1199
|
2577 |
|
|
koethe@1199
|
2578 |
result_type result;
|
|
ullrich@2455
|
2579 |
result[0] = Convert::cast(16.0 + 65.481*red + 128.553*green + 24.966*blue);
|
|
ullrich@2455
|
2580 |
result[1] = Convert::cast(128.0 - 37.79683972*red - 74.20316028*green + 112.0*blue);
|
|
ullrich@2455
|
2581 |
result[2] = Convert::cast(128.0 + 112.0*red - 93.78601998*green - 18.21398002*blue);
|
|
koethe@1199
|
2582 |
return result;
|
|
koethe@1199
|
2583 |
}
|
|
koethe@1199
|
2584 |
|
|
koethe@1199
|
2585 |
private:
|
|
koethe@1199
|
2586 |
component_type max_;
|
|
koethe@1199
|
2587 |
};
|
|
koethe@1199
|
2588 |
|
|
koethe@1199
|
2589 |
template <class T>
|
|
koethe@1199
|
2590 |
class FunctorTraits<RGBPrime2YPrimeCbCrFunctor<T> >
|
|
koethe@1199
|
2591 |
: public FunctorTraitsBase<RGBPrime2YPrimeCbCrFunctor<T> >
|
|
koethe@1199
|
2592 |
{
|
|
koethe@1199
|
2593 |
public:
|
|
koethe@1199
|
2594 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
2595 |
};
|
|
koethe@1199
|
2596 |
|
|
koethe@1199
|
2597 |
/** \brief Convert Y'CbCr color difference components into non-linear (gamma corrected) R'G'B'.
|
|
koethe@1199
|
2598 |
|
|
koethe@1623
|
2599 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2600 |
Namespace: vigra
|
|
koethe@1199
|
2601 |
|
|
koethe@1199
|
2602 |
The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeCbCrFunctor
|
|
koethe@1199
|
2603 |
|
|
koethe@1199
|
2604 |
<b> Traits defined:</b>
|
|
koethe@1199
|
2605 |
|
|
koethe@1623
|
2606 |
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
|
|
koethe@1199
|
2607 |
*/
|
|
koethe@1199
|
2608 |
template <class T>
|
|
koethe@1199
|
2609 |
class YPrimeCbCr2RGBPrimeFunctor
|
|
koethe@1199
|
2610 |
{
|
|
koethe@1199
|
2611 |
typedef typename NumericTraits<T>::RealPromote component_type;
|
|
koethe@1199
|
2612 |
|
|
koethe@1199
|
2613 |
component_type max_;
|
|
koethe@1199
|
2614 |
|
|
koethe@1199
|
2615 |
public:
|
|
koethe@1199
|
2616 |
|
|
koethe@1199
|
2617 |
/** the functor's argument type. (Actually, the argument type
|
|
koethe@1199
|
2618 |
can be any vector type with the same interface.
|
|
koethe@1199
|
2619 |
But this cannot be expressed in a typedef.)
|
|
koethe@1199
|
2620 |
*/
|
|
koethe@1199
|
2621 |
typedef TinyVector<T, 3> argument_type;
|
|
koethe@1199
|
2622 |
|
|
koethe@1199
|
2623 |
/** the functor's result type
|
|
koethe@1199
|
2624 |
*/
|
|
ullrich@2455
|
2625 |
typedef TinyVector<T, 3> result_type;
|
|
koethe@1199
|
2626 |
|
|
koethe@1199
|
2627 |
/** \deprecated use argument_type and result_type
|
|
koethe@1199
|
2628 |
*/
|
|
ullrich@2455
|
2629 |
typedef TinyVector<T, 3> value_type;
|
|
koethe@1199
|
2630 |
|
|
koethe@1199
|
2631 |
/** default constructor.
|
|
koethe@1199
|
2632 |
The maximum value for each RGB component defaults to 255.
|
|
koethe@1199
|
2633 |
*/
|
|
koethe@1199
|
2634 |
YPrimeCbCr2RGBPrimeFunctor()
|
|
koethe@1199
|
2635 |
: max_(255.0)
|
|
koethe@1199
|
2636 |
{}
|
|
koethe@1199
|
2637 |
|
|
koethe@1199
|
2638 |
/** constructor
|
|
koethe@1199
|
2639 |
\arg max - the maximum value for each RGB component
|
|
koethe@1199
|
2640 |
*/
|
|
koethe@1199
|
2641 |
YPrimeCbCr2RGBPrimeFunctor(component_type max)
|
|
koethe@1199
|
2642 |
: max_(max)
|
|
koethe@1199
|
2643 |
{}
|
|
koethe@1199
|
2644 |
|
|
koethe@1199
|
2645 |
/** apply the transformation
|
|
koethe@1199
|
2646 |
*/
|
|
koethe@1199
|
2647 |
template <class V>
|
|
koethe@1199
|
2648 |
result_type operator()(V const & ycbcr) const
|
|
koethe@1199
|
2649 |
{
|
|
ullrich@2455
|
2650 |
typedef detail::RequiresExplicitCast<component_type> Convert;
|
|
ullrich@2455
|
2651 |
component_type y = Convert::cast(ycbcr[0] - 16.0);
|
|
ullrich@2455
|
2652 |
component_type cb = Convert::cast(ycbcr[1] - 128.0);
|
|
ullrich@2455
|
2653 |
component_type cr = Convert::cast(ycbcr[2] - 128.0);
|
|
koethe@1199
|
2654 |
|
|
ullrich@2455
|
2655 |
component_type nred = Convert::cast(0.00456621*y + 0.006258928571*cr);
|
|
ullrich@2455
|
2656 |
component_type ngreen = Convert::cast(0.00456621*y - 0.001536322706*cb - 0.003188108420*cr);
|
|
ullrich@2455
|
2657 |
component_type nblue = Convert::cast(0.00456621*y + 0.007910714286*cb);
|
|
koethe@1199
|
2658 |
return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
|
|
koethe@1199
|
2659 |
NumericTraits<T>::fromRealPromote(ngreen * max_),
|
|
koethe@1199
|
2660 |
NumericTraits<T>::fromRealPromote(nblue * max_));
|
|
koethe@1199
|
2661 |
}
|
|
koethe@1199
|
2662 |
};
|
|
koethe@1199
|
2663 |
|
|
koethe@1199
|
2664 |
template <class T>
|
|
koethe@1199
|
2665 |
class FunctorTraits<YPrimeCbCr2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
2666 |
: public FunctorTraitsBase<YPrimeCbCr2RGBPrimeFunctor<T> >
|
|
koethe@1199
|
2667 |
{
|
|
koethe@1199
|
2668 |
public:
|
|
koethe@1199
|
2669 |
typedef VigraTrueType isUnaryFunctor;
|
|
koethe@1199
|
2670 |
};
|
|
koethe@1199
|
2671 |
|
|
koethe@1713
|
2672 |
//@}
|
|
koethe@1713
|
2673 |
|
|
koethe@1199
|
2674 |
/*
|
|
koethe@1199
|
2675 |
Polar coordinates of standard colors:
|
|
koethe@1199
|
2676 |
=====================================
|
|
koethe@1199
|
2677 |
|
|
koethe@1199
|
2678 |
Lab: black = [320.002, 0, 0]
|
|
koethe@1199
|
2679 |
Luv: black = [347.827, 0, 0]
|
|
koethe@1199
|
2680 |
YPbPr: black = [341.352, 0, 0]
|
|
koethe@1199
|
2681 |
YCbCr: black = [341.352, 0, 0]
|
|
koethe@1199
|
2682 |
YIQ: black = [19.5807, 0, 0]
|
|
koethe@1199
|
2683 |
YUV: black = [346.557, 0, 0]
|
|
koethe@1199
|
2684 |
Lab: red = [1.20391e-05, 0.532406, 0.781353]
|
|
koethe@1199
|
2685 |
Luv: red = [360, 0.532406, 1]
|
|
koethe@1199
|
2686 |
YPbPr: red = [360, 0.299, 0.988419]
|
|
koethe@1199
|
2687 |
YCbCr: red = [360, 0.299, 0.988417]
|
|
koethe@1199
|
2688 |
YIQ: red = [360, 0.299, 1]
|
|
koethe@1199
|
2689 |
YUV: red = [360, 0.299, 1]
|
|
koethe@1199
|
2690 |
Lab: green = [96.0184, 0.877351, 0.895108]
|
|
koethe@1199
|
2691 |
Luv: green = [115.552, 0.877351, 0.758352]
|
|
koethe@1199
|
2692 |
YPbPr: green = [123.001, 0.587, 1]
|
|
koethe@1199
|
2693 |
YCbCr: green = [123.001, 0.587, 0.999996]
|
|
koethe@1199
|
2694 |
YIQ: green = [137.231, 0.587, 0.933362]
|
|
koethe@1199
|
2695 |
YUV: green = [137.257, 0.587, 0.933931]
|
|
koethe@1199
|
2696 |
Lab: blue = [266.287, 0.322957, 0.999997]
|
|
koethe@1199
|
2697 |
Luv: blue = [253.7, 0.322957, 0.729883]
|
|
koethe@1199
|
2698 |
YPbPr: blue = [242.115, 0.114, 0.948831]
|
|
koethe@1199
|
2699 |
YCbCr: blue = [242.115, 0.114, 0.948829]
|
|
koethe@1199
|
2700 |
YIQ: blue = [243.585, 0.114, 0.707681]
|
|
koethe@1199
|
2701 |
YUV: blue = [243.639, 0.114, 0.707424]
|
|
koethe@1199
|
2702 |
Lab: yellow = [62.8531, 0.971395, 0.724189]
|
|
koethe@1199
|
2703 |
Luv: yellow = [73.7, 0.971395, 0.597953]
|
|
koethe@1199
|
2704 |
YPbPr: yellow = [62.1151, 0.886, 0.948831]
|
|
koethe@1199
|
2705 |
YCbCr: yellow = [62.1149, 0.886, 0.948829]
|
|
koethe@1199
|
2706 |
YIQ: yellow = [63.5851, 0.886, 0.707681]
|
|
koethe@1199
|
2707 |
YUV: yellow = [63.6393, 0.886, 0.707424]
|
|
koethe@1199
|
2708 |
Lab: magenta = [288.237, 0.603235, 0.863482]
|
|
koethe@1199
|
2709 |
Luv: magenta = [295.553, 0.603235, 0.767457]
|
|
koethe@1199
|
2710 |
YPbPr: magenta = [303.001, 0.413, 1]
|
|
koethe@1199
|
2711 |
YCbCr: magenta = [303.001, 0.413, 0.999996]
|
|
koethe@1199
|
2712 |
YIQ: magenta = [317.231, 0.413, 0.933362]
|
|
koethe@1199
|
2713 |
YUV: magenta = [317.257, 0.413, 0.933931]
|
|
koethe@1199
|
2714 |
Lab: cyan = [156.378, 0.911133, 0.374577]
|
|
koethe@1199
|
2715 |
Luv: cyan = [180, 0.911133, 0.402694]
|
|
koethe@1199
|
2716 |
YPbPr: cyan = [180, 0.701, 0.988419]
|
|
koethe@1199
|
2717 |
YCbCr: cyan = [180, 0.701, 0.988417]
|
|
koethe@1199
|
2718 |
YIQ: cyan = [180, 0.701, 1]
|
|
koethe@1199
|
2719 |
YUV: cyan = [180, 0.701, 1]
|
|
koethe@1199
|
2720 |
Lab: white = [320.002, 1, 0]
|
|
koethe@1199
|
2721 |
Luv: white = [14.3606, 1, 3.26357e-06]
|
|
koethe@1199
|
2722 |
YPbPr: white = [341.352, 1, 0]
|
|
koethe@1199
|
2723 |
YCbCr: white = [341.352, 1, 0]
|
|
koethe@1199
|
2724 |
YIQ: white = [154.581, 1, 1.24102e-16]
|
|
koethe@1199
|
2725 |
YUV: white = [229.992, 1, 9.81512e-17]
|
|
koethe@1199
|
2726 |
|
|
koethe@1199
|
2727 |
*/
|
|
koethe@1199
|
2728 |
|
|
koethe@1713
|
2729 |
/** \ingroup ColorConversions
|
|
koethe@1713
|
2730 |
\defgroup PolarColors Polar Color Coordinates
|
|
koethe@1199
|
2731 |
|
|
koethe@1199
|
2732 |
Transform colors from/to a polar representation (hue, brighness, saturation).
|
|
koethe@1199
|
2733 |
In many situations, this is more inituitive than direct initialization in a
|
|
koethe@1199
|
2734 |
particular color space. The polar coordinates are
|
|
koethe@1199
|
2735 |
normalized so that a color angle of 0 degrees is always associated with red
|
|
koethe@1199
|
2736 |
(green is at about 120 degrees, blue at about 240 degrees - exact values differ
|
|
koethe@1199
|
2737 |
between color spaces). A saturation of 1 is the highest saturation that any RGB color
|
|
koethe@1199
|
2738 |
gets after transformation into the respective color space, and saturation 0 corresponds to
|
|
koethe@1199
|
2739 |
gray. Thus, different color spaces become somewhat comparable.
|
|
koethe@1199
|
2740 |
*/
|
|
koethe@1199
|
2741 |
//@{
|
|
koethe@1199
|
2742 |
/** \brief Init L*a*b* color triple from polar representation.
|
|
koethe@1199
|
2743 |
|
|
koethe@1623
|
2744 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2745 |
Namespace: vigra
|
|
koethe@1199
|
2746 |
|
|
koethe@1199
|
2747 |
<b> Declarations:</b>
|
|
koethe@1199
|
2748 |
|
|
koethe@1199
|
2749 |
\code
|
|
koethe@1199
|
2750 |
TinyVector<float, 3>
|
|
koethe@1199
|
2751 |
polar2Lab(double color, double brightness, double saturation);
|
|
koethe@1199
|
2752 |
|
|
koethe@1199
|
2753 |
TinyVector<float, 3>
|
|
koethe@1199
|
2754 |
polar2Lab(TinyVector<float, 3> const & polar);
|
|
koethe@1199
|
2755 |
\endcode
|
|
koethe@1199
|
2756 |
|
|
koethe@1199
|
2757 |
\arg color - the color angle in degrees
|
|
koethe@1199
|
2758 |
\arg brightness - between 0 and 1
|
|
koethe@1199
|
2759 |
\arg saturation - between 0 and 1
|
|
koethe@1199
|
2760 |
|
|
koethe@1199
|
2761 |
L*a*b* polar coordinates of some important colors:
|
|
koethe@1199
|
2762 |
|
|
koethe@1199
|
2763 |
\code
|
|
koethe@1199
|
2764 |
black = [*, 0, 0] * - arbitrary
|
|
koethe@1199
|
2765 |
white = [*, 1, 0] * - arbitrary
|
|
koethe@1199
|
2766 |
|
|
koethe@1199
|
2767 |
red = [ 0, 0.532406, 0.781353]
|
|
koethe@1199
|
2768 |
yellow = [62.8531, 0.971395, 0.724189]
|
|
koethe@1199
|
2769 |
green = [96.0184, 0.877351, 0.895108]
|
|
koethe@1199
|
2770 |
cyan = [156.378, 0.911133, 0.374577]
|
|
koethe@1199
|
2771 |
blue = [266.287, 0.322957, 0.999997]
|
|
koethe@1199
|
2772 |
magenta = [288.237, 0.603235, 0.863482]
|
|
koethe@1199
|
2773 |
\endcode
|
|
koethe@1199
|
2774 |
*/
|
|
koethe@1199
|
2775 |
inline TinyVector<float, 3>
|
|
koethe@1199
|
2776 |
polar2Lab(double color, double brightness, double saturation)
|
|
koethe@1199
|
2777 |
{
|
|
koethe@1199
|
2778 |
double angle = (color+39.9977)/180.0*M_PI;
|
|
koethe@1199
|
2779 |
double normsat = saturation*133.809;
|
|
koethe@1199
|
2780 |
|
|
koethe@1199
|
2781 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
2782 |
result[0] = float(100.0*brightness);
|
|
ullrich@1791
|
2783 |
result[1] = float(normsat*VIGRA_CSTD::cos(angle));
|
|
ullrich@1791
|
2784 |
result[2] = float(normsat*VIGRA_CSTD::sin(angle));
|
|
koethe@1199
|
2785 |
return result;
|
|
koethe@1199
|
2786 |
}
|
|
koethe@1199
|
2787 |
|
|
koethe@1199
|
2788 |
|
|
koethe@1199
|
2789 |
template <class V>
|
|
koethe@1199
|
2790 |
TinyVector<float, 3>
|
|
koethe@1199
|
2791 |
polar2Lab(V const & polar)
|
|
koethe@1199
|
2792 |
{
|
|
koethe@1199
|
2793 |
return polar2Lab(polar[0], polar[1], polar[2]);
|
|
koethe@1199
|
2794 |
}
|
|
koethe@1199
|
2795 |
|
|
koethe@1199
|
2796 |
/** \brief Create polar representation form L*a*b*
|
|
koethe@1199
|
2797 |
|
|
koethe@1199
|
2798 |
<b> Declaration:</b>
|
|
koethe@1199
|
2799 |
|
|
koethe@1199
|
2800 |
\code
|
|
koethe@1199
|
2801 |
namespace vigra {
|
|
koethe@1199
|
2802 |
TinyVector<float, 3> lab2Polar(TinyVector<float, 3> const & lab);
|
|
koethe@1199
|
2803 |
}
|
|
koethe@1199
|
2804 |
\endcode
|
|
koethe@1199
|
2805 |
|
|
koethe@1623
|
2806 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2807 |
Namespace: vigra
|
|
koethe@1199
|
2808 |
|
|
koethe@1199
|
2809 |
This realizes the inverse of the transformation described in
|
|
koethe@1623
|
2810 |
\ref polar2Lab().
|
|
koethe@1199
|
2811 |
*/
|
|
koethe@1199
|
2812 |
template <class V>
|
|
koethe@1199
|
2813 |
TinyVector<float, 3>
|
|
koethe@1199
|
2814 |
lab2Polar(V const & lab)
|
|
koethe@1199
|
2815 |
{
|
|
koethe@1199
|
2816 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
2817 |
result[1] = float(lab[0]/100.0);
|
|
koethe@1199
|
2818 |
double angle = (lab[1] == 0.0 && lab[2] == 0.0)
|
|
koethe@1199
|
2819 |
? 0.0
|
|
koethe@1199
|
2820 |
: VIGRA_CSTD::atan2(lab[2], lab[1])/M_PI*180.0-39.9977;
|
|
koethe@1199
|
2821 |
result[0] = angle < 0.0 ?
|
|
ullrich@1791
|
2822 |
float(angle + 360.0) :
|
|
ullrich@1791
|
2823 |
float(angle);
|
|
ullrich@1791
|
2824 |
result[2] = float(VIGRA_CSTD::sqrt(lab[1]*lab[1] + lab[2]*lab[2])/133.809);
|
|
koethe@1199
|
2825 |
return result;
|
|
koethe@1199
|
2826 |
}
|
|
koethe@1199
|
2827 |
|
|
koethe@1199
|
2828 |
/** \brief Init L*u*v* color triple from polar representation.
|
|
koethe@1199
|
2829 |
|
|
koethe@1623
|
2830 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2831 |
Namespace: vigra
|
|
koethe@1199
|
2832 |
|
|
koethe@1199
|
2833 |
<b> Declarations:</b>
|
|
koethe@1199
|
2834 |
|
|
koethe@1199
|
2835 |
\code
|
|
koethe@1199
|
2836 |
TinyVector<float, 3>
|
|
koethe@1199
|
2837 |
polar2Luv(double color, double brightness, double saturation);
|
|
koethe@1199
|
2838 |
|
|
koethe@1199
|
2839 |
TinyVector<float, 3>
|
|
koethe@1199
|
2840 |
polar2Luv(TinyVector<float, 3> const & polar);
|
|
koethe@1199
|
2841 |
\endcode
|
|
koethe@1199
|
2842 |
|
|
koethe@1199
|
2843 |
\arg color - the color angle in degrees
|
|
koethe@1199
|
2844 |
\arg brightness - between 0 and 1
|
|
koethe@1199
|
2845 |
\arg saturation - between 0 and 1
|
|
koethe@1199
|
2846 |
|
|
koethe@1199
|
2847 |
L*u*v* polar coordinates of some important colors:
|
|
koethe@1199
|
2848 |
|
|
koethe@1199
|
2849 |
\code
|
|
koethe@1199
|
2850 |
black = [*, 0, 0] * - arbitrary
|
|
koethe@1199
|
2851 |
white = [*, 1, 0] * - arbitrary
|
|
koethe@1199
|
2852 |
|
|
koethe@1199
|
2853 |
red = [ 0, 0.532406, 1]
|
|
koethe@1199
|
2854 |
yellow = [ 73.7, 0.971395, 0.597953]
|
|
koethe@1199
|
2855 |
green = [115.552, 0.877351, 0.758352]
|
|
koethe@1199
|
2856 |
cyan = [ 180.0, 0.911133, 0.402694]
|
|
koethe@1199
|
2857 |
blue = [ 253.7, 0.322957, 0.729883]
|
|
koethe@1199
|
2858 |
magenta = [295.553, 0.603235, 0.767457]
|
|
koethe@1199
|
2859 |
\endcode
|
|
koethe@1199
|
2860 |
*/
|
|
koethe@1199
|
2861 |
inline TinyVector<float, 3>
|
|
koethe@1199
|
2862 |
polar2Luv(double color, double brightness, double saturation)
|
|
koethe@1199
|
2863 |
{
|
|
koethe@1199
|
2864 |
double angle = (color+12.1727)/180.0*M_PI;
|
|
koethe@1199
|
2865 |
double normsat = saturation*179.04;
|
|
koethe@1199
|
2866 |
|
|
koethe@1199
|
2867 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
2868 |
result[0] = float(100.0*brightness);
|
|
ullrich@1791
|
2869 |
result[1] = float(normsat*VIGRA_CSTD::cos(angle));
|
|
ullrich@1791
|
2870 |
result[2] = float(normsat*VIGRA_CSTD::sin(angle));
|
|
koethe@1199
|
2871 |
return result;
|
|
koethe@1199
|
2872 |
}
|
|
koethe@1199
|
2873 |
|
|
koethe@1199
|
2874 |
template <class V>
|
|
koethe@1199
|
2875 |
TinyVector<float, 3>
|
|
koethe@1199
|
2876 |
polar2Luv(V const & polar)
|
|
koethe@1199
|
2877 |
{
|
|
koethe@1199
|
2878 |
return polar2Luv(polar[0], polar[1], polar[2]);
|
|
koethe@1199
|
2879 |
}
|
|
koethe@1199
|
2880 |
|
|
koethe@1199
|
2881 |
/** \brief Create polar representation form L*u*v*
|
|
koethe@1199
|
2882 |
|
|
koethe@1199
|
2883 |
<b> Declaration:</b>
|
|
koethe@1199
|
2884 |
|
|
koethe@1199
|
2885 |
\code
|
|
koethe@1199
|
2886 |
namespace vigra {
|
|
koethe@1199
|
2887 |
TinyVector<float, 3> luv2Polar(TinyVector<float, 3> const & luv);
|
|
koethe@1199
|
2888 |
}
|
|
koethe@1199
|
2889 |
\endcode
|
|
koethe@1199
|
2890 |
|
|
koethe@1623
|
2891 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2892 |
Namespace: vigra
|
|
koethe@1199
|
2893 |
|
|
koethe@1199
|
2894 |
This realizes the inverse of the transformation described in
|
|
koethe@1623
|
2895 |
\ref polar2Luv().
|
|
koethe@1199
|
2896 |
*/
|
|
koethe@1199
|
2897 |
template <class V>
|
|
koethe@1199
|
2898 |
TinyVector<float, 3>
|
|
koethe@1199
|
2899 |
luv2Polar(V const & luv)
|
|
koethe@1199
|
2900 |
{
|
|
koethe@1199
|
2901 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
2902 |
result[1] = float(luv[0]/100.0);
|
|
koethe@1199
|
2903 |
double angle = (luv[1] == 0.0 && luv[2] == 0.0)
|
|
koethe@1199
|
2904 |
? 0.0
|
|
koethe@1199
|
2905 |
: VIGRA_CSTD::atan2(luv[2], luv[1])/M_PI*180.0-12.1727;
|
|
koethe@1199
|
2906 |
result[0] = angle < 0.0 ?
|
|
ullrich@1791
|
2907 |
float(angle + 360.0) :
|
|
ullrich@1791
|
2908 |
float(angle);
|
|
ullrich@1791
|
2909 |
result[2] = float(VIGRA_CSTD::sqrt(luv[1]*luv[1] + luv[2]*luv[2])/179.04);
|
|
koethe@1199
|
2910 |
return result;
|
|
koethe@1199
|
2911 |
}
|
|
koethe@1199
|
2912 |
|
|
koethe@1199
|
2913 |
/** \brief Init Y'PbPr color triple from polar representation.
|
|
koethe@1199
|
2914 |
|
|
koethe@1623
|
2915 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2916 |
Namespace: vigra
|
|
koethe@1199
|
2917 |
|
|
koethe@1199
|
2918 |
<b> Declarations:</b>
|
|
koethe@1199
|
2919 |
|
|
koethe@1199
|
2920 |
\code
|
|
koethe@1199
|
2921 |
TinyVector<float, 3>
|
|
koethe@1199
|
2922 |
polar2YPrimePbPr(double color, double brightness, double saturation);
|
|
koethe@1199
|
2923 |
|
|
koethe@1199
|
2924 |
TinyVector<float, 3>
|
|
koethe@1199
|
2925 |
polar2YPrimePbPr(TinyVector<float, 3> const & polar);
|
|
koethe@1199
|
2926 |
\endcode
|
|
koethe@1199
|
2927 |
|
|
koethe@1199
|
2928 |
\arg color - the color angle in degrees
|
|
koethe@1199
|
2929 |
\arg brightness - between 0 and 1
|
|
koethe@1199
|
2930 |
\arg saturation - between 0 and 1
|
|
koethe@1199
|
2931 |
|
|
koethe@1199
|
2932 |
Y'PbPr polar coordinates of some important colors:
|
|
koethe@1199
|
2933 |
|
|
koethe@1199
|
2934 |
\code
|
|
koethe@1199
|
2935 |
black = [*, 0, 0] * - arbitrary
|
|
koethe@1199
|
2936 |
white = [*, 1, 0] * - arbitrary
|
|
koethe@1199
|
2937 |
|
|
koethe@1199
|
2938 |
red = [ 0, 0.299, 0.988419]
|
|
koethe@1199
|
2939 |
yellow = [62.1151, 0.886, 0.948831]
|
|
koethe@1199
|
2940 |
green = [123.001, 0.587, 1]
|
|
koethe@1199
|
2941 |
cyan = [ 180.0, 0.701, 0.988419]
|
|
koethe@1199
|
2942 |
blue = [242.115, 0.114, 0.948831]
|
|
koethe@1199
|
2943 |
magenta = [303.001, 0.413, 1]
|
|
koethe@1199
|
2944 |
\endcode
|
|
koethe@1199
|
2945 |
*/
|
|
koethe@1199
|
2946 |
inline TinyVector<float, 3>
|
|
koethe@1199
|
2947 |
polar2YPrimePbPr(double color, double brightness, double saturation)
|
|
koethe@1199
|
2948 |
{
|
|
koethe@1199
|
2949 |
double angle = (color+18.6481)/180.0*M_PI;
|
|
koethe@1199
|
2950 |
double normsat = saturation*0.533887;
|
|
koethe@1199
|
2951 |
|
|
koethe@1199
|
2952 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
2953 |
result[0] = float(brightness);
|
|
ullrich@1791
|
2954 |
result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
|
|
ullrich@1791
|
2955 |
result[2] = float(normsat*VIGRA_CSTD::cos(angle));
|
|
koethe@1199
|
2956 |
return result;
|
|
koethe@1199
|
2957 |
}
|
|
koethe@1199
|
2958 |
|
|
koethe@1199
|
2959 |
template <class V>
|
|
koethe@1199
|
2960 |
TinyVector<float, 3>
|
|
koethe@1199
|
2961 |
polar2YPrimePbPr(V const & polar)
|
|
koethe@1199
|
2962 |
{
|
|
koethe@1199
|
2963 |
return polar2YPrimePbPr(polar[0], polar[1], polar[2]);
|
|
koethe@1199
|
2964 |
}
|
|
koethe@1199
|
2965 |
|
|
koethe@1199
|
2966 |
/** \brief Create polar representation form Y'PbPr
|
|
koethe@1199
|
2967 |
|
|
koethe@1199
|
2968 |
<b> Declaration:</b>
|
|
koethe@1199
|
2969 |
|
|
koethe@1199
|
2970 |
\code
|
|
koethe@1199
|
2971 |
namespace vigra {
|
|
koethe@1199
|
2972 |
TinyVector<float, 3> yPrimePbPr2Polar(TinyVector<float, 3> const & ypbpr);
|
|
koethe@1199
|
2973 |
}
|
|
koethe@1199
|
2974 |
\endcode
|
|
koethe@1199
|
2975 |
|
|
koethe@1623
|
2976 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
2977 |
Namespace: vigra
|
|
koethe@1199
|
2978 |
|
|
koethe@1199
|
2979 |
This realizes the inverse of the transformation described in
|
|
koethe@1623
|
2980 |
\ref polar2YPrimePbPr().
|
|
koethe@1199
|
2981 |
*/
|
|
koethe@1199
|
2982 |
template <class V>
|
|
koethe@1199
|
2983 |
TinyVector<float, 3>
|
|
koethe@1199
|
2984 |
yPrimePbPr2Polar(V const & ypbpr)
|
|
koethe@1199
|
2985 |
{
|
|
koethe@1199
|
2986 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
2987 |
result[1] = float(ypbpr[0]);
|
|
koethe@1199
|
2988 |
double angle = (ypbpr[1] == 0.0 && ypbpr[2] == 0.0)
|
|
koethe@1199
|
2989 |
? 0.0
|
|
koethe@1199
|
2990 |
: VIGRA_CSTD::atan2(-ypbpr[1], ypbpr[2])/M_PI*180.0-18.6481;
|
|
koethe@1199
|
2991 |
result[0] = angle < 0.0 ?
|
|
ullrich@1791
|
2992 |
float(angle + 360.0) :
|
|
ullrich@1791
|
2993 |
float(angle);
|
|
ullrich@1791
|
2994 |
result[2] = float(VIGRA_CSTD::sqrt(ypbpr[1]*ypbpr[1] + ypbpr[2]*ypbpr[2])/0.533887);
|
|
koethe@1199
|
2995 |
return result;
|
|
koethe@1199
|
2996 |
}
|
|
koethe@1199
|
2997 |
|
|
koethe@1199
|
2998 |
/** \brief Init Y'CbCr color triple from polar representation.
|
|
koethe@1199
|
2999 |
|
|
koethe@1623
|
3000 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
3001 |
Namespace: vigra
|
|
koethe@1199
|
3002 |
|
|
koethe@1199
|
3003 |
<b> Declarations:</b>
|
|
koethe@1199
|
3004 |
|
|
koethe@1199
|
3005 |
\code
|
|
koethe@1199
|
3006 |
TinyVector<float, 3>
|
|
koethe@1199
|
3007 |
polar2YPrimeCbCr(double color, double brightness, double saturation);
|
|
koethe@1199
|
3008 |
|
|
koethe@1199
|
3009 |
TinyVector<float, 3>
|
|
koethe@1199
|
3010 |
polar2YPrimeCbCr(TinyVector<float, 3> const & polar);
|
|
koethe@1199
|
3011 |
\endcode
|
|
koethe@1199
|
3012 |
|
|
koethe@1199
|
3013 |
\arg color - the color angle in degrees
|
|
koethe@1199
|
3014 |
\arg brightness - between 0 and 1
|
|
koethe@1199
|
3015 |
\arg saturation - between 0 and 1
|
|
koethe@1199
|
3016 |
|
|
koethe@1199
|
3017 |
Y'CbCr polar coordinates of some important colors:
|
|
koethe@1199
|
3018 |
|
|
koethe@1199
|
3019 |
\code
|
|
koethe@1199
|
3020 |
black = [*, 0, 0] * - arbitrary
|
|
koethe@1199
|
3021 |
white = [*, 1, 0] * - arbitrary
|
|
koethe@1199
|
3022 |
|
|
koethe@1199
|
3023 |
red = [ 0, 0.299, 0.988419]
|
|
koethe@1199
|
3024 |
yellow = [62.1151, 0.886, 0.948831]
|
|
koethe@1199
|
3025 |
green = [123.001, 0.587, 1]
|
|
koethe@1199
|
3026 |
cyan = [ 180.0, 0.701, 0.988419]
|
|
koethe@1199
|
3027 |
blue = [242.115, 0.114, 0.948831]
|
|
koethe@1199
|
3028 |
magenta = [303.001, 0.413, 1]
|
|
koethe@1199
|
3029 |
\endcode
|
|
koethe@1199
|
3030 |
*/
|
|
koethe@1199
|
3031 |
inline TinyVector<float, 3>
|
|
koethe@1199
|
3032 |
polar2YPrimeCbCr(double color, double brightness, double saturation)
|
|
koethe@1199
|
3033 |
{
|
|
koethe@1199
|
3034 |
double angle = (color+18.6482)/180.0*M_PI;
|
|
koethe@1199
|
3035 |
double normsat = saturation*119.591;
|
|
koethe@1199
|
3036 |
|
|
koethe@1199
|
3037 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
3038 |
result[0] = float(brightness*219.0 + 16.0);
|
|
ullrich@1791
|
3039 |
result[1] = float(-normsat*VIGRA_CSTD::sin(angle)+128.0);
|
|
ullrich@1791
|
3040 |
result[2] = float(normsat*VIGRA_CSTD::cos(angle)+128.0);
|
|
koethe@1199
|
3041 |
return result;
|
|
koethe@1199
|
3042 |
}
|
|
koethe@1199
|
3043 |
|
|
koethe@1199
|
3044 |
template <class V>
|
|
koethe@1199
|
3045 |
TinyVector<float, 3>
|
|
koethe@1199
|
3046 |
polar2YPrimeCbCr(V const & polar)
|
|
koethe@1199
|
3047 |
{
|
|
koethe@1199
|
3048 |
return polar2YPrimeCbCr(polar[0], polar[1], polar[2]);
|
|
koethe@1199
|
3049 |
}
|
|
koethe@1199
|
3050 |
|
|
koethe@1199
|
3051 |
/** \brief Create polar representation form Y'CbCr
|
|
koethe@1199
|
3052 |
|
|
koethe@1199
|
3053 |
<b> Declaration:</b>
|
|
koethe@1199
|
3054 |
|
|
koethe@1199
|
3055 |
\code
|
|
koethe@1199
|
3056 |
namespace vigra {
|
|
koethe@1199
|
3057 |
TinyVector<float, 3> yPrimeCbCr2Polar(TinyVector<float, 3> const & ycbcr);
|
|
koethe@1199
|
3058 |
}
|
|
koethe@1199
|
3059 |
\endcode
|
|
koethe@1199
|
3060 |
|
|
koethe@1623
|
3061 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
3062 |
Namespace: vigra
|
|
koethe@1199
|
3063 |
|
|
koethe@1199
|
3064 |
This realizes the inverse of the transformation described in
|
|
koethe@1623
|
3065 |
\ref polar2YPrimeCbCr().
|
|
koethe@1199
|
3066 |
*/
|
|
koethe@1199
|
3067 |
template <class V>
|
|
koethe@1199
|
3068 |
TinyVector<float, 3>
|
|
koethe@1199
|
3069 |
yPrimeCbCr2Polar(V const & ycbcr)
|
|
koethe@1199
|
3070 |
{
|
|
koethe@1199
|
3071 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
3072 |
result[1] = float((ycbcr[0]-16.0)/219.0);
|
|
koethe@1199
|
3073 |
double cb = ycbcr[1]-128.0;
|
|
koethe@1199
|
3074 |
double cr = ycbcr[2]-128.0;
|
|
koethe@1199
|
3075 |
double angle = (cb == 0.0 && cr == 0.0)
|
|
koethe@1199
|
3076 |
? 0.0
|
|
koethe@1199
|
3077 |
: VIGRA_CSTD::atan2(-cb, cr)/M_PI*180.0-18.6482;
|
|
koethe@1199
|
3078 |
result[0] = angle < 0.0 ?
|
|
ullrich@1791
|
3079 |
float(angle + 360.0) :
|
|
ullrich@1791
|
3080 |
float(angle);
|
|
ullrich@1791
|
3081 |
result[2] = float(VIGRA_CSTD::sqrt(cb*cb + cr*cr)/119.591);
|
|
koethe@1199
|
3082 |
return result;
|
|
koethe@1199
|
3083 |
}
|
|
koethe@1199
|
3084 |
|
|
koethe@1199
|
3085 |
/** \brief Init Y'IQ color triple from polar representation.
|
|
koethe@1199
|
3086 |
|
|
koethe@1623
|
3087 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
3088 |
Namespace: vigra
|
|
koethe@1199
|
3089 |
|
|
koethe@1199
|
3090 |
<b> Declarations:</b>
|
|
koethe@1199
|
3091 |
|
|
koethe@1199
|
3092 |
\code
|
|
koethe@1199
|
3093 |
TinyVector<float, 3>
|
|
koethe@1199
|
3094 |
polar2YPrimeIQ(double color, double brightness, double saturation);
|
|
koethe@1199
|
3095 |
|
|
koethe@1199
|
3096 |
TinyVector<float, 3>
|
|
koethe@1199
|
3097 |
polar2YPrimeIQ(TinyVector<float, 3> const & polar);
|
|
koethe@1199
|
3098 |
\endcode
|
|
koethe@1199
|
3099 |
|
|
koethe@1199
|
3100 |
\arg color - the color angle in degrees
|
|
koethe@1199
|
3101 |
\arg brightness - between 0 and 1
|
|
koethe@1199
|
3102 |
\arg saturation - between 0 and 1
|
|
koethe@1199
|
3103 |
|
|
koethe@1199
|
3104 |
Y'IQ polar coordinates of some important colors:
|
|
koethe@1199
|
3105 |
|
|
koethe@1199
|
3106 |
\code
|
|
koethe@1199
|
3107 |
black = [*, 0, 0] * - arbitrary
|
|
koethe@1199
|
3108 |
white = [*, 1, 0] * - arbitrary
|
|
koethe@1199
|
3109 |
|
|
koethe@1199
|
3110 |
red = [ 0, 0.299, 1]
|
|
koethe@1199
|
3111 |
yellow = [63.5851, 0.886, 0.707681]
|
|
koethe@1199
|
3112 |
green = [137.231, 0.587, 0.933362]
|
|
koethe@1199
|
3113 |
cyan = [ 180.0, 0.701, 1]
|
|
koethe@1199
|
3114 |
blue = [243.585, 0.114, 0.707681]
|
|
koethe@1199
|
3115 |
magenta = [317.231, 0.413, 0.933362]
|
|
koethe@1199
|
3116 |
\endcode
|
|
koethe@1199
|
3117 |
*/
|
|
koethe@1199
|
3118 |
inline TinyVector<float, 3>
|
|
koethe@1199
|
3119 |
polar2YPrimeIQ(double color, double brightness, double saturation)
|
|
koethe@1199
|
3120 |
{
|
|
koethe@1199
|
3121 |
double angle = (color-19.5807)/180.0*M_PI;
|
|
koethe@1199
|
3122 |
double normsat = saturation*0.632582;
|
|
koethe@1199
|
3123 |
|
|
koethe@1199
|
3124 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
3125 |
result[0] = float(brightness);
|
|
ullrich@1791
|
3126 |
result[1] = float(normsat*VIGRA_CSTD::cos(angle));
|
|
ullrich@1791
|
3127 |
result[2] = float(-normsat*VIGRA_CSTD::sin(angle));
|
|
koethe@1199
|
3128 |
return result;
|
|
koethe@1199
|
3129 |
}
|
|
koethe@1199
|
3130 |
|
|
koethe@1199
|
3131 |
template <class V>
|
|
koethe@1199
|
3132 |
TinyVector<float, 3>
|
|
koethe@1199
|
3133 |
polar2YPrimeIQ(V const & polar)
|
|
koethe@1199
|
3134 |
{
|
|
koethe@1199
|
3135 |
return polar2YPrimeIQ(polar[0], polar[1], polar[2]);
|
|
koethe@1199
|
3136 |
}
|
|
koethe@1199
|
3137 |
|
|
koethe@1199
|
3138 |
/** \brief Create polar representation form Y'IQ
|
|
koethe@1199
|
3139 |
|
|
koethe@1199
|
3140 |
<b> Declaration:</b>
|
|
koethe@1199
|
3141 |
|
|
koethe@1199
|
3142 |
\code
|
|
koethe@1199
|
3143 |
namespace vigra {
|
|
koethe@1199
|
3144 |
TinyVector<float, 3> yPrimeIQ2Polar(TinyVector<float, 3> const & yiq);
|
|
koethe@1199
|
3145 |
}
|
|
koethe@1199
|
3146 |
\endcode
|
|
koethe@1199
|
3147 |
|
|
koethe@1623
|
3148 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
3149 |
Namespace: vigra
|
|
koethe@1199
|
3150 |
|
|
koethe@1199
|
3151 |
This realizes the inverse of the transformation described in
|
|
koethe@1623
|
3152 |
\ref polar2YPrimeIQ().
|
|
koethe@1199
|
3153 |
*/
|
|
koethe@1199
|
3154 |
template <class V>
|
|
koethe@1199
|
3155 |
TinyVector<float, 3>
|
|
koethe@1199
|
3156 |
yPrimeIQ2Polar(V const & yiq)
|
|
koethe@1199
|
3157 |
{
|
|
koethe@1199
|
3158 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
3159 |
result[1] = float(yiq[0]);
|
|
koethe@1199
|
3160 |
double angle = (yiq[1] == 0.0 && yiq[2] == 0.0)
|
|
koethe@1199
|
3161 |
? 0.0
|
|
koethe@1199
|
3162 |
: VIGRA_CSTD::atan2(-yiq[2], yiq[1])/M_PI*180.0+19.5807;
|
|
koethe@1199
|
3163 |
result[0] = angle < 0.0 ?
|
|
ullrich@1791
|
3164 |
float(angle + 360.0) :
|
|
ullrich@1791
|
3165 |
float(angle);
|
|
ullrich@1791
|
3166 |
result[2] = float(VIGRA_CSTD::sqrt(yiq[1]*yiq[1] + yiq[2]*yiq[2])/0.632582);
|
|
koethe@1199
|
3167 |
return result;
|
|
koethe@1199
|
3168 |
}
|
|
koethe@1199
|
3169 |
|
|
koethe@1199
|
3170 |
/** \brief Init Y'UV color triple from polar representation.
|
|
koethe@1199
|
3171 |
|
|
koethe@1623
|
3172 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
3173 |
Namespace: vigra
|
|
koethe@1199
|
3174 |
|
|
koethe@1199
|
3175 |
<b> Declarations:</b>
|
|
koethe@1199
|
3176 |
|
|
koethe@1199
|
3177 |
\code
|
|
koethe@1199
|
3178 |
TinyVector<float, 3>
|
|
koethe@1199
|
3179 |
polar2YPrimeUV(double color, double brightness, double saturation);
|
|
koethe@1199
|
3180 |
|
|
koethe@1199
|
3181 |
TinyVector<float, 3>
|
|
koethe@1199
|
3182 |
polar2YPrimeUV(TinyVector<float, 3> const & polar);
|
|
koethe@1199
|
3183 |
\endcode
|
|
koethe@1199
|
3184 |
|
|
koethe@1199
|
3185 |
\arg color - the color angle in degrees
|
|
koethe@1199
|
3186 |
\arg brightness - between 0 and 1
|
|
koethe@1199
|
3187 |
\arg saturation - between 0 and 1
|
|
koethe@1199
|
3188 |
|
|
koethe@1199
|
3189 |
Y'UV polar coordinates of some important colors:
|
|
koethe@1199
|
3190 |
|
|
koethe@1199
|
3191 |
\code
|
|
koethe@1199
|
3192 |
black = [*, 0, 0] * - arbitrary
|
|
koethe@1199
|
3193 |
white = [*, 1, 0] * - arbitrary
|
|
koethe@1199
|
3194 |
|
|
koethe@1199
|
3195 |
red = [ 0, 0.299, 1]
|
|
koethe@1199
|
3196 |
yellow = [63.5851, 0.886, 0.707681]
|
|
koethe@1199
|
3197 |
green = [137.231, 0.587, 0.933362]
|
|
koethe@1199
|
3198 |
cyan = [ 180.0, 0.701, 1]
|
|
koethe@1199
|
3199 |
blue = [243.585, 0.114, 0.707681]
|
|
koethe@1199
|
3200 |
magenta = [317.231, 0.413, 0.933362]
|
|
koethe@1199
|
3201 |
\endcode
|
|
koethe@1199
|
3202 |
*/
|
|
koethe@1199
|
3203 |
inline TinyVector<float, 3>
|
|
koethe@1199
|
3204 |
polar2YPrimeUV(double color, double brightness, double saturation)
|
|
koethe@1199
|
3205 |
{
|
|
koethe@1199
|
3206 |
double angle = (color+13.4569)/180.0*M_PI;
|
|
koethe@1199
|
3207 |
double normsat = saturation*0.632324;
|
|
koethe@1199
|
3208 |
|
|
koethe@1199
|
3209 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
3210 |
result[0] = float(brightness);
|
|
ullrich@1791
|
3211 |
result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
|
|
ullrich@1791
|
3212 |
result[2] = float(normsat*VIGRA_CSTD::cos(angle));
|
|
koethe@1199
|
3213 |
return result;
|
|
koethe@1199
|
3214 |
}
|
|
koethe@1199
|
3215 |
|
|
koethe@1199
|
3216 |
template <class V>
|
|
koethe@1199
|
3217 |
TinyVector<float, 3>
|
|
koethe@1199
|
3218 |
polar2YPrimeUV(V const & polar)
|
|
koethe@1199
|
3219 |
{
|
|
koethe@1199
|
3220 |
return polar2YPrimeUV(polar[0], polar[1], polar[2]);
|
|
koethe@1199
|
3221 |
}
|
|
koethe@1199
|
3222 |
|
|
koethe@1199
|
3223 |
/** \brief Create polar representation form Y'UV
|
|
koethe@1199
|
3224 |
|
|
koethe@1199
|
3225 |
<b> Declaration:</b>
|
|
koethe@1199
|
3226 |
|
|
koethe@1199
|
3227 |
\code
|
|
koethe@1199
|
3228 |
namespace vigra {
|
|
koethe@1199
|
3229 |
TinyVector<float, 3> yPrimeUV2Polar(TinyVector<float, 3> const & yuv);
|
|
koethe@1199
|
3230 |
}
|
|
koethe@1199
|
3231 |
\endcode
|
|
koethe@1199
|
3232 |
|
|
koethe@1623
|
3233 |
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/colorconversions.hxx</a>\><br>
|
|
koethe@1199
|
3234 |
Namespace: vigra
|
|
koethe@1199
|
3235 |
|
|
koethe@1199
|
3236 |
This realizes the inverse of the transformation described in
|
|
koethe@1623
|
3237 |
\ref polar2YPrimeUV().
|
|
koethe@1199
|
3238 |
*/
|
|
koethe@1199
|
3239 |
template <class V>
|
|
koethe@1199
|
3240 |
TinyVector<float, 3>
|
|
koethe@1199
|
3241 |
yPrimeUV2Polar(V const & yuv)
|
|
koethe@1199
|
3242 |
{
|
|
koethe@1199
|
3243 |
TinyVector<float, 3> result;
|
|
ullrich@1791
|
3244 |
result[1] = float(yuv[0]);
|
|
koethe@1199
|
3245 |
double angle = (yuv[1] == 0.0 && yuv[2] == 0.0)
|
|
koethe@1199
|
3246 |
? 0.0
|
|
koethe@1199
|
3247 |
: VIGRA_CSTD::atan2(-yuv[1], yuv[2])/M_PI*180.0-13.4569;
|
|
koethe@1199
|
3248 |
result[0] = angle < 0.0 ?
|
|
ullrich@1791
|
3249 |
float(angle + 360.0) :
|
|
ullrich@1791
|
3250 |
float(angle);
|
|
ullrich@1791
|
3251 |
result[2] = float(VIGRA_CSTD::sqrt(yuv[1]*yuv[1] + yuv[2]*yuv[2])/0.632324);
|
|
koethe@1199
|
3252 |
return result;
|
|
koethe@1199
|
3253 |
}
|
|
koethe@1199
|
3254 |
|
|
koethe@1199
|
3255 |
//@}
|
|
koethe@1199
|
3256 |
|
|
koethe@1199
|
3257 |
} // namespace vigra
|
|
koethe@1199
|
3258 |
|
|
koethe@1199
|
3259 |
#endif /* VIGRA_COLORCONVERSIONS_HXX */
|