HCL цвет в RGB и в обратном направлении - PullRequest
11 голосов
/ 23 сентября 2011

Мне нужен алгоритм для преобразования цвета HCL в RGB и обратного RGB в HCL, учитывая, что эти цветовые пространства имеют разные цветовые гаммы (мне нужно ограничить цвета HCL теми, которые можно воспроизводить в цветовом пространстве RGB). Каков алгоритм для этого (алгоритм предназначен для реализации в Wolfram Mathematica , который изначально поддерживает только цвет RGB)? У меня нет опыта работы с цветовыми пространствами.

P.S. Некоторые статьи о цвете HCL:

M. Сарифуддин (2005). Новое воспринимаемое однородное цветовое пространство со связанной мерой цветового сходства для поиска изображений и видео на основе контента.

Zeileis, Hornik and Murrell (2009): выход из RGBland: выбор цветов для статистической графики // Вычислительная статистика и анализ данных, том 53, выпуск 9, 1 июля 2009 года, страницы 3259-3270

UPDATE: Как указывает Джонатан Янссон , в двух вышеприведенных статьях различные цветовые пространства описываются именем "HCL": "Во второй статье используется L C h (uv), который является такой же, как L u v *, но описан в полярных координатах, где h (uv) - угол координаты u * и v *, а C * - величина этого вектора ". Так что на самом деле мне нужен алгоритм для преобразования RGB в L u v * и обратно.

Ответы [ 5 ]

7 голосов
/ 27 сентября 2011

Я только что узнал о цветовом пространстве HCL. Цветовое пространство, используемое в двух статьях в вашем вопросе, похоже, отличается цветовыми пространствами.

Во второй статье используется L * C * h (uv), который аналогичен L * u * v *, но описан в полярных координатах, где h (uv) - это угол координат u * и v * и C * это величина этого вектора.

Цветовое пространство LCH в первой статье, по-видимому, описывает другое цветовое пространство, которое использует более алгоритмическое преобразование. Здесь также есть другая версия первой статьи: http://isjd.pdii.lipi.go.id/admin/jurnal/14209102121.pdf

Если вы намеревались использовать CIE L * u * v *, вам необходимо сначала преобразовать sRGB в CIE XYZ, а затем преобразовать в CIE L * u * v *. На самом деле RGB в большинстве случаев относится к sRGB, поэтому нет необходимости преобразовывать RGB в sRGB.

Весь исходный код необходим

Хорошая статья о том, как работает преобразование в XYZ

Хороший онлайн-конвертер

Но я не могу ответить на ваш вопрос о том, как ограничить цвета пространством sRGB. Вы можете просто выбросить цвета RGB, которые находятся за пределами диапазона от 0 до 1 после преобразования. Простое совмещение цветов может дать довольно странные результаты. Попробуйте перейти к конвертеру и ввести цвет RGB 0 0 255 и преобразовать в L * a * b * (аналогично L * u * v *), а затем увеличить L * до 70 и преобразовать его обратно, и результат, безусловно, больше не синий.

Редактировать: исправил URL Изменить: Объединить другой ответ в этот ответ

6 голосов
/ 23 сентября 2011

Я знаком с довольно многими цветовыми пространствами, но это новое для меня. Увы, ColorConvert Mathematica тоже не знает этого.

Я нашел здесь подпрограмму rgb2hcl , но никакой подпрограммы, идущей в другую сторону, нет.

Более полный пакет преобразования цветового пространства можно найти здесь . Кажется, что он может делать преобразования во все виды цветовых пространств. Найдите файл colorspace.c в colorspace_1.1-0.tar.gz \ colorspace_1.1-0.tar \ colorspace \ src. Обратите внимание, что в этом пакете HCL известен как PolarLUV.

3 голосов
/ 15 августа 2012

HCL - это очень общее название, есть много способов получить оттенок, цветность и яркость. Например, в Chroma.js есть нечто, что он называет HCL, который представляет собой Lab с преобразованием полярных координат (если вы посмотрите на реальный код). Другие реализации, даже связанные с того же сайта, используют Polar Luv. Поскольку вы можете просто позаимствовать L-фактор и получить оттенок путем преобразования в полярные координаты, оба эти способа являются допустимыми для получения этих трех элементов. Гораздо лучше называть их Polar Lab и Polar Luv из-за путаницы.

M. Алгоритм Sarifuddin (2005) не является Polar Luv или Polar Lab и более прост в вычислительном отношении (вам не нужно сначала выводить пространство Lab или Luv), и на самом деле может быть лучше. Есть некоторые вещи, которые кажутся неправильными в газете. Например, применение евклидова расстояния к цветовому пространству CIE L * C * H *. Использование Hue означает, что оно обязательно круглое, и простое замешивание этого числа в A² + B² + C² вызовет у вас проблемы. То же самое верно для применения цветового пространства на основе оттенков к D94 или D00, поскольку это алгоритмы расстояния со встроенными коррекциями, специфичными для цветового пространства Lab. Если бы я не пропустил что-то там, я бы проигнорировал цифры 6-8. И я подвергаю сомнению отклонения отклонения в графике. Вы можете установить более низкий порог и добиться большего успеха, а числа между цветовыми пространствами не нормализуются. В любом случае, несмотря на некоторые кажущиеся недостатки в статье, описанный алгоритм стоит попробовать. Возможно, вы захотите сделать евклидово на RGB, если это не имеет большого значения. Но, если вы ходите по магазинам вокруг алгоритмов цветового расстояния, то вы идете.

