在您的实现的色度适应部分中有些东西不起作用。
使用colour 和手动转换:
>>> import colour
>>> import numpy as np
>>> RGB = np.array([100, 80, 20]) / 255
>>> D50 = colour.CCS_ILLUMINANTS['cie_2_1931']['D50']
>>> XYZ = colour.sRGB_to_XYZ(RGB, illuminant=D50)
>>> print(colour.XYZ_to_Lab(XYZ, illuminant=D50))
[ 35.31471609 3.63177851 37.28158403]
并使用自动颜色转换图:
>>> colour.convert(RGB, 'sRGB', 'CIE Lab', illuminant=D50) * 100
array([ 35.31471609, 3.63177851, 37.28158403]
还有一个不使用colour.sRGB_to_XYZ 定义并且似乎与您的匹配的替代路径:
>>> colour.convert(RGB, 'Output-Referred RGB', 'CIE Lab', illuminant=D50, verbose={'mode': 'short'}) * 100
===============================================================================
* *
* [ Conversion Path ] *
* *
* "cctf_decoding" --> "RGB_to_XYZ" --> "XYZ_to_Lab" *
* *
===============================================================================
array([ 34.99753019, 0.50577795, 31.35732344])
这里发生的情况是,从 RGB 到 CIE XYZ 三色值的转换不会在 D65 和 D65 之间执行任何色度适应em>D50 因为illuminant 参数与colour.RGB_to_XYZ 定义不匹配。正确的做法是为 RGB 端指定 illuminant_RGB,尽管 CIE XYZ默认为 D65 和 illuminant_XYZ > 侧面:
>>> colour.convert(RGB, 'Output-Referred RGB', 'CIE Lab', illuminant_XYZ=D50, illuminant=D50, verbose={'mode': 'short'}) * 100
===============================================================================
* *
* [ Conversion Path ] *
* *
* "cctf_decoding" --> "RGB_to_XYZ" --> "XYZ_to_Lab" *
* *
===============================================================================
array([ 35.31471609, 3.63177851, 37.28158403])
现在我们匹配预期的转换结果。这是详细的转换,以便您可以检查中间值:
>>> colour.convert(RGB, 'Output-Referred RGB', 'CIE Lab', RGB_to_XYZ={'illuminant_XYZ': D50}, XYZ_to_Lab={'illuminant': D50}, verbose={'mode': 'Extended'}) * 100
===================================================================================
* *
* [ Conversion Path ] *
* *
* "cctf_decoding" --> "RGB_to_XYZ" --> "XYZ_to_Lab" *
* *
===================================================================================
===================================================================================
* *
* [ "cctf_decoding" ] *
* *
* [ Signature ] *
* *
* <Signature (value, function='sRGB', **kwargs)> *
* *
* [ Documentation ] *
* *
* Decodes non-linear :math:`R'G'B'` values to linear :math:`RGB` values using *
* given decoding colour component transfer function (Decoding CCTF). *
* *
* Parameters *
* ---------- *
* value : numeric or array_like *
* Non-linear :math:`R'G'B'` values. *
* function : unicode, optional *
* {:attr:`colour.CCTF_DECODINGS`}, *
* Computation function. *
* *
* Other Parameters *
* ---------------- *
* \**kwargs : dict, optional *
* Keywords arguments for the relevant decoding CCTF of the *
* :attr:`colour.CCTF_DECODINGS` attribute collection. *
* *
* Warnings *
* -------- *
* For *ITU-R BT.2100*, only the electro-optical transfer functions *
* (EOTFs / EOCFs) are exposed by this definition, please refer to the *
* :func:`colour.oetf_inverse` definition for the inverse opto-electronic *
* transfer functions (OETF / OECF). *
* *
* Returns *
* ------- *
* numeric or ndarray *
* Linear :math:`RGB` values. *
* *
* Examples *
* -------- *
* >>> cctf_decoding(0.391006842619746, function='PLog', log_reference=400) *
* ... # doctest: +ELLIPSIS *
* 0.1... *
* >>> cctf_decoding(0.182011532850008, function='ST 2084', L_p=1000) *
* ... # doctest: +ELLIPSIS *
* 0.1... *
* >>> cctf_decoding( # doctest: +ELLIPSIS *
* ... 0.461356129500442, function='ITU-R BT.1886') *
* 0.1... *
* *
* [ Conversion Output ] *
* *
* [ 0.12743768 0.08021982 0.00699541] *
* *
===================================================================================
===================================================================================
* *
* [ "RGB_to_XYZ" ] *
* *
* [ Signature ] *
* *
* <Signature (RGB, illuminant_RGB, illuminant_XYZ, matrix_RGB_to_XYZ, *
* chromatic_adaptation_transform='CAT02', cctf_decoding=None)> *
* *
* [ Filtered Arguments ] *
* *
* {'cctf_decoding': {'return': array([ 0.12743768, 0.08021982, *
* 0.00699541])}, *
* 'illuminant_XYZ': array([ 0.3457, 0.3585])} *
* *
* [ Documentation ] *
* *
* Converts given *RGB* colourspace array to *CIE XYZ* tristimulus values. *
* *
* Parameters *
* ---------- *
* RGB : array_like *
* *RGB* colourspace array. *
* illuminant_RGB : array_like *
* *CIE xy* chromaticity coordinates or *CIE xyY* colourspace array of the *
* *illuminant* for the input *RGB* colourspace array. *
* illuminant_XYZ : array_like *
* *CIE xy* chromaticity coordinates or *CIE xyY* colourspace array of the *
* *illuminant* for the output *CIE XYZ* tristimulus values. *
* matrix_RGB_to_XYZ : array_like *
* Matrix converting the *RGB* colourspace array to *CIE XYZ* tristimulus *
* values, i.e. the *Normalised Primary Matrix* (NPM). *
* chromatic_adaptation_transform : unicode, optional *
* **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp', *
* 'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02 Brill 2008', *
* 'Bianco 2010', 'Bianco PC 2010', None}**, *
* *Chromatic adaptation* transform, if *None* no chromatic adaptation is *
* performed. *
* cctf_decoding : object, optional *
* Decoding colour component transfer function (Decoding CCTF) or *
* electro-optical transfer function (EOTF / EOCF). *
* *
* Returns *
* ------- *
* ndarray *
* *CIE XYZ* tristimulus values. *
* *
* Notes *
* ----- *
* *
* +--------------------+-----------------------+---------------+ *
* | **Domain** | **Scale - Reference** | **Scale - 1** | *
* +====================+=======================+===============+ *
* | ``RGB`` | [0, 1] | [0, 1] | *
* +--------------------+-----------------------+---------------+ *
* | ``illuminant_XYZ`` | [0, 1] | [0, 1] | *
* +--------------------+-----------------------+---------------+ *
* | ``illuminant_RGB`` | [0, 1] | [0, 1] | *
* +--------------------+-----------------------+---------------+ *
* *
* +--------------------+-----------------------+---------------+ *
* | **Range** | **Scale - Reference** | **Scale - 1** | *
* +====================+=======================+===============+ *
* | ``XYZ`` | [0, 1] | [0, 1] | *
* +--------------------+-----------------------+---------------+ *
* *
* Examples *
* -------- *
* >>> RGB = np.array([0.45595571, 0.03039702, 0.04087245]) *
* >>> illuminant_RGB = np.array([0.31270, 0.32900]) *
* >>> illuminant_XYZ = np.array([0.34570, 0.35850]) *
* >>> chromatic_adaptation_transform = 'Bradford' *
* >>> matrix_RGB_to_XYZ = np.array( *
* ... [[0.41240000, 0.35760000, 0.18050000], *
* ... [0.21260000, 0.71520000, 0.07220000], *
* ... [0.01930000, 0.11920000, 0.95050000]] *
* ... ) *
* >>> RGB_to_XYZ(RGB, illuminant_RGB, illuminant_XYZ, matrix_RGB_to_XYZ, *
* ... chromatic_adaptation_transform) # doctest: +ELLIPSIS *
* array([ 0.2163881..., 0.1257 , 0.0384749...]) *
* *
* [ Conversion Output ] *
* *
* [ 0.08765592 0.08656689 0.01383652] *
* *
===================================================================================
===================================================================================
* *
* [ "XYZ_to_Lab" ] *
* *
* [ Signature ] *
* *
* <Signature (XYZ, illuminant=array([ 0.3127, 0.329 ]))> *
* *
* [ Filtered Arguments ] *
* *
* {'illuminant': array([ 0.3457, 0.3585])} *
* *
* [ Documentation ] *
* *
* Converts from *CIE XYZ* tristimulus values to *CIE L\*a\*b\** *
* colourspace. *
* *
* Parameters *
* ---------- *
* XYZ : array_like *
* *CIE XYZ* tristimulus values. *
* illuminant : array_like, optional *
* Reference *illuminant* *CIE xy* chromaticity coordinates or *CIE xyY* *
* colourspace array. *
* *
* Returns *
* ------- *
* ndarray *
* *CIE L\*a\*b\** colourspace array. *
* *
* Notes *
* ----- *
* *
* +----------------+-----------------------+-----------------+ *
* | **Domain** | **Scale - Reference** | **Scale - 1** | *
* +================+=======================+=================+ *
* | ``XYZ`` | [0, 1] | [0, 1] | *
* +----------------+-----------------------+-----------------+ *
* | ``illuminant`` | [0, 1] | [0, 1] | *
* +----------------+-----------------------+-----------------+ *
* *
* +----------------+-----------------------+-----------------+ *
* | **Range** | **Scale - Reference** | **Scale - 1** | *
* +================+=======================+=================+ *
* | ``Lab`` | ``L`` : [0, 100] | ``L`` : [0, 1] | *
* | | | | *
* | | ``a`` : [-100, 100] | ``a`` : [-1, 1] | *
* | | | | *
* | | ``b`` : [-100, 100] | ``b`` : [-1, 1] | *
* +----------------+-----------------------+-----------------+ *
* *
* References *
* ---------- *
* :cite:`CIETC1-482004m` *
* *
* Examples *
* -------- *
* >>> import numpy as np *
* >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) *
* >>> XYZ_to_Lab(XYZ) # doctest: +ELLIPSIS *
* array([ 41.5278752..., 52.6385830..., 26.9231792...]) *
* *
* [ Conversion Output ] *
* *
* [ 0.35314716 0.03631779 0.37281584] *
* *
===================================================================================
array([ 35.31471609, 3.63177851, 37.28158403])