RGB 转换为 XYZ 和 LAB空间,forward matrix,CIE Color Calculator

转载自
How to convert between sRGB and CIEXYZ

How to convert between sRGB and CIEXYZ

Technote 09 Aug 2017

sRGB 是常见的一个图像标准
cie xyz 是评估人眼视觉 常用的一个标准

1. sRGB

The “s” in sRGB stands for “standard” and it is the lowest common denominator in color spaces. It was developed in the 1990s to provide a universal usable color space for display and printers of the time. While there are many different and larger color spaces available, sRGB is still the de facto standard for RGB image data.

2. CIE-XYZ

CIE (Commission Internationale de l’Éclairage) stands for the International Commission on Illumination, which established color spaces based on colors that can be perceived by the human eye. XYZ does not incorporate negative numbers and instead uses tristimulus values to define the color space that can be seen by the human eye. X represents the linear combination of the cone response non-negative curves created. Y represents luminance and Z is defined as almost equal to blue.

3. How to Convert

两者之前如何转换很多人不太清楚。
首先 sRGB 转换为 XYZ, 需要首先对 sRGB 反gamma处理变为 linear sRGB,
在通过矩阵转换 变为 XYZ。

XYZ 转换为sRGB则是相反的操作: 首先通过矩阵转换将 XYZ变为linear sRGB, 然后 gamma处理 得到sRGB.

3.1 sRGB to XYZ

a. sRGB to Linear RGB
可以利用下面的公式转换,也可以直接用 2.2的gamma近似

在这里插入图片描述

b. sRGB’ to XYZ - apply transformation matrix

A standardized 3x3 matrix describes how to convert from sRGB’ data to CIE-XYZ data.

在这里插入图片描述

As a quick reminder for those who implement with a tool that does not support matrix calculation easily (e.g. MS-Excel), the calculation of Y as a single equation is here.

在这里插入图片描述

Side note: When we say that Y represents the brightness, we see that green contributes the most and that blue has only a minor effect.

One more Side note: In case you compare your results with the results you get from tools that use an ICC profile (e.g. apply form in Mathworks Matlab) please note: the conversion shown here results into CIE-XYZ data with a reference white point of D65, as defined in the sRGB definition. ICC-Profiles always use D50 as reference white, which you should be aware of when calculating from XYZ to LAB or are comparing to these results.

3.2 XYZ to sRGB

是一个相反的过程,首先乘上一个矩阵,转化为 linear RGB
然后 apply gamma, 得到sRGB
在这里插入图片描述

4. 参考

