Рассчитать воспринимаемые равные шаги в цветовой яркости

Я пытался понять это какое-то время, и это сводит меня с ума. Как известно большинству людей, если вы нарисуете 10 прямоугольников рядом друг с другом, начиная от белого и заканчивая черным с равными шагами яркости HSV, они не будут восприниматься глазом одинаково. Вот пример этого:

прямоугольники с одинаковым интервалом в яркости HSB

И код в обработке:

void setup()
{
  size(600, 150);
  colorMode(HSB, 360, 100, 100);
  background(0, 0, 100);

  translate(50, 50);

  noStroke();
  for(int i = 0; i < 10; i++)
  {
    fill(0, 0, i * 10);
    rect(i * 50, 0, 50, 50);
  }
}

Как видите, контраст между некоторыми более темными плитками воспринимается намного больше, чем между некоторыми белыми плитками.

На это указывали многие люди. В своей книге «Искусство цвета» Йозеф Альберс описывает (основываясь на законе Вебера-Фехнера), что вместо этого вы должны увеличивать яркость экспоненциально. Позже было доказано, что Альберс допустил некоторые неприятные просчеты, и идея использования постоянное логарифмическое увеличение яркости оказалось правдой noreferrer">только в очень ограниченных пределах. Об этом написано много статей, но многие из них мне очень трудно читать, и большинство из них связано с физическими аспектами сетчатки.

Итак, мой вопрос:

Учитывая любой цвет, как рассчитать воспринимаемые равные шаги яркости от яркости HSV от 0 до 100?

Более того, как рассчитать воспринимаемые равные шаги яркости от одного цвета к любому другому?

Я создаю файлы для печати с помощью кода, и мне нужно сделать это в Processing. Однако подойдет любой пример на любом языке.


person Ronze    schedule 11.05.2013    source источник
comment
Восприятие цвета невозможно понять в цветовом пространстве HSB, поскольку это цветовое пространство, зависящее от устройства. Вам необходимо ознакомиться с цветовыми пространствами CIE XYZ и CIE Lab*. CIE Lab* поможет вам с восприятием. Вам нужно будет посмотреть на преобразование из CIE Lab* в HSB и соответствующим образом рассчитать яркость. А для печати вы должны посмотреть расчеты HSB в CYMK.   -  person nico_c    schedule 11.05.2013
comment
Да, я так и думал. У меня есть библиотека цветов, которая позволяет мне легко использовать CIE LAB. Значит, если я сделаю то же самое в LAB, изменив L на постоянное значение, я получу правильный результат?   -  person Ronze    schedule 12.05.2013
comment
Насколько я понимаю, вы должны преобразовать Lab* в XYZ, которое является линейным цветовым пространством. Затем вы должны изменить значение Y и преобразовать его в L*, используя формулу: L* = 116 * f(Y/Y0) - 16, где f(Y/Y0) может быть (Y/Y0)^1/ 3 или 1/3*(29/6)^2*(Г/Г0)+4/29. Формула для f, которую вы выберете, будет зависеть от того, больше или меньше Y/Y0, чем (6/29) ^ 3, если оно больше, вы выбираете первую формулу, в противном случае вторую. Y0 обычно принимается равным 100 или около того. Вы можете найти значения для Y0 в Интернете в зависимости от ваших потребностей. Я лично всегда использовал 100 для этого. Примечание: Y0=Y ноль.   -  person nico_c    schedule 12.05.2013
comment
Большое спасибо. Я разместил ответ ниже.   -  person Ronze    schedule 12.05.2013


Ответы (1)


Для других людей, которые хотят сделать это в Processing, вот ответ. Класс Toxiclibs TColor поставляется с преобразованием LAB -> RGB, так что это было несложно. Как видно на скриншоте, разница очевидна.

import toxi.color.*;
import toxi.geom.*;

void setup()
{
  size(600, 250);
  colorMode(RGB, 1, 1, 1);
  background(1);
  noStroke();
  translate(50, 50);

  // RGB: 10 rects where perceived contrast is NOT equal in all squares
  for(float i = 0; i < 10; i++)
  {
    fill(i / 10.0, i / 10.0, i / 10.0);
    rect(i * 50, 0, 50, 50);
  }

  // LAB: 10 rects where perceived contrast IS equal in all squares
  translate(0, 50);

  for(int i = 0; i < 10; i++)
  {
    float[] rgb = TColor.labToRGB(i * 10, 0, 0);
    TColor col = TColor.newRandom().setRGB(rgb);
    fill(col.toARGB());
    rect(i * 50, 0, 50, 50);
  }
}

И вот результат:

введите здесь описание изображения

person Ronze    schedule 12.05.2013
comment
+1. Думаю, мой путь был довольно долгим. Я предполагал, что вам придется работать с цветами HSB в конце (что вы все еще можете с преобразованием RSB → HSB). В любом случае, рад, что вы нашли решение. - person nico_c; 12.05.2013
comment
Я действительно думаю, что сама библиотека делает именно то, что вы описали: преобразование в пространство XYZ, а затем каким-то образом в RGB. Класс TColor имеет функцию toHSV(), поэтому в HSB colorMode она будет почти такой же. - person Ronze; 12.05.2013
comment
У меня сложилось впечатление, что fromCIEXYZ класса ColorSpace сделает то же самое без необходимости использования сторонней зависимости. - person VGR; 12.05.2013