pixtreme 0.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pixtreme/__init__.py +198 -0
- pixtreme/color/__init__.py +62 -0
- pixtreme/color/aces/__init__.py +67 -0
- pixtreme/color/aces/encoding.py +186 -0
- pixtreme/color/aces/eotf.py +219 -0
- pixtreme/color/aces/matrix.py +198 -0
- pixtreme/color/aces/transform.py +143 -0
- pixtreme/color/bgr.py +44 -0
- pixtreme/color/grayscale.py +67 -0
- pixtreme/color/hsv.py +184 -0
- pixtreme/color/lut/__init__.py +54 -0
- pixtreme/color/lut/apply_lut.py +182 -0
- pixtreme/color/lut/read_lut.py +72 -0
- pixtreme/color/uyvy422.py +83 -0
- pixtreme/color/uyvy422_ndi.py +166 -0
- pixtreme/color/ycbcr.py +245 -0
- pixtreme/color/yuv420.py +114 -0
- pixtreme/color/yuv422p10le.py +69 -0
- pixtreme/draw/__init__.py +11 -0
- pixtreme/draw/mask.py +79 -0
- pixtreme/draw/shape.py +49 -0
- pixtreme/draw/text.py +118 -0
- pixtreme/filter/__init__.py +3 -0
- pixtreme/filter/gaussian.py +181 -0
- pixtreme/io/__init__.py +15 -0
- pixtreme/io/imdecode.py +40 -0
- pixtreme/io/imencode.py +50 -0
- pixtreme/io/imread.py +103 -0
- pixtreme/io/imshow.py +110 -0
- pixtreme/io/imwrite.py +72 -0
- pixtreme/py.typed +0 -0
- pixtreme/transform/__init__.py +46 -0
- pixtreme/transform/affine.py +131 -0
- pixtreme/transform/erode.py +134 -0
- pixtreme/transform/interpolation/area.py +192 -0
- pixtreme/transform/interpolation/bicubic.py +154 -0
- pixtreme/transform/interpolation/bilinear.py +113 -0
- pixtreme/transform/interpolation/lanczos.py +197 -0
- pixtreme/transform/interpolation/mitchell.py +189 -0
- pixtreme/transform/interpolation/nearest.py +95 -0
- pixtreme/transform/resize.py +167 -0
- pixtreme/transform/schema.py +11 -0
- pixtreme/transform/stack.py +42 -0
- pixtreme/transform/subsample.py +155 -0
- pixtreme/transform/subsample_flattened.py +207 -0
- pixtreme/transform/subsample_optimized_v2.py +231 -0
- pixtreme/transform/tile.py +116 -0
- pixtreme/upscale/__init__.py +9 -0
- pixtreme/upscale/onnx_upscaler.py +245 -0
- pixtreme/upscale/torch_upscaler.py +86 -0
- pixtreme/upscale/trt_upscaler.py +165 -0
- pixtreme/utils/__init__.py +35 -0
- pixtreme/utils/convert.py +623 -0
- pixtreme/utils/dimension.py +216 -0
- pixtreme/utils/dlpack.py +41 -0
- pixtreme/utils/dtypes.py +98 -0
- pixtreme-0.5.1.dist-info/METADATA +391 -0
- pixtreme-0.5.1.dist-info/RECORD +61 -0
- pixtreme-0.5.1.dist-info/WHEEL +4 -0
- pixtreme-0.5.1.dist-info/licenses/LICENSE +21 -0
- pixtreme-0.5.1.dist-info/licenses/third_party/aces/LICENSE_ACES.txt +50 -0
pixtreme/__init__.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import cupy as cp
|
|
2
|
+
|
|
3
|
+
from .color import (
|
|
4
|
+
aces2065_1_to_acescct,
|
|
5
|
+
aces2065_1_to_acescg,
|
|
6
|
+
aces2065_1_to_rec709,
|
|
7
|
+
acescct_to_aces2065_1,
|
|
8
|
+
acescg_to_aces2065_1,
|
|
9
|
+
apply_lut,
|
|
10
|
+
apply_lut_cp,
|
|
11
|
+
bgr_to_grayscale,
|
|
12
|
+
bgr_to_hsv,
|
|
13
|
+
bgr_to_rgb,
|
|
14
|
+
bgr_to_ycbcr,
|
|
15
|
+
hsv_to_bgr,
|
|
16
|
+
hsv_to_rgb,
|
|
17
|
+
ndi_uyvy422_to_ycbcr444,
|
|
18
|
+
ndi_uyvy422_to_ycbcr444_cp,
|
|
19
|
+
read_lut,
|
|
20
|
+
rec709_to_aces2065_1,
|
|
21
|
+
rgb_to_bgr,
|
|
22
|
+
rgb_to_grayscale,
|
|
23
|
+
rgb_to_hsv,
|
|
24
|
+
rgb_to_ycbcr,
|
|
25
|
+
uyvy422_to_ycbcr444,
|
|
26
|
+
uyvy422_to_ycbcr444_cp,
|
|
27
|
+
ycbcr_full_to_legal,
|
|
28
|
+
ycbcr_legal_to_full,
|
|
29
|
+
ycbcr_to_bgr,
|
|
30
|
+
ycbcr_to_grayscale,
|
|
31
|
+
ycbcr_to_rgb,
|
|
32
|
+
yuv420p_to_ycbcr444,
|
|
33
|
+
yuv420p_to_ycbcr444_cp,
|
|
34
|
+
yuv422p10le_to_ycbcr444,
|
|
35
|
+
yuv422p10le_to_ycbcr444_cp,
|
|
36
|
+
)
|
|
37
|
+
from .draw import add_label, circle, create_rounded_mask, put_text, rectangle
|
|
38
|
+
from .filter import GaussianBlur, gaussian_blur, get_gaussian_kernel
|
|
39
|
+
from .io import destroy_all_windows, imdecode, imencode, imread, imshow, imwrite, waitkey
|
|
40
|
+
from .transform import (
|
|
41
|
+
INTER_AREA,
|
|
42
|
+
INTER_AUTO,
|
|
43
|
+
INTER_B_SPLINE,
|
|
44
|
+
INTER_CATMULL_ROM,
|
|
45
|
+
INTER_CUBIC,
|
|
46
|
+
INTER_LANCZOS2,
|
|
47
|
+
INTER_LANCZOS3,
|
|
48
|
+
INTER_LANCZOS4,
|
|
49
|
+
INTER_LINEAR,
|
|
50
|
+
INTER_MITCHELL,
|
|
51
|
+
INTER_NEAREST,
|
|
52
|
+
add_padding,
|
|
53
|
+
affine_transform,
|
|
54
|
+
create_erode_kernel,
|
|
55
|
+
create_gaussian_weights,
|
|
56
|
+
erode,
|
|
57
|
+
get_inverse_matrix,
|
|
58
|
+
merge_tiles,
|
|
59
|
+
resize,
|
|
60
|
+
stack_images,
|
|
61
|
+
subsample_image,
|
|
62
|
+
subsample_image_back,
|
|
63
|
+
tile_image,
|
|
64
|
+
)
|
|
65
|
+
from .upscale import OnnxUpscaler, TorchUpscaler, TrtUpscaler
|
|
66
|
+
from .utils import (
|
|
67
|
+
batch_to_images,
|
|
68
|
+
check_onnx_model,
|
|
69
|
+
check_torch_model,
|
|
70
|
+
guess_image_layout,
|
|
71
|
+
image_to_batch,
|
|
72
|
+
images_to_batch,
|
|
73
|
+
onnx_to_onnx_dynamic,
|
|
74
|
+
onnx_to_trt,
|
|
75
|
+
onnx_to_trt_dynamic_shape,
|
|
76
|
+
onnx_to_trt_fixed_shape,
|
|
77
|
+
to_cupy,
|
|
78
|
+
to_dtype,
|
|
79
|
+
to_float16,
|
|
80
|
+
to_float32,
|
|
81
|
+
to_float64,
|
|
82
|
+
to_numpy,
|
|
83
|
+
to_tensor,
|
|
84
|
+
to_uint8,
|
|
85
|
+
to_uint16,
|
|
86
|
+
torch_to_onnx,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
get_device_id = cp.cuda.device.get_device_id
|
|
90
|
+
get_device_count = cp.cuda.runtime.getDeviceCount
|
|
91
|
+
Device = cp.cuda.Device
|
|
92
|
+
|
|
93
|
+
__all__ = [
|
|
94
|
+
# Color conversion functions
|
|
95
|
+
"aces2065_1_to_acescct",
|
|
96
|
+
"aces2065_1_to_acescg",
|
|
97
|
+
"aces2065_1_to_rec709",
|
|
98
|
+
"acescct_to_aces2065_1",
|
|
99
|
+
"acescg_to_aces2065_1",
|
|
100
|
+
"apply_lut",
|
|
101
|
+
"apply_lut_cp",
|
|
102
|
+
"bgr_to_grayscale",
|
|
103
|
+
"bgr_to_hsv",
|
|
104
|
+
"bgr_to_rgb",
|
|
105
|
+
"bgr_to_ycbcr",
|
|
106
|
+
"hsv_to_bgr",
|
|
107
|
+
"hsv_to_rgb",
|
|
108
|
+
"ndi_uyvy422_to_ycbcr444",
|
|
109
|
+
"ndi_uyvy422_to_ycbcr444_cp",
|
|
110
|
+
"read_lut",
|
|
111
|
+
"rec709_to_aces2065_1",
|
|
112
|
+
"rgb_to_bgr",
|
|
113
|
+
"rgb_to_grayscale",
|
|
114
|
+
"rgb_to_hsv",
|
|
115
|
+
"rgb_to_ycbcr",
|
|
116
|
+
"uyvy422_to_ycbcr444",
|
|
117
|
+
"uyvy422_to_ycbcr444_cp",
|
|
118
|
+
"ycbcr_full_to_legal",
|
|
119
|
+
"ycbcr_legal_to_full",
|
|
120
|
+
"ycbcr_to_bgr",
|
|
121
|
+
"ycbcr_to_grayscale",
|
|
122
|
+
"ycbcr_to_rgb",
|
|
123
|
+
"yuv420p_to_ycbcr444",
|
|
124
|
+
"yuv420p_to_ycbcr444_cp",
|
|
125
|
+
"yuv422p10le_to_ycbcr444",
|
|
126
|
+
"yuv422p10le_to_ycbcr444_cp",
|
|
127
|
+
# Drawing functions
|
|
128
|
+
"add_label",
|
|
129
|
+
"circle",
|
|
130
|
+
"create_rounded_mask",
|
|
131
|
+
"put_text",
|
|
132
|
+
"rectangle",
|
|
133
|
+
# Filtering
|
|
134
|
+
"GaussianBlur",
|
|
135
|
+
"gaussian_blur",
|
|
136
|
+
"get_gaussian_kernel",
|
|
137
|
+
# I/O operations
|
|
138
|
+
"destroy_all_windows",
|
|
139
|
+
"imdecode",
|
|
140
|
+
"imencode",
|
|
141
|
+
"imread",
|
|
142
|
+
"imshow",
|
|
143
|
+
"imwrite",
|
|
144
|
+
"waitkey",
|
|
145
|
+
# Transform operations
|
|
146
|
+
"INTER_AREA",
|
|
147
|
+
"INTER_AUTO",
|
|
148
|
+
"INTER_B_SPLINE",
|
|
149
|
+
"INTER_CATMULL_ROM",
|
|
150
|
+
"INTER_CUBIC",
|
|
151
|
+
"INTER_LANCZOS2",
|
|
152
|
+
"INTER_LANCZOS3",
|
|
153
|
+
"INTER_LANCZOS4",
|
|
154
|
+
"INTER_LINEAR",
|
|
155
|
+
"INTER_MITCHELL",
|
|
156
|
+
"INTER_NEAREST",
|
|
157
|
+
"affine_transform",
|
|
158
|
+
"create_erode_kernel",
|
|
159
|
+
"erode",
|
|
160
|
+
"get_inverse_matrix",
|
|
161
|
+
"resize",
|
|
162
|
+
"stack_images",
|
|
163
|
+
"subsample_image",
|
|
164
|
+
"subsample_image_back",
|
|
165
|
+
# Upscaling
|
|
166
|
+
"OnnxUpscaler",
|
|
167
|
+
"TorchUpscaler",
|
|
168
|
+
"TrtUpscaler",
|
|
169
|
+
"add_padding",
|
|
170
|
+
"create_gaussian_weights",
|
|
171
|
+
"merge_tiles",
|
|
172
|
+
"tile_image",
|
|
173
|
+
# Utilities
|
|
174
|
+
"check_onnx_model",
|
|
175
|
+
"check_torch_model",
|
|
176
|
+
"torch_to_onnx",
|
|
177
|
+
"onnx_to_onnx_dynamic",
|
|
178
|
+
"onnx_to_trt",
|
|
179
|
+
"onnx_to_trt_dynamic_shape",
|
|
180
|
+
"onnx_to_trt_fixed_shape",
|
|
181
|
+
"batch_to_images",
|
|
182
|
+
"image_to_batch",
|
|
183
|
+
"images_to_batch",
|
|
184
|
+
"guess_image_layout",
|
|
185
|
+
"to_cupy",
|
|
186
|
+
"to_dtype",
|
|
187
|
+
"to_float16",
|
|
188
|
+
"to_float32",
|
|
189
|
+
"to_float64",
|
|
190
|
+
"to_numpy",
|
|
191
|
+
"to_tensor",
|
|
192
|
+
"to_uint8",
|
|
193
|
+
"to_uint16",
|
|
194
|
+
# Device functions
|
|
195
|
+
"Device",
|
|
196
|
+
"get_device_count",
|
|
197
|
+
"get_device_id",
|
|
198
|
+
]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from .aces import (
|
|
2
|
+
aces2065_1_to_acescct,
|
|
3
|
+
aces2065_1_to_acescg,
|
|
4
|
+
aces2065_1_to_rec709,
|
|
5
|
+
acescct_to_aces2065_1,
|
|
6
|
+
acescg_to_aces2065_1,
|
|
7
|
+
rec709_to_aces2065_1,
|
|
8
|
+
)
|
|
9
|
+
from .bgr import bgr_to_rgb, rgb_to_bgr
|
|
10
|
+
from .grayscale import bgr_to_grayscale, rgb_to_grayscale
|
|
11
|
+
from .hsv import bgr_to_hsv, hsv_to_bgr, hsv_to_rgb, rgb_to_hsv
|
|
12
|
+
from .lut import apply_lut, read_lut
|
|
13
|
+
from .uyvy422 import uyvy422_to_ycbcr444
|
|
14
|
+
from .uyvy422_ndi import ndi_uyvy422_to_ycbcr444
|
|
15
|
+
from .ycbcr import (
|
|
16
|
+
bgr_to_ycbcr,
|
|
17
|
+
rgb_to_ycbcr,
|
|
18
|
+
ycbcr_full_to_legal,
|
|
19
|
+
ycbcr_legal_to_full,
|
|
20
|
+
ycbcr_to_bgr,
|
|
21
|
+
ycbcr_to_grayscale,
|
|
22
|
+
ycbcr_to_rgb,
|
|
23
|
+
)
|
|
24
|
+
from .yuv420 import yuv420p_to_ycbcr444
|
|
25
|
+
from .yuv422p10le import yuv422p10le_to_ycbcr444
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
# ACES color management
|
|
29
|
+
"aces2065_1_to_acescct",
|
|
30
|
+
"aces2065_1_to_acescg",
|
|
31
|
+
"aces2065_1_to_rec709",
|
|
32
|
+
"acescct_to_aces2065_1",
|
|
33
|
+
"acescg_to_aces2065_1",
|
|
34
|
+
"rec709_to_aces2065_1",
|
|
35
|
+
# 3D LUT operations
|
|
36
|
+
"apply_lut",
|
|
37
|
+
"read_lut",
|
|
38
|
+
# BGR/RGB conversions
|
|
39
|
+
"bgr_to_rgb",
|
|
40
|
+
"rgb_to_bgr",
|
|
41
|
+
# Grayscale conversions
|
|
42
|
+
"bgr_to_grayscale",
|
|
43
|
+
"rgb_to_grayscale",
|
|
44
|
+
# HSV conversions
|
|
45
|
+
"bgr_to_hsv",
|
|
46
|
+
"hsv_to_bgr",
|
|
47
|
+
"hsv_to_rgb",
|
|
48
|
+
"rgb_to_hsv",
|
|
49
|
+
# YCbCr conversions
|
|
50
|
+
"bgr_to_ycbcr",
|
|
51
|
+
"rgb_to_ycbcr",
|
|
52
|
+
"ycbcr_full_to_legal",
|
|
53
|
+
"ycbcr_legal_to_full",
|
|
54
|
+
"ycbcr_to_bgr",
|
|
55
|
+
"ycbcr_to_grayscale",
|
|
56
|
+
"ycbcr_to_rgb",
|
|
57
|
+
# Video format conversions
|
|
58
|
+
"uyvy422_to_ycbcr444",
|
|
59
|
+
"ndi_uyvy422_to_ycbcr444",
|
|
60
|
+
"yuv420p_to_ycbcr444",
|
|
61
|
+
"yuv422p10le_to_ycbcr444",
|
|
62
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ACES Color Management
|
|
3
|
+
|
|
4
|
+
Provides ACES 1.2 color transformations following Nuke/VFX industry standards.
|
|
5
|
+
|
|
6
|
+
This package implements the Academy Color Encoding System (ACES), a color management
|
|
7
|
+
framework developed by the Academy of Motion Picture Arts and Sciences. The implementation
|
|
8
|
+
follows the ACES 1.2 standard and is compatible with industry-standard VFX applications
|
|
9
|
+
like Nuke, Houdini, and Maya.
|
|
10
|
+
|
|
11
|
+
Main Modules
|
|
12
|
+
------------
|
|
13
|
+
transform : High-level IDT/ODT functions
|
|
14
|
+
rec709_to_aces2065_1 : Rec.709 → ACES2065-1 (Default IDT)
|
|
15
|
+
aces2065_1_to_rec709 : ACES2065-1 → Rec.709 (Default ODT)
|
|
16
|
+
|
|
17
|
+
encoding : ACES color space conversions
|
|
18
|
+
aces2065_1_to_acescct : ACES2065-1 → ACEScct (log-encoded AP1)
|
|
19
|
+
acescct_to_aces2065_1 : ACEScct → ACES2065-1
|
|
20
|
+
aces2065_1_to_acescg : ACES2065-1 → ACEScg (linear AP1)
|
|
21
|
+
acescg_to_aces2065_1 : ACEScg → ACES2065-1
|
|
22
|
+
|
|
23
|
+
matrix : Low-level matrix transformations
|
|
24
|
+
eotf : Transfer functions (gamma encoding/decoding)
|
|
25
|
+
|
|
26
|
+
Workflow
|
|
27
|
+
--------
|
|
28
|
+
The default workflow follows the "Utility - sRGB - Texture" IDT approach:
|
|
29
|
+
|
|
30
|
+
1. Input: Display-referred content (textures, graphics, graded footage)
|
|
31
|
+
2. IDT: rec709_to_aces2065_1() - Gamma decode + matrix transform
|
|
32
|
+
3. Working space: ACES2065-1 (AP0, linear) or ACEScg (AP1, linear)
|
|
33
|
+
4. ODT: aces2065_1_to_rec709() - Matrix transform + gamma encode
|
|
34
|
+
5. Output: Display-ready Rec.709 content
|
|
35
|
+
|
|
36
|
+
White Level
|
|
37
|
+
-----------
|
|
38
|
+
This implementation maintains normalized white levels (≈1.0) for display-referred
|
|
39
|
+
content, which is the standard for CG/VFX workflows. This differs from some video
|
|
40
|
+
workflows that use elevated white levels (≈16.3) for scene-referred content.
|
|
41
|
+
|
|
42
|
+
References
|
|
43
|
+
----------
|
|
44
|
+
- ACES Project: https://acescentral.com
|
|
45
|
+
- ACES Technical Documentation: https://docs.acescentral.com
|
|
46
|
+
- OpenColorIO ACES Configs: https://github.com/AcademySoftwareFoundation/OpenColorIO-Config-ACES
|
|
47
|
+
- SMPTE ST 2065-1: ACES2065-1 specification
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
from .encoding import (
|
|
51
|
+
aces2065_1_to_acescct,
|
|
52
|
+
aces2065_1_to_acescg,
|
|
53
|
+
acescct_to_aces2065_1,
|
|
54
|
+
acescg_to_aces2065_1,
|
|
55
|
+
)
|
|
56
|
+
from .transform import aces2065_1_to_rec709, rec709_to_aces2065_1
|
|
57
|
+
|
|
58
|
+
__all__ = [
|
|
59
|
+
# Main IDT/ODT
|
|
60
|
+
"rec709_to_aces2065_1",
|
|
61
|
+
"aces2065_1_to_rec709",
|
|
62
|
+
# Color space conversions
|
|
63
|
+
"aces2065_1_to_acescct",
|
|
64
|
+
"acescct_to_aces2065_1",
|
|
65
|
+
"aces2065_1_to_acescg",
|
|
66
|
+
"acescg_to_aces2065_1",
|
|
67
|
+
]
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ACES log encoding and color space transformations (ACEScct, ACEScg).
|
|
3
|
+
|
|
4
|
+
ACEScg (AP1):
|
|
5
|
+
Linear working space for CG/VFX, using AP1 primaries.
|
|
6
|
+
|
|
7
|
+
ACEScct (AP1 Log):
|
|
8
|
+
Log-encoded version of ACEScg, commonly used in color grading.
|
|
9
|
+
Uses a log curve optimized for grading controls.
|
|
10
|
+
|
|
11
|
+
References:
|
|
12
|
+
- SMPTE S-2016-001: ACEScg specification
|
|
13
|
+
- Academy TB-2014-004: ACEScct specification
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import cupy as cp
|
|
17
|
+
import numpy as np
|
|
18
|
+
|
|
19
|
+
from ...utils.dlpack import to_cupy
|
|
20
|
+
from ...utils.dtypes import to_float32
|
|
21
|
+
|
|
22
|
+
# AP0 (ACES2065-1) ↔ AP1 (ACEScg) transformation matrices
|
|
23
|
+
ap0_to_ap1_matrix = cp.array(
|
|
24
|
+
[
|
|
25
|
+
[1.4514393161, -0.2365107469, -0.2149285693],
|
|
26
|
+
[-0.0765537734, 1.1762296998, -0.0996759264],
|
|
27
|
+
[0.0083161484, -0.0060324498, 0.9977163014],
|
|
28
|
+
]
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
ap1_to_ap0_matrix = cp.array(
|
|
32
|
+
[
|
|
33
|
+
[0.6954522414, 0.1406786965, 0.1638690622],
|
|
34
|
+
[0.0447945634, 0.8596711185, 0.0955343182],
|
|
35
|
+
[-0.0055258826, 0.0040252103, 1.0015006723],
|
|
36
|
+
]
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def aces2065_1_to_acescct(image: cp.ndarray | np.ndarray) -> cp.ndarray | np.ndarray:
|
|
41
|
+
"""
|
|
42
|
+
Convert ACES2065-1 (AP0) to ACEScct (AP1 log-encoded).
|
|
43
|
+
|
|
44
|
+
ACEScct uses a log curve optimized for color grading, commonly used
|
|
45
|
+
in DaVinci Resolve and other grading applications.
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
image : cp.ndarray | np.ndarray
|
|
50
|
+
ACES2065-1 image (AP0, linear)
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
cp.ndarray | np.ndarray
|
|
55
|
+
ACEScct image (AP1, log-encoded)
|
|
56
|
+
"""
|
|
57
|
+
image = to_float32(image, clip=False)
|
|
58
|
+
|
|
59
|
+
# Remember input type
|
|
60
|
+
was_numpy = isinstance(image, np.ndarray)
|
|
61
|
+
|
|
62
|
+
# Convert to CuPy for processing
|
|
63
|
+
if was_numpy:
|
|
64
|
+
image = to_cupy(image)
|
|
65
|
+
|
|
66
|
+
# AP0 → AP1
|
|
67
|
+
ap1_image = cp.dot(image, ap0_to_ap1_matrix.T)
|
|
68
|
+
|
|
69
|
+
# Apply ACEScct log curve
|
|
70
|
+
acescct_image = cp.where(
|
|
71
|
+
ap1_image <= 0.0078125,
|
|
72
|
+
10.5402377416545 * ap1_image + 0.0729055341958355,
|
|
73
|
+
(cp.log2(ap1_image) + 9.72) / 17.52,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Convert back to original type
|
|
77
|
+
if was_numpy:
|
|
78
|
+
return cp.asnumpy(acescct_image)
|
|
79
|
+
return acescct_image
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def acescct_to_aces2065_1(image: cp.ndarray | np.ndarray) -> cp.ndarray | np.ndarray:
|
|
83
|
+
"""
|
|
84
|
+
Convert ACEScct (AP1 log-encoded) to ACES2065-1 (AP0).
|
|
85
|
+
|
|
86
|
+
Parameters
|
|
87
|
+
----------
|
|
88
|
+
image : cp.ndarray | np.ndarray
|
|
89
|
+
ACEScct image (AP1, log-encoded)
|
|
90
|
+
|
|
91
|
+
Returns
|
|
92
|
+
-------
|
|
93
|
+
cp.ndarray | np.ndarray
|
|
94
|
+
ACES2065-1 image (AP0, linear)
|
|
95
|
+
"""
|
|
96
|
+
image = to_float32(image, clip=False)
|
|
97
|
+
|
|
98
|
+
# Remember input type
|
|
99
|
+
was_numpy = isinstance(image, np.ndarray)
|
|
100
|
+
|
|
101
|
+
# Convert to CuPy for processing
|
|
102
|
+
if was_numpy:
|
|
103
|
+
image = to_cupy(image)
|
|
104
|
+
|
|
105
|
+
# Apply inverse ACEScct log curve
|
|
106
|
+
ap1_image = cp.where(
|
|
107
|
+
image <= 0.155251141552511,
|
|
108
|
+
(image - 0.0729055341958355) / 10.5402377416545,
|
|
109
|
+
cp.where(
|
|
110
|
+
image < cp.log2(65504),
|
|
111
|
+
2 ** ((image * 17.52) - 9.72),
|
|
112
|
+
65504,
|
|
113
|
+
),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# AP1 → AP0
|
|
117
|
+
ap0_image = cp.dot(ap1_image, ap1_to_ap0_matrix.T)
|
|
118
|
+
|
|
119
|
+
# Convert back to original type
|
|
120
|
+
if was_numpy:
|
|
121
|
+
return cp.asnumpy(ap0_image)
|
|
122
|
+
return ap0_image
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def aces2065_1_to_acescg(image: cp.ndarray | np.ndarray) -> cp.ndarray | np.ndarray:
|
|
126
|
+
"""
|
|
127
|
+
Convert ACES2065-1 (AP0) to ACEScg (AP1 linear).
|
|
128
|
+
|
|
129
|
+
ACEScg is the linear working space for CG/VFX using AP1 primaries.
|
|
130
|
+
|
|
131
|
+
Parameters
|
|
132
|
+
----------
|
|
133
|
+
image : cp.ndarray | np.ndarray
|
|
134
|
+
ACES2065-1 image (AP0, linear)
|
|
135
|
+
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
cp.ndarray | np.ndarray
|
|
139
|
+
ACEScg image (AP1, linear)
|
|
140
|
+
"""
|
|
141
|
+
image = to_float32(image, clip=False)
|
|
142
|
+
|
|
143
|
+
# Remember input type
|
|
144
|
+
was_numpy = isinstance(image, np.ndarray)
|
|
145
|
+
|
|
146
|
+
# Convert to CuPy for processing
|
|
147
|
+
if was_numpy:
|
|
148
|
+
image = to_cupy(image)
|
|
149
|
+
|
|
150
|
+
ap1_image = cp.dot(image, ap0_to_ap1_matrix.T)
|
|
151
|
+
|
|
152
|
+
# Convert back to original type
|
|
153
|
+
if was_numpy:
|
|
154
|
+
return cp.asnumpy(ap1_image)
|
|
155
|
+
return ap1_image
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def acescg_to_aces2065_1(image: cp.ndarray | np.ndarray) -> cp.ndarray | np.ndarray:
|
|
159
|
+
"""
|
|
160
|
+
Convert ACEScg (AP1 linear) to ACES2065-1 (AP0).
|
|
161
|
+
|
|
162
|
+
Parameters
|
|
163
|
+
----------
|
|
164
|
+
image : cp.ndarray | np.ndarray
|
|
165
|
+
ACEScg image (AP1, linear)
|
|
166
|
+
|
|
167
|
+
Returns
|
|
168
|
+
-------
|
|
169
|
+
cp.ndarray | np.ndarray
|
|
170
|
+
ACES2065-1 image (AP0, linear)
|
|
171
|
+
"""
|
|
172
|
+
image = to_float32(image, clip=False)
|
|
173
|
+
|
|
174
|
+
# Remember input type
|
|
175
|
+
was_numpy = isinstance(image, np.ndarray)
|
|
176
|
+
|
|
177
|
+
# Convert to CuPy for processing
|
|
178
|
+
if was_numpy:
|
|
179
|
+
image = to_cupy(image)
|
|
180
|
+
|
|
181
|
+
ap0_image = cp.dot(image, ap1_to_ap0_matrix.T)
|
|
182
|
+
|
|
183
|
+
# Convert back to original type
|
|
184
|
+
if was_numpy:
|
|
185
|
+
return cp.asnumpy(ap0_image)
|
|
186
|
+
return ap0_image
|