Матрицы RGB/XYZ (XYZ/RGB)

  • Автор темы Автор темы TRANTOR
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

TRANTOR

Son of a Gun
Топикстартер
R.I.P.
Сообщения
4 566
Реакции
2 957
Копаюсь с DNG-профилями, где используются означенные матрицы. Вызывает некоторое недоумение, что в готовых профилях от Adobe имеются отрицательные значения. Например:

0.4716000 0.0603000 -0.0830000
-0.7798000 1.5474000 0.2480000
-0.1496000 0.1937000 0.6651000

Как известно, матрица RGB/XYZ не может содержать отрицательных чисел. XYZ/RGB (инверсная то есть к RGB/XYZ) может, но все равно получается ерунда:

2.02269404 -0.11582494 0.29560696
0.99274149 0.62103912 -0.10768329
0.16584123 -0.20692030 1.60138484

Это, соответственно, инверсная к изначальной. В любом случае, выходят отрицательные числа.

Из документации к DNG не совсем ясно, какие именно матрицы используются - RGB/XYZ или XYZ/RGB. Интересующие теги <ColorMatrix1> и <ColorMatrix2>.

Вот как это понять?


ЗЫ. Для контрольных расчетов брал вот эти формулы.
 
Вы уверены, что это не матрицы смены хромадаптации?
 
У верен. Это не они. Из спецификации DNG:

ColorMatrix1 defines a transformation matrix that converts XYZ values to reference camera native color space values, under the first calibration illuminant. The matrix values are stored in row scan order.

Тем более, что LR/ACR пользуется стандартным Бредфордом, который известен и он другой.
 
Как известно, матрица RGB/XYZ не может содержать отрицательных чисел. XYZ/RGB (инверсная то есть к RGB/XYZ) может, но все равно получается ерунда
Может когда считали инверсную матрицу в матричных уравнениях ошибки сделали? Перепроверьте. Я когда матричные уравнения программирую постоянно ошибаюсь и долго отлаживаю.
Вот можете свериться с функциями инверсии матрицы 3х3 у Линдблума, они точно правильные:
Код:
function Determinant3x3(m)
{
    var det = m.m00 * (m.m22 * m.m11 - m.m21 * m.m12) -
              m.m10 * (m.m22 * m.m01 - m.m21 * m.m02) +
              m.m20 * (m.m12 * m.m01 - m.m11 * m.m02);
 
    return (det);
}
 
function MtxInvert3x3(m, i)
{
    var scale = 1.0 / Determinant3x3(m);
 
    i.m00 =  scale * (m.m22 * m.m11 - m.m21 * m.m12);
    i.m01 = -scale * (m.m22 * m.m01 - m.m21 * m.m02);
    i.m02 =  scale * (m.m12 * m.m01 - m.m11 * m.m02);
 
    i.m10 = -scale * (m.m22 * m.m10 - m.m20 * m.m12);
    i.m11 =  scale * (m.m22 * m.m00 - m.m20 * m.m02);
    i.m12 = -scale * (m.m12 * m.m00 - m.m10 * m.m02);
 
    i.m20 =  scale * (m.m21 * m.m10 - m.m20 * m.m11);
    i.m21 = -scale * (m.m21 * m.m00 - m.m20 * m.m01);
    i.m22 =  scale * (m.m11 * m.m00 - m.m10 * m.m01);
}
 
function MtxTranspose3x3(m)
{
var v = m.m01;
m.m01 = m.m10;
m.m10 = v;
 
v = m.m02;
m.m02 = m.m20;
m.m20 = v;
 
v = m.m12;
m.m12 = m.m21;
m.m21 = v;
}
 
Это обычная функция Экселя, МОБР(). Она не делает ошибок. :)

Впрочем, уже догадываюсь, в чем тут дело. Матрицы составлены таким образом, чтобы не смотря на выход за пределы XYZ:

1. Покрывать охватом ProPhoto (RIMM space т.е.)
2. Это линейно растянутое ProPhoto
3. Точка белого учтена для компенсации повышенной чувствительности сенсора в зеленом (и не только в нем, кстати), т.е. это некая точка белого самого сенсора.

Т.е. на первом этапе расчета не делается хромадаптации в стандартном виде, а тупо сдвиг матрицей.

Уже попробовал примерно сместить/вернуть primaries в нормальное русло, оставив точку белого как было. А так же взять primaries, например, AdobeRGB. Почти похоже на правду, за исключением, собственно, не совсем верной точки белого для новой матрицы. Для этого надо знать некие коэффициенты сдвига усиления сенсора. Или подбирать руками.

Возможно ошибаюсь и оно все на так, на самом деле.
 
