|
ru.algorithms- RU.ALGORITHMS ---------------------------------------------------------------- From : Alexey Volkov 2:5080/143.45 23 Aug 2001 20:30:19 To : All Subject : метры -> RGB --------------------------------------------------------------------------------
Hello, comrade All!
It was 2001-08-09 19:57, when Sergey Andrianov (2:5017/13.40) wrote to Vadim
Ponomarev:
Hу, образованность свою в физике и колориметрии вроде показали уже все, на
вопрос, как обычно, никто не ответил...
Если кому-нибудь subj ещё нужен - ловите ниже... Это, по крайней мере, хорошее
приближение... Более точные (с шагом 1 нм и сглаженные) таблицы кривых
спектральных цветностей CIE 1931 и CIE 1964 можно найти на
http://cvision.ucsd.edu/cie.htm
Кроме того, если для задачи не нужна особая точность, а достаточно изобразить
нечто похожее на спектр - существуют более простые в вычислениях "эвристические"
методы, например, http://www.physics.sfasu.edu/astro/color.html
или симпатичная программка на Delphi с исходниками -
http://www.efg2.com/Lab/ScienceAndEngineering/Spectra.htm
Hа всякий случай - несколько замечаний по нижеприведённому тексту:
- прямая, проходящая через белую точку и спектральный цвет, разумеется,
пересекает RGB-треугольник в двух точках: одна соответствует спектральному
цвету, вторая - дополнительному к нему - это надо иметь в виду при решении
уравнений;
- для большей переносимости лучше, наверное, взять xy-координаты более
стандартного RGB-пространства - ну, например, по ITU-R BT.709 (они же
рекомендуются как стандарт для Internet -
http://www.w3.org/Graphics/Color/sRGB);
- из текста как-то выпало преобразование xyY -> XYZ: X = (x/y)*Y, Zя=я(z/y)*Y,
причём Y как раз и надо выбирать таким, чтобы "одна из RGB-компонент была в
точности равна единице";
- полученный "спектр" будет неоднородным по яркости (из-за разницы в
относительных яркостях основных цветов) - это можно, наверное, попытаться
сгладить, взяв меньшие насыщенности... ну, это - по вкусу и задаче..
- результатом будут, естественно, линейные RGB-координаты - при использовании не
надо забывать о cоответствующей гамма-коррекции...
=== FREQ-RGB.TXT ===
Converting Frequency to RGB
[1]Chris R. Schoenenman
18 Nov 1991, comp.graphics.algorithms
_________________________________________________________________
The best way of finding the RGB values of a given wavelength is to use
the CIE chromaticity diagram. The spectral locus is on the edge of the
wing-shaped curve. You just need to transform the xy coordinate from
CIEXYZ space into RGB space.
Below I have spectral locus coordinates from 380nm to 780m in steps of
5 nm. It's written as a C array. We'll refer to any particular
wavelength's coordinates as xc and yc.
To transform into RGB, we need the xy coordinates of the RGB primaries
and the alignment white. I'll use a set of typical values.
x y
Red 0.628 0.346 call these xr and yr
Green 0.268 0.588 " " xg and yg
Blue 0.150 0.070 " " xb and yb
White 0.313 0.329 " " xw and yw
From these we can compute the linear transformation from CIEXYZ to
RGB. It is:
[R] = [ 2.739 -1.145 -0.424 ] [X]
[G] = [ -1.119 2.029 0.033 ] [Y]
[B] = [ 0.138 -0.333 1.105 ] [Z]
However, if the xy coordinate of the spectral color isn't inside the
triangle formed by the RGB xy coordinates given above (and none of
them are), then we must first find a closest match that is inside the
triangle. Otherwise our RGB values will go outside the range [0,1],
i.e. some values will be less than zero or greater than one.
One common way of moving the color inside the triangle is to make the
color whiter (i.e. desaturate it). Mathematically we do this by
intersecting the line joining the color and the alignment white with
the edges of the triangle.
First define the line that goes through white and your color
implicitly:
Lc: [-(yw - yc)] * P = [-(yw - yc)] * [xc]
[ xw - wc ] [ xw - xc ] [yc]
For every pair of red, green, and blue, define an explicit (parametric
line). For example, the line between the red and green primaries is:
Lrg: P = [xr] + t * [xg - xr]
[yr] [yg - yr]
Substitute Lrg for P into Lc and solve for the parameter t. If 0 <= t
<= 1, then you've got the answer and you don't need to try the other
lines. Otherwise, substitute Lgb, and if necessary Lbr. If t is not in
the range [0,1] then the intersection occured outside the triangle.
Once you have t, plug it into the original equation for Lrg (or
whatever line gave a good solution) and you get the xy coordinate.
Plug this into the linear transformation above (using z = 1 - x - y)
to get the RGB values. At least one of R, G, or B should be exactly
one (i.e. fully saturated in the RGB color space).
Since this is an involved procedure, I would suggest precomputing
RGB's for all the wavelengths you'll need (or enough to interpolate)
once for each display device you'll be using. If you know the
chromaticity coordinates of your display's primaries and its white you
can compute the linear transformation easily. Just check reference [1]
or if you can't get it, just say so and I'll give you the equations.
[1] also gives code to transform RGB to HSV and back.
Rogers, David F., "Procedural Elements for Computer Graphics,"
McGraw-Hill Book Company, New York, 1985, pp390-398.
/*
* CIE 1931 chromaticity coordinates of spectral stimuli
* (only xy, z = 1 - x - y)
*/
float spectrum_xy[][2] = {
{0.1741, 0.0050}, {0.1740, 0.0050}, {0.1738, 0.0049}, {0.1736, 0.0049},
{0.1733, 0.0048}, {0.1730, 0.0048}, {0.1726, 0.0048}, {0.1721, 0.0048},
{0.1714, 0.0051}, {0.1703, 0.0058}, {0.1689, 0.0069}, {0.1669, 0.0086},
{0.1644, 0.0109}, {0.1611, 0.0138}, {0.1566, 0.0177}, {0.1510, 0.0227},
{0.1440, 0.0297}, {0.1355, 0.0399}, {0.1241, 0.0578}, {0.1096, 0.0868},
{0.0913, 0.1327}, {0.0687, 0.2007}, {0.0454, 0.2950}, {0.0235, 0.4127},
{0.0082, 0.5384}, {0.0039, 0.6548}, {0.0139, 0.7502}, {0.0389, 0.8120},
{0.0743, 0.8338}, {0.1142, 0.8262}, {0.1547, 0.8059}, {0.1929, 0.7816},
{0.2296, 0.7543}, {0.2658, 0.7243}, {0.3016, 0.6923}, {0.3373, 0.6589},
{0.3731, 0.6245}, {0.4087, 0.5896}, {0.4441, 0.5547}, {0.4788, 0.5202},
{0.5125, 0.4866}, {0.5448, 0.4544}, {0.5752, 0.4242}, {0.6029, 0.3965},
{0.6270, 0.3725}, {0.6482, 0.3514}, {0.6658, 0.3340}, {0.6801, 0.3197},
{0.6915, 0.3083}, {0.7006, 0.2993}, {0.7079, 0.2920}, {0.7140, 0.2859},
{0.7190, 0.2809}, {0.7230, 0.2770}, {0.7260, 0.2740}, {0.7283, 0.2717},
{0.7300, 0.2700}, {0.7311, 0.2689}, {0.7320, 0.2680}, {0.7327, 0.2673},
{0.7334, 0.2666}, {0.7340, 0.2660}, {0.7344, 0.2656}, {0.7346, 0.2654},
{0.7347, 0.2653}, {0.7347, 0.2653}, {0.7347, 0.2653}, {0.7347, 0.2653},
{0.7347, 0.2653}, {0.7347, 0.2653}, {0.7347, 0.2653}, {0.7347, 0.2653},
{0.7347, 0.2653}, {0.7347, 0.2653}, {0.7347, 0.2653}, {0.7347, 0.2653},
{0.7347, 0.2653}, {0.7347, 0.2653}, {0.7347, 0.2653}, {0.7347, 0.2653},
{0.7347, 0.2653}};
References
1. mailto:crs@neptune.graphics.cornell.edu
=== EOF ===
Bye.
... I'm so amazingly cool you could keep a side of meat inside me for a month.
--- GoldED+/W32 1.1.4.7
* Origin: Skoll (2:5080/143.45)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/39403b85138a.html, оценка из 5, голосов 10
|