Вот HCL, предоставленный М. Сарифуддином, реализованным на Java. Прочитав эту статью несколько раз, я не могу избежать вывода о том, что она масштабирует расстояние с коэффициентом от 0,16 до 180,16 с учетом изменения оттенка в процедуре distance_hcl. Это настолько серьезный фактор, что он почти не может быть правильным. И делает соответствие цвета отстой. Я закомментировал строку статьи и использую строку только с коэффициентом Al. Масштабирование люминесценции с постоянным коэффициентом ~ 1,4 не сделает его непригодным для использования. Без масштабного коэффициента он оказывается идентичным циклическому сопротивлению.

http://w3.uqo.ca/missaoui/Publications/TRColorSpace.zip исправлена ​​и улучшена версия статьи.

static final public double Y0 = 100;
static final public double gamma = 3;
static final public double Al = 1.4456;
static final public double Ach_inc = 0.16;

public void rgb2hcl(double[] returnarray, int r, int g, int b) {
    double min = Math.min(Math.min(r, g), b);
    double max = Math.max(Math.max(r, g), b);
    if (max == 0) {
        returnarray[0] = 0;
        returnarray[1] = 0;
        returnarray[2] = 0;
        return;
    }

    double alpha = (min / max) / Y0;
    double Q = Math.exp(alpha * gamma);
    double rg = r - g;
    double gb = g - b;
    double br = b - r;
    double L = ((Q * max) + ((1 - Q) * min)) / 2;
    double C = Q * (Math.abs(rg) + Math.abs(gb) + Math.abs(br)) / 3;
    double H = Math.toDegrees(Math.atan2(gb, rg));

    /*
    //the formulae given in paper, don't work.
    if (rg >= 0 && gb >= 0) {
        H = 2 * H / 3;
    } else if (rg >= 0 && gb < 0) {
        H = 4 * H / 3;
    } else if (rg < 0 && gb >= 0) {
        H = 180 + 4 * H / 3;
    } else if (rg < 0 && gb < 0) {
        H = 2 * H / 3 - 180;
    } // 180 causes the parts to overlap (green == red) and it oddly crumples up bits of the hue for no good reason. 2/3H and 4/3H expanding and contracting quandrants.
    */

    if (rg <  0) {
        if (gb >= 0) H = 90 + H;
        else { H = H - 90; }
    } //works


    returnarray[0] = H;
    returnarray[1] = C;
    returnarray[2] = L;
}

public double cycldistance(double[] hcl1, double[] hcl2) {
    double dL = hcl1[2] - hcl2[2];
    double dH = Math.abs(hcl1[0] - hcl2[0]);
    double C1 = hcl1[1];
    double C2 = hcl2[1];
    return Math.sqrt(dL*dL + C1*C1 + C2*C2 - 2*C1*C2*Math.cos(Math.toRadians(dH)));
}

public double distance_hcl(double[] hcl1, double[] hcl2) {
    double c1 = hcl1[1];
    double c2 = hcl2[1];
    double Dh = Math.abs(hcl1[0] - hcl2[0]);
    if (Dh > 180) Dh = 360 - Dh;
    double Ach = Dh + Ach_inc;
    double AlDl = Al * Math.abs(hcl1[2] - hcl2[2]);
    return Math.sqrt(AlDl * AlDl + (c1 * c1 + c2 * c2 - 2 * c1 * c2 * Math.cos(Math.toRadians(Dh))));
    //return Math.sqrt(AlDl * AlDl + Ach * (c1 * c1 + c2 * c2 - 2 * c1 * c2 * Math.cos(Math.toRadians(Dh))));
}
1 голос
/ 10 февраля 2019

Как упоминалось в других ответах, существует множество способов реализовать цветовое пространство HCL и отобразить его в RGB.

HSLuv оказался тем, что я использовал, и имеет MIT-лицензированные реализации на C, C #, Go, Java, PHP и некоторых других языках. Это похоже на CIELUV LCh, но полностью соответствует RGB. Реализации доступны на GitHub .

Вот краткая графика с веб-сайта, описывающая цветовое пространство HSLuv, с выводом реализации на двух правых панелях:

HSLuv color space examples compared to HSL and CIELUV

0 голосов
/ 16 января 2013

Я думаю,

if (rg <  0) {
    if (gb >= 0) H = 90 + H;
    else { H = H - 90; }
} //works

на самом деле не нужно из-за atan2 (,) вместо atan (/) из бумаги (но теперь ничего о java atan2 (,) особенно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...