1. Покрывать охватом ProPhoto (RIMM space т.е.)
Про RIMM space поясните пожалуйста чуть подробнее что это? А то я уже немного запутался во всех этих HVS, и сплайнах типа от МакАдама на картинках линдблума под названием Lab Color Space.
 
Adobe решила взять профиль ProPhoto в качестве базового для расчетов и преобразований. Вот тут его спецификации. Отличие от обычного ProPhoto заключается в линейной гамме (вроде только в ней, если я ничего не упустил).

Лично я с таким подходом не согласен. Все те же проблемы типа "brue turns purple", перцептуальная неравномерность по chroma итд. Нет бы, чтоб взять Lch из UPLab у Линдблума. Ну да ладно, имеем то, что имеем. Все равно никто переписывать LR/ACR не станет.

Но в целом идея профилей с двумя иллюминантами интересная. Возможность задавать свои матрицы хромадаптации тоже заслуживает. Однако, текущее ПО ни в какие ворота. Сделано, по моему мнению, на "отвяжись". Поэтому приходится думать над своим.
 
  • Спасибо
Реакции: avs60 и mihas
Сделано, по моему мнению, на "отвяжись"
По горячим следам, так сказать. Мишень снята под Illuminant A; проявка в LR по профилю (мой стандартный профиль для работы), построенному с помощью DNG Profile Editor по обычному КолорЧекеру (другого он и не позволяет).

Adobe DCP Profile Fail.png

Adobe DCP Profile Fail Stats.png

Курам на смех.
 
По горячим следам, так сказать. Мишень снята под Illuminant A; проявка в LR по профилю (мой стандартный профиль для работы), построенному с помощью DNG Profile Editor по обычному КолорЧекеру

А почему вы не строите профили сами? Инструмент, который из raw-данных делает CGATS есть и называется RawDigger :)

Что касается адобовских ColorMatrix в DNG-файлах, то там именно то, что написано: преобразование из XYZ в камерный RGB плюс конверсия баланса белого в указанные условия (D65 для ColorMatrix2 и не помню что для ColorMatrix1).
И они, действительно, не очень хорошие.
 
не строите профили сами?
ПО в процессе разработки пока что.

Или я что-то пропустил и есть готовая программа, которая строит DCP-профили по любым мишеням?

делает CGATS есть и называется RawDigger
Знаю. :)

Однако, придется повторить весь процессинг DNG, который оговорен в шестом разделе спеков DNG. Это слегка утомительно, поэтому пока что пробую по простому методу, методу черного ящика.

плюс конверсия баланса белого в указанные условия
Вот тут засада. Брал соотношение значений камерного RGB на белых/серых патчах при соответствующих условиях съемки и перестраивал матрицу под них. Не. Не попадает - движок ББ в LR выскакивает в космос (если As Shot или пипеткой по серому патчу).

Вообще-то не конверсия, а указание точки белого для соответствующей матрицы. Матрицы конверсии (хромадаптации) прописываются в тегах ForwardMatrix.

не помню что для ColorMatrix1
Illuminant A. Эти матрицы, впрочем, можно посчитать самому для любых пар условий освещения, оговоренных стандартом EXIF. Соответственно, указать в тегах Calibration Illuminant используемые освещения.
 
ПО в процессе разработки пока что.
Или я что-то пропустил и есть готовая программа, которая строит DCP-профили по любым мишеням?
Про DCP профили я знаю мало, в электричество это не верю.
Но есть готовые программы, которые строят ICC-профили по любым мишеням.

Вообще-то не конверсия, а указание точки белого для соответствующей матрицы. Матрицы конверсии (хромадаптации) прописываются в тегах ForwardMatrix.
Всем известная dcraw.c в два простых действия из этой матрицы (ColorMatrix2) получает а) коэффициенты баланса белого для D65 б) собственно матрицу преобразования rgb2rgb (в colorspace вывода).
Там буквально 10 строчек кода, их проще прочитать, чем пересказ мой слушать (и уж мне это тем более проще)

Что же касается DNG Processing Model, то какая-то она сомнительная. Зачем она вам?
 
которые строят ICC-профили
Вопрос исключительно в DCP-профилях. Понятное дело, что для ICC все есть. Но у ICC нет двухиллюминантности.

Всем известная dcraw.c
Я смотрел исходники. Дейв взял адобовские матрицы и дальше "не парился". На этом можно вопрос с dcraw закруглить.

б) собственно матрицу преобразования rgb2rgb
Это матрица хромадаптации. Тут никаких особых проблем нет - брэдфордовские известны (как и другие всякие). Как говорится, бери и ставь.

то какая-то она сомнительная
Чем?

Работаю в LR.
 
Вдогонку, в качестве иллюстрации подходов к хромадаптации на примере Capture One (ICC-профили) и Lightroom (DCP-профили) последних версий. В C1 применен стандартный, в комплекте идущий, ICC для моего Canon 6D. В LR адобоский DCP с обнуленными 3DLUT (чтобы не мешались). Матрицы адобоские (т.к. своих нет пока что).

