Во время преобразования XYZ в линейный sRGB ответ выходит за пределы диапазона [0,1]
Моей задачей было преобразовать RGB-изображение в LuvImage. Выполните линейное растяжение в этой области. А потом конвертировать обратно в домен RGB.
Исходное изображение:
[[0 0 0]
[255 0 0]
[100 100 100]
[0 100 100]]
Luv изображение после линейного растяжения в Luv Domain
[[0, 0, 0],
[100, 175, 37,7],
[79,64, 0, 0],
[71,2,-29,29,-6,339]]
Теперь я конвертирую его в изображение XYZ. Ответ,
[[0,0, 0],
[1,5, 1, 0,53],
[0,533, 0,56, 0,61],
[0,344, 0,425, 0,523]]
Теперь, после этого я преобразую его в линейное изображение sRGB, умножив изображение на матрицу:
[[3.240479, -1.53715, -0.498535],
[-0,969256, 1,875991, 0,041556],
[0.055648, -0.204043, 1.057311]]
Ответ для этого преобразования - линейное изображение sRGB,
[[0. 0. 0.],
[3.07132001 0.44046801 0.44082034],
[0,55904669 0,55972465 0,55993322],
[0.20106868 0.4850426 0.48520307]]
Проблема здесь заключается в том, что для 2-го пикселя значения sRGB не находятся в диапазоне [0,1]. Для всех остальных пикселей я получаю правильное значение.
def XYZToLinearRGB(self, XYZImage):
'''
to find linearsRGBImage, we multiply XYZImage with static array
[[3.240479, -1.53715, -0.498535],
[-0.969256, 1.875991, 0.041556],
[0.055648, -0.204043, 1.057311]]
'''
rows, cols, bands = XYZImage.shape # bands == 3
linearsRGBImage = np.zeros([rows, cols, bands], dtype=float)
multiplierMatrix = np.array([[3.240479, -1.53715, -0.498535],
[-0.969256, 1.875991, 0.041556],
[0.055648, -0.204043, 1.057311]])
for i in range(0, rows):
for j in range(0, cols):
X,Y,Z = XYZImage[i,j]
linearsRGBImage[i,j] = np.matmul(multiplierMatrix, np.array([X,Y,Z]))
#for j -ends
#for i -ends
return linearsRGBImage
Код для этого преобразования, как указано выше. Может кто-нибудь указать, что я делаю неправильно для 2-го пикселя, и как это исправить?
1 ответ
Ну, одно простое решение, которое я нашел после исследования, это просто обрезать значения. Таким образом, если значение выходит за пределы диапазона, скажем, если r<0, то мы назначим r как 0. То же самое для больших значений. Если r>1 (в моем случае 3.07), то мы будем назначать r как 1.
Итак, последняя версия моего кода:
def XYZToLinearRGB(self, XYZImage):
'''
to find linearsRGBImage, we multiply XYZImage with static array
[[3.240479, -1.53715, -0.498535],
[-0.969256, 1.875991, 0.041556],
[0.055648, -0.204043, 1.057311]]
'''
rows, cols, bands = XYZImage.shape # bands == 3
linearsRGBImage = np.zeros([rows, cols, bands], dtype=float)
multiplierMatrix = np.array([[3.240479, -1.53715, -0.498535],
[-0.969256, 1.875991, 0.041556],
[0.055648, -0.204043, 1.057311]])
for i in range(0, rows):
for j in range(0, cols):
X,Y,Z = XYZImage[i,j]
rgbList = np.matmul(multiplierMatrix, np.array([X,Y,Z]))
for index, val in enumerate(rgbList):
if val<0:
rgbList[index]=0
#if val -ends
if val>1:
rgbList[index]=1
#if val -ends
#for index, val -ends
linearsRGBImage[i,j]=rgbList
#for j -ends
#for i -ends
return linearsRGBImage
Хотя, если у кого-то есть лучшее предложение, оно приветствуется.