1 Calculating RGB↔XYZ matrix (https://mina86.com/2019/srgb-xyz-matrix/)
2 Imatest 測CCM係數的方法: https://www.twblogs.net/a/5b8d00542b7177188338e917
3 CIE Color Calculator :http://www.brucelindbloom.com/index.html?ColorCalculator.html
4. COLOR: DETERMINING A FORWARD MATRIX FOR YOUR CAMERA:(https://www.strollswithmydog.com/determining-forward-color-matrix/)
5. Color conversion matrices in digital cameras: a tutorial :(https://www.spiedigitallibrary.org/journals/optical-engineering/volume-59/issue-11/110801/Color-conversion-matrices-in-digital-cameras-a-tutorial/10.1117/1.OE.59.11.110801.full?SSO=1)

5. 用五种方法来实现 sRGB 到 lab的转换

在这里插入图片描述

import cv2
import numpy as np
from skimage import color
import colour


Xn = 0.950456
Yn = 1.0
Zn = 1.088754

def RGB2XYZ(r, g, b):
    x = 0.412453 * r + 0.357580 * g + 0.180423 * b
    y = 0.212671 * r + 0.715160 * g + 0.072169 * b
    z = 0.019334 * r + 0.119193 * g + 0.950227 * b
    return x, y, z
def f(v):
    if v >0.008856:
        return v**(1/3)
    else:
        return 1 / 3 * v * (29/6)**2  + 4 / 29
def XYZ2Lab(x, y, z):
    x /= Xn
    y /= Yn
    z /= Zn

    l = 116.0 * f(y) - 16.0
    a = 500 * (f(x)-f(y))
    b = 200.0 * (f(y) - f(z))
    return [round(l, 2), round(a, 2), round(b, 2)]


def RGB2Lab(r, g, b):
    x, y, z = RGB2XYZ(r, g, b)
    return XYZ2Lab(x, y, z)

if __name__ == "__main__":
    np.random.seed(0)
    im = np.random.randint(0, 255, (4, 4, 3))
    # 0. 归一化到 0-1 float32
    im1 = im / 255
    im1 = im1.astype(np.float32)
	# 1. opencv
    im1_lab = cv2.cvtColor(im1, cv2.COLOR_RGB2LAB)
    # 2. skimage.color
    im1_lab2 = color.rgb2lab(im1)
	# 3. colour science (完整的三个步骤, degamma, linearRGB to xyz, xyz to lab)
    im1_rgb = colour.cctf_decoding(im1)
    #im1_rgb = im1 ** 2.2
    im1_xyz = colour.sRGB_to_XYZ(im1_rgb, apply_cctf_decoding=False)
    im1_lab3 = colour.XYZ_to_Lab(im1_xyz)
	# 4. colour science (sRGB to xyz, xyz to lab)
    im1_xyz = colour.sRGB_to_XYZ(im1, apply_cctf_decoding=True)
    im1_lab4 = colour.XYZ_to_Lab(im1_xyz)
	
	# 5. 自己的一个实现,更好的理解具体的步骤
    im1_lab5 = []
    for i in range(4):
        for j in range(4):
            im1_lab5.append(RGB2Lab(im1_rgb[i,j,0], im1_rgb[i,j,1], im1_rgb[i,j,2]))
    im1_lab5 = np.array(im1_lab5).reshape(4,4,3)

    im1_l, im1_a, im1_b = cv2.split(im1_lab)
    im1_l2, im1_a2, im1_b2 = cv2.split(im1_lab2)
    im1_l3, im1_a3, im1_b3 = cv2.split(im1_lab3)
    im1_l4, im1_a4, im1_b4 = cv2.split(im1_lab4)
    im1_l5, im1_a5, im1_b5 = cv2.split(im1_lab5)
    print(im1_l.min(), im1_l.max(), im1_a.min(), im1_a.max(), im1_b.min(), im1_b.max())
    print(im1_l2.min(), im1_l2.max(), im1_a2.min(), im1_a2.max(), im1_b2.min(), im1_b2.max())
    print(im1_l3.min(), im1_l3.max(), im1_a3.min(), im1_a3.max(), im1_b3.min(), im1_b3.max())
    print(im1_l4.min(), im1_l4.max(), im1_a4.min(), im1_a4.max(), im1_b4.min(), im1_b4.max())
    print(im1_l5.min(), im1_l5.max(), im1_a5.min(), im1_a5.max(), im1_b5.min(), im1_b5.max())

    """ 总而言之,不同的库得到的答案是一致的:
    主要分为3步:
    1) degamma: srgb to linear rgb
    2)  linear_rgb to xyz
    3)  xyz to lab
    """

7. 图像显示

求得的lab的范围是:
在这里插入图片描述

转换为8bit image:
在这里插入图片描述

8.显示器色域检测

https://www.mpyit.com/monitorinfo.html

9.forward matrix

dng格式中往往会有一个forward matrix, 他的具体含义是什么呢?
raw图经过demosaic 和 wb之后的 图 与 forwar matrix 相乘 ----->得到 xyz
这个矩阵怎么得到呢?标定 xyz是已知的或者通过光谱测出来。
xyz 再乘上一个固定的转换矩阵 ------------>转换为线性srgb, apply gamma后就是srgb
参考:https://www.strollswithmydog.com/determining-forward-color-matrix/#footnote

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值