Хромадаптация двух мишеней, снятых под Illuminant A и D65. То есть, проще говоря, точку ББ тык по белому патчу. Сравнение мишеней друг с другом.

C1:

01 c1.png 02 c1.png

LR:

03 LR.png 04 LR.png


Такие дела.
 
Нет-нет, dcraw-шный rgb_cam[][] - это именно device link профиль, из камеры в sRGB/Adobe/whatever. Почему вы называете его хромадаптацией - мне непонятно.

Что касается диаграм dE: CIE2000 учитывает не только разницу цветности, но и разницу яркости (что естественно), лично я бы рекомендовал бы (временно) игнорировать dL. Либо убедиться в линейности проверяемых Raw-процессоров по серому клину (в общем случае у адобовского движка с этим не очень хорошо, про C1 не знаю)
 
Да, добавка про "Но у ICC нет двухиллюминантности."

Да, нету. Но вот камера у нас остается одной и той же независимо от освещения, меняется ли описывающий ее ICC-профиль? (а если да - то почему, каков физический механизм?)
 
?? Не нашел там LUT-таблиц.

Впрочем, это не важно. Матрицы все равно взяты адобовские. Он сам их не строил.

По остальным патчам видно (если каждый отдельно пипеткой посмотреть), что разброс не столько по L, сколько по ab.

по серому клину
На скриншотах видно, что по серому полую (оно в центре) разброса нет, dE в пределах нормы. Т.е. по серому хромадаптация ОК. А вот все остальные разбежались как тараканы. В случае одноиллюминантности (ICC) заметно больше.

у адобовского движка с этим не очень хорошо
Как видно из скришншота, вполне нормально. Повторюсь - профиль линейный, создан специально. Все остальное тоже по нулям.

Так же напомню, что сравниваются между собой пары мишеней под разным освещением, а не с референсом или результаты разных проявок друг с другом. Сравнивается качество хромадаптации.


а если да - то почему, каков физический механизм?
При разном освещении несамосветящихся объектов меняются метамерные множества. Это справедливо для трихроматичсекой системы захвата, коей у нас является сенсор камеры. Был бы спектрофотометр, это не имело бы никакого значения. Механизм двухиллюминантного профилирования призван это хоть в какой-то мере скомпенсировать. Разумеется, полностью последствия этого эффекта устранить невозможно. Но хоть как-то.
 
1) Отчего бы device link профилю не быть матричному? Кто запрещает? По смыслу - это именно device link, [камерный RGB] *[Profile] => [sRGB]
Совершенно такие же по смыслу матричные device link профили лежат в метаданных многих камер. У кого-то в sRGB, у кого-то в ROMM.

2) Линейность профиля не означает линейности всего процессинга. Вот у вашего 6D (как и у моего) от точки серого "по экспонометру" до насыщения- 3.6EV (для дневного света, зеленый канал). Отснял специально серый кадр, запихал в ACR версии 8.2 (движок тот же что и в LR 5.2): со "всеми настройками по нулям" и отключенным профилем оно делает из этого 107 в 8-bit Adobe RGB (взял его, чтобы не думать про линейный участок sRGB и какая там на самом деле гамма).
Для гаммы 2.2 это (255/107)^2.2 = 6.75 раз или 2.75 стопа вниз от точки белого.

Внимание, вопрос: вот 3.6EV headroom сжались в 2.75EV после проявки, линейна ли тоновая кривая? А если нет - то не стоит ли все-таки L-компоненту исключить из рассмотрения временно?

Вдогонку про скриншоты: я вижу сильно разную яркость нейтральных полей: у адобы в светах, у C1 в полутонах.
 
[камерный RGB] *[Profile] => [sRGB]
Нет. Там процессинг такой: CAMRGB -> XYZCAM, XYZCAM ->XYZD50, XYZD50 -> OUTRGB.

"Классические" Deivice-link профили работают без участия PCS (Profile Connection Space). Поэтому тут я Вас не понимаю.

со "всеми настройками по нулям"
Этого недостаточно. Нужен профиль, который "по нулям".

отключенным профилем
В ACR/LR отключить профиль нельзя. Можно только сделать специальный без 3DLUT и/или линейный.

разную яркость нейтральных полей: у адобы в светах, у C1 в полутонах.
Это не имеет значения. Сравниваются не проявщики между собой, а каждый сам с собой, внутри себя. RAW_A сравнивается с RAW_D65 проявленый LR. И тот же RAW_A сравнивается с RAW_D65 проявленный C1. dE не между LR и C1, а внутри друг друга.
 
Статус
Закрыто для дальнейших ответов.