Coverage for models/oklab.py: 8%

25 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1""" 

2Oklab Colourspace 

3================= 

4 

5Define the *Oklab* colourspace transformations. 

6 

7- :func:`colour.XYZ_to_Oklab` 

8- :func:`colour.Oklab_to_XYZ` 

9 

10References 

11---------- 

12- :cite:`Ottosson2020` : Ottosson, B. (2020). A perceptual color space for 

13 image processing. Retrieved December 24, 2020, from 

14 https://bottosson.github.io/posts/oklab/ 

15""" 

16 

17from __future__ import annotations 

18 

19from functools import partial 

20 

21import numpy as np 

22 

23from colour.algebra import spow 

24from colour.hints import ( # noqa: TC001 

25 Domain1, 

26 NDArrayFloat, 

27 Range1, 

28) 

29from colour.models import Iab_to_XYZ, XYZ_to_Iab 

30 

31__author__ = "Colour Developers" 

32__copyright__ = "Copyright 2013 Colour Developers" 

33__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" 

34__maintainer__ = "Colour Developers" 

35__email__ = "colour-developers@colour-science.org" 

36__status__ = "Production" 

37 

38__all__ = [ 

39 "MATRIX_1_XYZ_TO_LMS", 

40 "MATRIX_1_LMS_TO_XYZ", 

41 "MATRIX_2_LMS_TO_LAB", 

42 "MATRIX_2_LAB_TO_LMS", 

43 "XYZ_to_Oklab", 

44 "Oklab_to_XYZ", 

45] 

46 

47MATRIX_1_XYZ_TO_LMS: NDArrayFloat = np.array( 

48 [ 

49 [0.8189330101, 0.3618667424, -0.1288597137], 

50 [0.0329845436, 0.9293118715, 0.0361456387], 

51 [0.0482003018, 0.2643662691, 0.6338517070], 

52 ] 

53) 

54"""*CIE XYZ* tristimulus values to normalised cone responses matrix.""" 

55 

56MATRIX_1_LMS_TO_XYZ: NDArrayFloat = np.linalg.inv(MATRIX_1_XYZ_TO_LMS) 

57"""Normalised cone responses to *CIE XYZ* tristimulus values matrix.""" 

58 

59MATRIX_2_LMS_TO_LAB: NDArrayFloat = np.array( 

60 [ 

61 [0.2104542553, 0.7936177850, -0.0040720468], 

62 [1.9779984951, -2.4285922050, 0.4505937099], 

63 [0.0259040371, 0.7827717662, -0.8086757660], 

64 ] 

65) 

66"""Normalised cone responses to *Oklab* colourspace matrix.""" 

67 

68MATRIX_2_LAB_TO_LMS: NDArrayFloat = np.linalg.inv(MATRIX_2_LMS_TO_LAB) 

69"""*Oklab* colourspace to normalised cone responses matrix.""" 

70 

71 

72def XYZ_to_Oklab(XYZ: Domain1) -> Range1: 

73 """ 

74 Convert from *CIE XYZ* tristimulus values to *Oklab* colourspace. 

75 

76 Parameters 

77 ---------- 

78 XYZ 

79 *CIE XYZ* tristimulus values. 

80 

81 Returns 

82 ------- 

83 :class:`numpy.ndarray` 

84 *Oklab* colourspace array. 

85 

86 Notes 

87 ----- 

88 +------------+-----------------------+-----------------+ 

89 | **Domain** | **Scale - Reference** | **Scale - 1** | 

90 +============+=======================+=================+ 

91 | ``XYZ`` | 1 | 1 | 

92 +------------+-----------------------+-----------------+ 

93 

94 +------------+-----------------------+-----------------+ 

95 | **Range** | **Scale - Reference** | **Scale - 1** | 

96 +============+=======================+=================+ 

97 | ``Lab`` | 1 | 1 | 

98 +------------+-----------------------+-----------------+ 

99 

100 - Input *CIE XYZ* tristimulus values must be adapted to 

101 *CIE Standard Illuminant D Series* *D65*. 

102 

103 References 

104 ---------- 

105 :cite:`Ottosson2020` 

106 

107 Examples 

108 -------- 

109 >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) 

110 >>> XYZ_to_Oklab(XYZ) # doctest: +ELLIPSIS 

111 array([ 0.5163401..., 0.154695 ..., 0.0628957...]) 

112 """ 

113 

114 return XYZ_to_Iab( 

115 XYZ, 

116 partial(spow, p=1 / 3), 

117 MATRIX_1_XYZ_TO_LMS, 

118 MATRIX_2_LMS_TO_LAB, 

119 ) 

120 

121 

122def Oklab_to_XYZ(Lab: Domain1) -> Range1: 

123 """ 

124 Convert from *Oklab* colourspace to *CIE XYZ* tristimulus values. 

125 

126 Parameters 

127 ---------- 

128 Lab 

129 *Oklab* colourspace array. 

130 

131 Returns 

132 ------- 

133 :class:`numpy.ndarray` 

134 *CIE XYZ* tristimulus values. 

135 

136 Notes 

137 ----- 

138 +------------+-----------------------+-----------------+ 

139 | **Domain** | **Scale - Reference** | **Scale - 1** | 

140 +============+=======================+=================+ 

141 | ``Lab`` | 1 | 1 | 

142 +------------+-----------------------+-----------------+ 

143 

144 +------------+-----------------------+-----------------+ 

145 | **Range** | **Scale - Reference** | **Scale - 1** | 

146 +============+=======================+=================+ 

147 | ``XYZ`` | 1 | 1 | 

148 +------------+-----------------------+-----------------+ 

149 

150 References 

151 ---------- 

152 :cite:`Ottosson2020` 

153 

154 Examples 

155 -------- 

156 >>> Lab = np.array([0.51634019, 0.15469500, 0.06289579]) 

157 >>> Oklab_to_XYZ(Lab) # doctest: +ELLIPSIS 

158 array([ 0.2065400..., 0.1219722..., 0.0513695...]) 

159 """ 

160 

161 return Iab_to_XYZ( 

162 Lab, 

163 partial(spow, p=3), 

164 MATRIX_2_LAB_TO_LMS, 

165 MATRIX_1_LMS_TO_XYZ, 

166 )