универсальные цветовые координаты LAB.
Люди, такой вопрос, как определить к какой области или точке в видимом спектре относится изображение в универсальных цветовых координатах LAB. И как можно построить такой линейный график: по оси ординат - эта область относительно цветового спектра, по оси абсцисс - время.
Какое еще время?
Идёт реальное время.
И как оно связано с цветом?
как определить к какой области или точке в видимом спектре относится изображение в (указать в универсальных цветовых координатах LAB в цветовом кубе). И как можно указать эту точку на прямой.
Да и единого стандарта на LAB не существует.
Если хочешь чего-то другого, то попытайся сформулировать свою мысль более отчетливо.
И, заодно, о какой именно прямой ты ведешь речь.
Я не так написал, уже отредактировал. Насчёт lab - CIE Lab.
По поводу прямой - нужно представить lab не в виде куба, а в виде координатной прямой.
Боюсь, то, чего ты хочешь, в принципе невозможно.
Или ты опять что-то не так сформулировал.
А что с первой частью вопроса.
Я наткнулся на сайте http://www.easyrgb.com/math.php?MATH=M2 как конвертировать. Вот оттуда пример
Код:
Это RGB -> XYZ
var_R = ( R / 255 ) //Where R = 0 ч 255
var_G = ( G / 255 ) //Where G = 0 ч 255
var_B = ( B / 255 ) //Where B = 0 ч 255
if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
else var_R = var_R / 12.92
if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
else var_G = var_G / 12.92
if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
else var_B = var_B / 12.92
var_R = var_R * 100
var_G = var_G * 100
var_B = var_B * 100
//Observer. = 2°, Illuminant = D65
X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
var_R = ( R / 255 ) //Where R = 0 ч 255
var_G = ( G / 255 ) //Where G = 0 ч 255
var_B = ( B / 255 ) //Where B = 0 ч 255
if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
else var_R = var_R / 12.92
if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
else var_G = var_G / 12.92
if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
else var_B = var_B / 12.92
var_R = var_R * 100
var_G = var_G * 100
var_B = var_B * 100
//Observer. = 2°, Illuminant = D65
X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
Код:
XYZ -> CIE Lab
var_X = X / ref_X //ref_X = 95.047 Observer= 2°, Illuminant= D65
var_Y = Y / ref_Y //ref_Y = 100.000
var_Z = Z / ref_Z //ref_Z = 108.883
if ( var_X > 0.008856 ) var_X = var_X ^ ( 1/3 )
else var_X = ( 7.787 * var_X ) + ( 16 / 116 )
if ( var_Y > 0.008856 ) var_Y = var_Y ^ ( 1/3 )
else var_Y = ( 7.787 * var_Y ) + ( 16 / 116 )
if ( var_Z > 0.008856 ) var_Z = var_Z ^ ( 1/3 )
else var_Z = ( 7.787 * var_Z ) + ( 16 / 116 )
CIE-L* = ( 116 * var_Y ) - 16
CIE-a* = 500 * ( var_X - var_Y )
CIE-b* = 200 * ( var_Y - var_Z )
var_X = X / ref_X //ref_X = 95.047 Observer= 2°, Illuminant= D65
var_Y = Y / ref_Y //ref_Y = 100.000
var_Z = Z / ref_Z //ref_Z = 108.883
if ( var_X > 0.008856 ) var_X = var_X ^ ( 1/3 )
else var_X = ( 7.787 * var_X ) + ( 16 / 116 )
if ( var_Y > 0.008856 ) var_Y = var_Y ^ ( 1/3 )
else var_Y = ( 7.787 * var_Y ) + ( 16 / 116 )
if ( var_Z > 0.008856 ) var_Z = var_Z ^ ( 1/3 )
else var_Z = ( 7.787 * var_Z ) + ( 16 / 116 )
CIE-L* = ( 116 * var_Y ) - 16
CIE-a* = 500 * ( var_X - var_Y )
CIE-b* = 200 * ( var_Y - var_Z )
Для этих преобразований я написал класс, вот его методы:
Код:
double a, b, l;
TCieLabColor::TCieLabColor(int red, int green, int blue)
{
double x = 0, y = 0, z = 0;
ConvertRGBToXYZ(red, green, blue, x, y, z);
ConvertXYZToLab(x, y, z);
}
inline
double TCieLabColor::ConvertRGBComponentToXYZ(double component)
{
if (component > 0.04045)
{
component = pow((component + 0.055 ) / 1.055, 2.4);
}
else
{
component = component / 12.92;
}
return component;
}
inline
void TCieLabColor::ConvertRGBToXYZ(double &red, double &green, double &blue, double &x, double &y, double &z)
{
double r = red / 255;
double g = green / 255;
double b = blue / 255;
r = ConvertRGBComponentToXYZ(r);
g = ConvertRGBComponentToXYZ(g);
b = ConvertRGBComponentToXYZ(b);
r *= 100;
g *= 100;
b *= 100;
x = r * 0.4124 + g * 0.3576 + b * 0.1805;
y = r * 0.2126 + g * 0.7152 + b * 0.0722;
z = r * 0.0193 + g * 0.1192 + b * 0.9505;
}
inline
void TCieLabColor::ConvertXYZToLab(double &x, double &y, double &z)
{
double xComponent = x / 95.047;
double yComponent = y / 100.000;
double zComponent = z / 108.883;
xComponent = ConvertXYZComponentToLab(xComponent);
yComponent = ConvertXYZComponentToLab(yComponent);
zComponent = ConvertXYZComponentToLab(zComponent);
l = (116 * yComponent) - 16;
a = 500 * (xComponent - yComponent);
b = 200 * (yComponent - zComponent);
}
inline
double TCieLabColor::ConvertXYZComponentToLab(double component)
{
if (component > 0.008856)
{
component = pow(component, 1 / 3 );
}
else
{
component = (7.787 * component) + (16 / 116);
}
return component;
}
double TCieLabColor::GetL()
{
return l;
}
double TCieLabColor::GetA()
{
return a;
}
double TCieLabColor::GetB()
{
return b;
}
TCieLabColor::TCieLabColor(int red, int green, int blue)
{
double x = 0, y = 0, z = 0;
ConvertRGBToXYZ(red, green, blue, x, y, z);
ConvertXYZToLab(x, y, z);
}
inline
double TCieLabColor::ConvertRGBComponentToXYZ(double component)
{
if (component > 0.04045)
{
component = pow((component + 0.055 ) / 1.055, 2.4);
}
else
{
component = component / 12.92;
}
return component;
}
inline
void TCieLabColor::ConvertRGBToXYZ(double &red, double &green, double &blue, double &x, double &y, double &z)
{
double r = red / 255;
double g = green / 255;
double b = blue / 255;
r = ConvertRGBComponentToXYZ(r);
g = ConvertRGBComponentToXYZ(g);
b = ConvertRGBComponentToXYZ(b);
r *= 100;
g *= 100;
b *= 100;
x = r * 0.4124 + g * 0.3576 + b * 0.1805;
y = r * 0.2126 + g * 0.7152 + b * 0.0722;
z = r * 0.0193 + g * 0.1192 + b * 0.9505;
}
inline
void TCieLabColor::ConvertXYZToLab(double &x, double &y, double &z)
{
double xComponent = x / 95.047;
double yComponent = y / 100.000;
double zComponent = z / 108.883;
xComponent = ConvertXYZComponentToLab(xComponent);
yComponent = ConvertXYZComponentToLab(yComponent);
zComponent = ConvertXYZComponentToLab(zComponent);
l = (116 * yComponent) - 16;
a = 500 * (xComponent - yComponent);
b = 200 * (yComponent - zComponent);
}
inline
double TCieLabColor::ConvertXYZComponentToLab(double component)
{
if (component > 0.008856)
{
component = pow(component, 1 / 3 );
}
else
{
component = (7.787 * component) + (16 / 116);
}
return component;
}
double TCieLabColor::GetL()
{
return l;
}
double TCieLabColor::GetA()
{
return a;
}
double TCieLabColor::GetB()
{
return b;
}
Второй вопрос: Как определить к какой области (точке) цветовых координат lab относится изображение?
2. Что такое "область цветовых координат"?
PS. Нельзя ли все-таки изъясныться по-русски?
А как всё-таки можно получить координаты lab TBitmap'a, и что именно неправильно в этом алгоритме.
Цитата: Maximillian_Cavalera
А как всё-таки можно получить координаты lab TBitmap'a,
А что у тебя для этого есть?
Цитата:
и что именно неправильно в этом алгоритме.
Разбираться в заведомо неверном алгоритме, извини, желания нет.
А можешь показать верный алгоритм перевода RGB в CIE Lab.
Зато знаю некоторые критерии, по которым можно отличить часть заведмо неверных алгоритмов.
В частности, алгоритм обязательно должен учитывать цветовой профиль конкретного устройства.
Поэтому и о переводе RGB-LAB тоже можно говорить лишь для одного конкретного устройства. Для другого устройства алгоритм (по крайней мере, константы) будет другим.