Coverage for io/ocio.py: 53%

1"""

2 OpenColorIO Processing

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

4

5 Define the object for *OpenColorIO* processing.

6

7- :func:`colour.io.process_image_OpenColorIO`

8"""

9

10 from __future__ import annotations

11

12 import typing

13

14 import numpy as np

15

16 if typing.TYPE_CHECKING:

17 from colour.hints import Any, ArrayLike, NDArrayFloat

18

19 from colour.io import as_3_channels_image

20 from colour.utilities import as_float, as_float_array, required

21

22 __author__ = "Colour Developers"

23 __copyright__ = "Copyright 2013 Colour Developers"

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

25 __maintainer__ = "Colour Developers"

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

27 __status__ = "Production"

28

29 __all__ = [

30 "process_image_OpenColorIO",

31]

32

33

34@required("OpenColorIO")

35 def process_image_OpenColorIO(a: ArrayLike, *args: Any, **kwargs: Any) -> NDArrayFloat:

36 """

37 Process the specified image data with *OpenColorIO*.

38

39 Parameters

40 ----------

41 a

42 Image data to process with *OpenColorIO*.

43

44 Other Parameters

45 ----------------

46 config

47 *OpenColorIO* configuration to use for processing. If not specified,

48 the *OpenColorIO* configuration defined by the ``$OCIO`` environment

49 variable is used.

50 args

51 Arguments for the ``Config.getProcessor`` method. See

52 https://opencolorio.readthedocs.io/en/latest/api/config.html for

53 more information.

54

55 Returns

56 -------

57 :class:`numpy.ndarray`

58 Processed image data.

59

60 Raises

61 ------

62 RuntimeError

63 If *OpenColorIO* is not available.

64

65 Examples

66 --------

67 >>> import os

68 >>> import PyOpenColorIO as ocio # doctest: +SKIP

69 >>> from colour.utilities import full

70 >>> config = os.path.join(

71 ... os.path.dirname(__file__),

72 ... "tests",

73 ... "resources",

74 ... "config-aces-reference.ocio.yaml",

75 ... )

76 >>> a = 0.18

77 >>> process_image_OpenColorIO( # doctest: +SKIP

78 ... a, "ACES - ACES2065-1", "ACES - ACEScct", config=config

79 ... )

80 0.4135884...

81 >>> a = np.array([0.18])

82 >>> process_image_OpenColorIO( # doctest: +SKIP

83 ... a, "ACES - ACES2065-1", "ACES - ACEScct", config=config

84 ... )

85 array([ 0.4135884...])

86 >>> a = np.array([0.18, 0.18, 0.18])

87 >>> process_image_OpenColorIO( # doctest: +SKIP

88 ... a, "ACES - ACES2065-1", "ACES - ACEScct", config=config

89 ... )

90 array([ 0.4135884..., 0.4135884..., 0.4135884...])

91 >>> a = np.array([[0.18, 0.18, 0.18]])

92 >>> process_image_OpenColorIO( # doctest: +SKIP

93 ... a, "ACES - ACES2065-1", "ACES - ACEScct", config=config

94 ... )

95 array([[ 0.4135884..., 0.4135884..., 0.4135884...]])

96 >>> a = np.array([[[0.18, 0.18, 0.18]]])

97 >>> process_image_OpenColorIO( # doctest: +SKIP

98 ... a, "ACES - ACES2065-1", "ACES - ACEScct", config=config

99 ... )

100 array([[[ 0.4135884..., 0.4135884..., 0.4135884...]]])

101 >>> a = full([4, 2, 3], 0.18)

102 >>> process_image_OpenColorIO( # doctest: +SKIP

103 ... a, "ACES - ACES2065-1", "ACES - ACEScct", config=config

104 ... )

105 array([[[ 0.4135884..., 0.4135884..., 0.4135884...],

106 [ 0.4135884..., 0.4135884..., 0.4135884...]],

107 <BLANKLINE>

108 [[ 0.4135884..., 0.4135884..., 0.4135884...],

109 [ 0.4135884..., 0.4135884..., 0.4135884...]],

110 <BLANKLINE>

111 [[ 0.4135884..., 0.4135884..., 0.4135884...],

112 [ 0.4135884..., 0.4135884..., 0.4135884...]],

113 <BLANKLINE>

114 [[ 0.4135884..., 0.4135884..., 0.4135884...],

115 [ 0.4135884..., 0.4135884..., 0.4135884...]]])

116 >>> process_image_OpenColorIO( # doctest: +SKIP

117 ... a,

118 ... "ACES - ACES2065-1",

119 ... "Display - sRGB",

120 ... "Output - SDR Video - ACES 1.0",

121 ... ocio.TRANSFORM_DIR_FORWARD,

122 ... config=config,

123 ... )

124 array([[[ 0.3559542..., 0.3559542..., 0.3559542...],

125 [ 0.3559542..., 0.3559542..., 0.3559542...]],

126 <BLANKLINE>

127 [[ 0.3559542..., 0.3559542..., 0.3559542...],

128 [ 0.3559542..., 0.3559542..., 0.3559542...]],

129 <BLANKLINE>

130 [[ 0.3559542..., 0.3559542..., 0.3559542...],

131 [ 0.3559542..., 0.3559542..., 0.3559542...]],

132 <BLANKLINE>

133 [[ 0.3559542..., 0.3559542..., 0.3559542...],

134 [ 0.3559542..., 0.3559542..., 0.3559542...]]])

135 """

136

137 import PyOpenColorIO as ocio # noqa: PLC0415

138

139 config = kwargs.get("config")

140 config = (

141 ocio.Config.CreateFromEnv() # pyright: ignore

142 if config is None

143 else ocio.Config.CreateFromFile(config) # pyright: ignore

144 )

145

146 a = as_float_array(a)

147 shape, dtype = a.shape, a.dtype

148 a = as_3_channels_image(a).astype(np.float32)

149

150 height, width, channels = a.shape

151

152 processor = config.getProcessor(*args).getDefaultCPUProcessor()

153

154 image_desc = ocio.PackedImageDesc( # pyright: ignore

155 a, width, height, channels

156 )

157

158 processor.apply(image_desc)

159

160 b = np.reshape(image_desc.getData(), (height, width, channels)).astype(dtype)

161

162 if len(shape) == 0:

163 return as_float(np.squeeze(b)[0])

164

165 if shape[-1] == 1:

166 return np.reshape(b[..., 0], shape)

167

168 return np.reshape(b, shape)