Умножение матриц для преобразования цветового пространства

При обработке необработанных изображений вы обычно выполняете два преобразования цветового пространства, используя две матрицы 3x3: rgb2xyz и xyz2camera.

Затем вы можете получить rgb2camera любым из этих двух матричных умножений: (1) rgb2camera = (rgb2xyz)(xyz2camera) или: (2) rgb2camera = (xyz2camera)(rgb2xyz)

А затем получить camera2rgb, инвертировав матрицу rgb2camera.

Однако умножение матриц не является коммутативным, поэтому (1) и (2) дают разные результаты. Я видел оба метода в различных онлайн-статьях, но какой из них правильный? Для меня (1) выглядит правильно (математически), но (2), кажется, дает более правильное изображение (визуально) для образца изображения, которое у меня есть.


person Jim Merkel    schedule 19.07.2019    source источник


Ответы (2)


Математически, если вы сначала умножаете на A, а затем на B, правильной комбинированной матрицей будет BA, а не AB. Они идут в обратном порядке. Вы можете думать об этом как о том, что вектор всегда ставится последним, чтобы он выглядел логично. Так что второе должно быть правильным.

person Sami Kuhmonen    schedule 19.07.2019

Вы можете использовать оба порядка, если измените параметры xyz2camera. С другой стороны, имя переменной имеет еще и семантическое значение, и ваше имя переменной кажется "странным". Обычно вы конвертируете из цветового пространства камеры в хорошо известное цветовое пространство, поэтому было бы более нормально использовать camera2xyz.

Случай 2 верен, если мы рассматриваем семантически допустимые имена переменных:

rgb2camera = (xyz2camera)(rgb2xyz)

Пойдем справа налево. Мы предполагаем (из названий), что мы конвертируем вектор RGB (sRGB?) в RGB_camera, давайте назовем его LMS просто для удовольствия (LMS на самом деле просто реакция глаз, а не датчик камеры), и вы хотите RGB (точно не указано).

  L                     R                              R
[ S ] =  rgb2camera * [ G ] = xyz2camera * rgb2xyz * [ G ]
  M                     B                              B

Ваше имя переменной подразумевает, что:

  X                  R
[ Y ] =  rgb2xyz * [ G ]
  Z                  B

так что у тебя есть

  L                    X
[ S ] = xyz2camera * [ Y ]
  M                    Z

поэтому у вас есть ожидаемое значение:

  L                    R
[ S ] = rgb2camera * [ G ]
  M                    B

Это означает, что rgb2camera = (xyz2camera)(rgb2xyz) как во втором уравнении.

Вы всегда должны интерпретировать такое умножение справа налево. Добавьте в конце виртуальный вектор и аннотируйте на каждом шаге, какое цветовое пространство у вас есть (которое будет входом для следующего умножения). Так вы сделаете меньше ошибок.

Примечание: датчики фотокамер обычно имеют форму RGB (почти все имеют фильтры R, G, B над каждым фотодатчиком). Но сначала вам нужно демозаизировать и линеаризовать R, G, B [они не имеют гамма-коррекции, но имеют собственную функцию коррекции].

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

person Giacomo Catenazzi    schedule 23.07.2019
comment
Я согласен, терминология xyz2camera странная, однако это матрица, указанная в метаданных в файле DNG (ColorMatrix1 и ColorMatrix2). Вы действительно хотите camera2xyz. - person Jim Merkel; 30.07.2019