PyColorSpace 0.0.1__tar.gz
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.
- pycolorspace-0.0.1/LICENSE +0 -0
- pycolorspace-0.0.1/PKG-INFO +9 -0
- pycolorspace-0.0.1/pyproject.toml +9 -0
- pycolorspace-0.0.1/setup.cfg +4 -0
- pycolorspace-0.0.1/src/PyColorSpace/__init__.py +4 -0
- pycolorspace-0.0.1/src/PyColorSpace/hsv.py +0 -0
- pycolorspace-0.0.1/src/PyColorSpace/matrices/__init__.py +0 -0
- pycolorspace-0.0.1/src/PyColorSpace/matrices/bt2020.py +8 -0
- pycolorspace-0.0.1/src/PyColorSpace/matrices/bt601.py +7 -0
- pycolorspace-0.0.1/src/PyColorSpace/matrices/bt709.py +7 -0
- pycolorspace-0.0.1/src/PyColorSpace/rgb.py +174 -0
- pycolorspace-0.0.1/src/PyColorSpace/utils/__init__.py +2 -0
- pycolorspace-0.0.1/src/PyColorSpace/utils/get_rgb_to_yuv_matrix.py +53 -0
- pycolorspace-0.0.1/src/PyColorSpace/utils/get_yuv_to_rgb_matrix.py +52 -0
- pycolorspace-0.0.1/src/PyColorSpace/yuv.py +232 -0
- pycolorspace-0.0.1/src/PyColorSpace.egg-info/PKG-INFO +9 -0
- pycolorspace-0.0.1/src/PyColorSpace.egg-info/SOURCES.txt +19 -0
- pycolorspace-0.0.1/src/PyColorSpace.egg-info/dependency_links.txt +1 -0
- pycolorspace-0.0.1/src/PyColorSpace.egg-info/requires.txt +2 -0
- pycolorspace-0.0.1/src/PyColorSpace.egg-info/top_level.txt +1 -0
- pycolorspace-0.0.1/tests/test.py +9 -0
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import cv2
|
|
5
|
+
from .utils import get_rgb_to_yuv_matrix
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def rgb_to_yuv444(
|
|
9
|
+
rgb: np.ndarray,
|
|
10
|
+
*,
|
|
11
|
+
standard: str = "bt709",
|
|
12
|
+
bit_depth: int = 8,
|
|
13
|
+
normalized: bool = False,
|
|
14
|
+
input_layout: str = "HWC",
|
|
15
|
+
output_layout: str = "HWC",
|
|
16
|
+
output_range: str = "normalized",
|
|
17
|
+
output_dtype=None,
|
|
18
|
+
) -> np.ndarray:
|
|
19
|
+
"""
|
|
20
|
+
Convert an RGB image to YUV444.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
rgb : numpy.ndarray
|
|
25
|
+
Input RGB image.
|
|
26
|
+
|
|
27
|
+
Accepted layouts
|
|
28
|
+
----------------
|
|
29
|
+
- "HWC" : (H, W, 3)
|
|
30
|
+
- "CHW" : (3, H, W)
|
|
31
|
+
|
|
32
|
+
standard : {"bt601", "bt709", "bt2020"}, default="bt709"
|
|
33
|
+
Color conversion standard.
|
|
34
|
+
|
|
35
|
+
bit_depth : int, default=8
|
|
36
|
+
Bit depth used when normalized=False.
|
|
37
|
+
|
|
38
|
+
normalized : bool, default=False
|
|
39
|
+
If True, input RGB is assumed to be in [0,1].
|
|
40
|
+
|
|
41
|
+
If False, RGB is assumed to be integer-scaled according
|
|
42
|
+
to bit_depth.
|
|
43
|
+
|
|
44
|
+
input_layout : {"HWC","CHW"}, default="HWC"
|
|
45
|
+
|
|
46
|
+
output_layout : {"HWC","CHW"}, default="HWC"
|
|
47
|
+
|
|
48
|
+
output_range : {"normalized","integer"}, default="normalized"
|
|
49
|
+
|
|
50
|
+
output_dtype : numpy.dtype or None
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
numpy.ndarray
|
|
55
|
+
YUV444 image.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
# Validate
|
|
59
|
+
if not isinstance(rgb, np.ndarray):
|
|
60
|
+
raise TypeError("rgb must be a NumPy array.")
|
|
61
|
+
|
|
62
|
+
if input_layout not in ("HWC", "CHW"):
|
|
63
|
+
raise ValueError("input_layout must be 'HWC' or 'CHW'.")
|
|
64
|
+
|
|
65
|
+
if output_layout not in ("HWC", "CHW"):
|
|
66
|
+
raise ValueError("output_layout must be 'HWC' or 'CHW'.")
|
|
67
|
+
|
|
68
|
+
if output_range not in ("normalized", "integer"):
|
|
69
|
+
raise ValueError(
|
|
70
|
+
"output_range must be 'normalized' or 'integer'."
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Convert CHW -> HWC
|
|
74
|
+
if input_layout == "CHW":
|
|
75
|
+
rgb = np.transpose(rgb, (1, 2, 0))
|
|
76
|
+
|
|
77
|
+
if rgb.ndim != 3 or rgb.shape[-1] != 3:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
"Expected RGB image with shape (H, W, 3)."
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Normalize
|
|
83
|
+
rgb = rgb.astype(np.float32)
|
|
84
|
+
|
|
85
|
+
if not normalized:
|
|
86
|
+
max_value = (1 << bit_depth) - 1
|
|
87
|
+
rgb /= max_value
|
|
88
|
+
|
|
89
|
+
# RGB -> YUV
|
|
90
|
+
matrix = get_rgb_to_yuv_matrix(standard)
|
|
91
|
+
|
|
92
|
+
yuv = rgb @ matrix.T
|
|
93
|
+
|
|
94
|
+
# Shift chroma to [0,1]
|
|
95
|
+
yuv[..., 1:] += 0.5
|
|
96
|
+
|
|
97
|
+
# Clip
|
|
98
|
+
yuv = np.clip(yuv, 0.0, 1.0)
|
|
99
|
+
|
|
100
|
+
# Scale if requested
|
|
101
|
+
if output_range == "integer":
|
|
102
|
+
yuv *= (1 << bit_depth) - 1
|
|
103
|
+
|
|
104
|
+
# Cast
|
|
105
|
+
if output_dtype is not None:
|
|
106
|
+
yuv = yuv.astype(output_dtype)
|
|
107
|
+
|
|
108
|
+
# Layout
|
|
109
|
+
if output_layout == "CHW":
|
|
110
|
+
yuv = np.transpose(yuv, (2, 0, 1))
|
|
111
|
+
|
|
112
|
+
return yuv
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def rgb_to_yuv420(
|
|
117
|
+
rgb: np.ndarray,
|
|
118
|
+
*,
|
|
119
|
+
standard: str = "bt709",
|
|
120
|
+
bit_depth: int = 8,
|
|
121
|
+
normalized: bool = False,
|
|
122
|
+
input_layout: str = "HWC",
|
|
123
|
+
output_layout: str = "HWC",
|
|
124
|
+
output_range: str = "normalized",
|
|
125
|
+
output_dtype=None,
|
|
126
|
+
):
|
|
127
|
+
"""
|
|
128
|
+
Convert an RGB image to YUV420.
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
tuple
|
|
133
|
+
(Y, U420, V420)
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
# Convert RGB -> YUV444
|
|
137
|
+
yuv444 = rgb_to_yuv444(
|
|
138
|
+
rgb,
|
|
139
|
+
standard=standard,
|
|
140
|
+
bit_depth=bit_depth,
|
|
141
|
+
normalized=normalized,
|
|
142
|
+
input_layout=input_layout,
|
|
143
|
+
output_layout="HWC",
|
|
144
|
+
output_range=output_range,
|
|
145
|
+
output_dtype=output_dtype,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Split channels
|
|
149
|
+
Y = yuv444[..., 0]
|
|
150
|
+
U = yuv444[..., 1]
|
|
151
|
+
V = yuv444[..., 2]
|
|
152
|
+
|
|
153
|
+
height, width = Y.shape
|
|
154
|
+
|
|
155
|
+
# Bicubic chroma downsampling
|
|
156
|
+
U420 = cv2.resize(
|
|
157
|
+
U,
|
|
158
|
+
(width // 2, height // 2),
|
|
159
|
+
interpolation=cv2.INTER_CUBIC,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
V420 = cv2.resize(
|
|
163
|
+
V,
|
|
164
|
+
(width // 2, height // 2),
|
|
165
|
+
interpolation=cv2.INTER_CUBIC,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# Return requested layout
|
|
169
|
+
if output_layout == "CHW":
|
|
170
|
+
Y = Y[np.newaxis, ...]
|
|
171
|
+
U420 = U420[np.newaxis, ...]
|
|
172
|
+
V420 = V420[np.newaxis, ...]
|
|
173
|
+
|
|
174
|
+
return Y, U420, V420
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from ..matrices.bt601 import YUV_TO_RGB_BT601
|
|
4
|
+
from ..matrices.bt709 import YUV_TO_RGB_BT709
|
|
5
|
+
from ..matrices.bt2020 import YUV_TO_RGB_BT2020
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
RGB_TO_YUV_MATRICES = {
|
|
9
|
+
"bt601": np.linalg.inv(YUV_TO_RGB_BT601),
|
|
10
|
+
"bt709": np.linalg.inv(YUV_TO_RGB_BT709),
|
|
11
|
+
"bt2020": np.linalg.inv(YUV_TO_RGB_BT2020),
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_rgb_to_yuv_matrix(standard: str):
|
|
16
|
+
"""
|
|
17
|
+
Return the RGB -> YUV conversion matrix.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
standard : str
|
|
22
|
+
Color conversion standard.
|
|
23
|
+
|
|
24
|
+
Supported values
|
|
25
|
+
----------------
|
|
26
|
+
- "bt601"
|
|
27
|
+
- "bt709"
|
|
28
|
+
- "bt2020"
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
numpy.ndarray
|
|
33
|
+
3x3 RGB→YUV conversion matrix.
|
|
34
|
+
|
|
35
|
+
Raises
|
|
36
|
+
------
|
|
37
|
+
ValueError
|
|
38
|
+
If the requested standard is unsupported.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
if not isinstance(standard, str):
|
|
42
|
+
raise TypeError("standard must be a string.")
|
|
43
|
+
|
|
44
|
+
standard = standard.lower()
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
return RGB_TO_YUV_MATRICES[standard]
|
|
48
|
+
except KeyError:
|
|
49
|
+
supported = ", ".join(RGB_TO_YUV_MATRICES.keys())
|
|
50
|
+
raise ValueError(
|
|
51
|
+
f"Unsupported standard '{standard}'. "
|
|
52
|
+
f"Supported standards are: {supported}."
|
|
53
|
+
)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
from ..matrices.bt601 import YUV_TO_RGB_BT601
|
|
3
|
+
from ..matrices.bt709 import YUV_TO_RGB_BT709
|
|
4
|
+
from ..matrices.bt2020 import YUV_TO_RGB_BT2020
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
YUV_TO_RGB_MATRICES = {
|
|
8
|
+
"bt601": YUV_TO_RGB_BT601,
|
|
9
|
+
"bt709": YUV_TO_RGB_BT709,
|
|
10
|
+
"bt2020": YUV_TO_RGB_BT2020,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_yuv_to_rgb_matrix(standard: str):
|
|
15
|
+
"""
|
|
16
|
+
Return the YUV→RGB conversion matrix.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
standard : str
|
|
21
|
+
Color conversion standard.
|
|
22
|
+
|
|
23
|
+
Supported values
|
|
24
|
+
----------------
|
|
25
|
+
- "bt601"
|
|
26
|
+
- "bt709"
|
|
27
|
+
- "bt2020"
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
numpy.ndarray
|
|
32
|
+
3x3 YUV→RGB conversion matrix.
|
|
33
|
+
|
|
34
|
+
Raises
|
|
35
|
+
------
|
|
36
|
+
ValueError
|
|
37
|
+
If the requested standard is unsupported.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
if not isinstance(standard, str):
|
|
41
|
+
raise TypeError("standard must be a string.")
|
|
42
|
+
|
|
43
|
+
standard = standard.lower()
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
return YUV_TO_RGB_MATRICES[standard]
|
|
47
|
+
except KeyError:
|
|
48
|
+
supported = ", ".join(YUV_TO_RGB_MATRICES.keys())
|
|
49
|
+
raise ValueError(
|
|
50
|
+
f"Unsupported standard '{standard}'. "
|
|
51
|
+
f"Supported standards are: {supported}."
|
|
52
|
+
)
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
from .utils import get_yuv_to_rgb_matrix
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def yuv444_to_rgb(
|
|
7
|
+
yuv: np.ndarray,
|
|
8
|
+
*,
|
|
9
|
+
standard: str = "bt709",
|
|
10
|
+
bit_depth: int = 8,
|
|
11
|
+
normalized: bool = False,
|
|
12
|
+
input_layout: str = "HWC",
|
|
13
|
+
output_layout: str = "HWC",
|
|
14
|
+
output_range: str = "normalized",
|
|
15
|
+
output_dtype=None,
|
|
16
|
+
) -> np.ndarray:
|
|
17
|
+
"""
|
|
18
|
+
Convert a YUV444 image to RGB.
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
yuv : numpy.ndarray
|
|
23
|
+
Input YUV444 image.
|
|
24
|
+
|
|
25
|
+
Accepted layouts:
|
|
26
|
+
- "HWC" : (H, W, 3)
|
|
27
|
+
- "CHW" : (3, H, W)
|
|
28
|
+
|
|
29
|
+
standard : str, default="bt709"
|
|
30
|
+
Color conversion standard.
|
|
31
|
+
|
|
32
|
+
Supported values include:
|
|
33
|
+
- "bt601"
|
|
34
|
+
- "bt709"
|
|
35
|
+
- "bt2020"
|
|
36
|
+
|
|
37
|
+
bit_depth : int, default=8
|
|
38
|
+
Bit depth of the Y channel and chroma channels.
|
|
39
|
+
Used only when ``normalized=False``.
|
|
40
|
+
|
|
41
|
+
Examples
|
|
42
|
+
--------
|
|
43
|
+
8 -> values in [0, 255]
|
|
44
|
+
|
|
45
|
+
10 -> values in [0, 1023]
|
|
46
|
+
|
|
47
|
+
12 -> values in [0, 4095]
|
|
48
|
+
|
|
49
|
+
normalized : bool, default=False
|
|
50
|
+
If True, the input image is assumed to be normalized
|
|
51
|
+
to the range [0, 1].
|
|
52
|
+
|
|
53
|
+
If False, values are assumed to be integer-scaled
|
|
54
|
+
according to ``bit_depth``.
|
|
55
|
+
|
|
56
|
+
input_layout : {"HWC", "CHW"}, default="HWC"
|
|
57
|
+
Memory layout of the input image.
|
|
58
|
+
|
|
59
|
+
output_layout : {"HWC", "CHW"}, default="HWC"
|
|
60
|
+
Desired layout of the returned RGB image.
|
|
61
|
+
|
|
62
|
+
output_range : {"normalized", "integer"}, default="normalized"
|
|
63
|
+
|
|
64
|
+
"normalized"
|
|
65
|
+
Returns RGB in [0,1].
|
|
66
|
+
|
|
67
|
+
"integer"
|
|
68
|
+
Returns RGB scaled to the selected bit depth.
|
|
69
|
+
|
|
70
|
+
output_dtype : numpy.dtype or None, default=None
|
|
71
|
+
Desired output dtype.
|
|
72
|
+
|
|
73
|
+
Examples
|
|
74
|
+
--------
|
|
75
|
+
np.float32
|
|
76
|
+
|
|
77
|
+
np.float64
|
|
78
|
+
|
|
79
|
+
np.uint8
|
|
80
|
+
|
|
81
|
+
np.uint16
|
|
82
|
+
|
|
83
|
+
If None, an appropriate dtype is chosen automatically.
|
|
84
|
+
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
numpy.ndarray
|
|
88
|
+
RGB image.
|
|
89
|
+
|
|
90
|
+
Raises
|
|
91
|
+
------
|
|
92
|
+
ValueError
|
|
93
|
+
If an invalid layout, range, or standard is supplied.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
# Validate image
|
|
97
|
+
if not isinstance(yuv, np.ndarray):
|
|
98
|
+
raise TypeError("yuv must be a NumPy array.")
|
|
99
|
+
|
|
100
|
+
if input_layout not in ("HWC", "CHW"):
|
|
101
|
+
raise ValueError("input_layout must be 'HWC' or 'CHW'.")
|
|
102
|
+
|
|
103
|
+
if output_layout not in ("HWC", "CHW"):
|
|
104
|
+
raise ValueError("output_layout must be 'HWC' or 'CHW'.")
|
|
105
|
+
|
|
106
|
+
if output_range not in ("normalized", "integer"):
|
|
107
|
+
raise ValueError(
|
|
108
|
+
"output_range must be 'normalized' or 'integer'."
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Convert CHW -> HWC
|
|
112
|
+
if input_layout == "CHW":
|
|
113
|
+
yuv = np.transpose(yuv, (1, 2, 0))
|
|
114
|
+
|
|
115
|
+
if yuv.ndim != 3 or yuv.shape[-1] != 3:
|
|
116
|
+
raise ValueError(
|
|
117
|
+
"Expected YUV image with shape (H, W, 3)."
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Normalize input
|
|
121
|
+
yuv = yuv.astype(np.float32)
|
|
122
|
+
|
|
123
|
+
if not normalized:
|
|
124
|
+
max_value = (1 << bit_depth) - 1
|
|
125
|
+
yuv /= max_value
|
|
126
|
+
|
|
127
|
+
# Split channels and center the chroma
|
|
128
|
+
Y = yuv[..., 0]
|
|
129
|
+
U = yuv[..., 1] - 0.5
|
|
130
|
+
V = yuv[..., 2] - 0.5
|
|
131
|
+
|
|
132
|
+
# Load conversion matrix
|
|
133
|
+
matrix = get_yuv_to_rgb_matrix(standard)
|
|
134
|
+
|
|
135
|
+
# matrix should be 3x3
|
|
136
|
+
rgb = np.stack((Y, U, V), axis=-1)
|
|
137
|
+
rgb = rgb @ matrix.T
|
|
138
|
+
|
|
139
|
+
# Clip
|
|
140
|
+
rgb = np.clip(rgb, 0.0, 1.0)
|
|
141
|
+
|
|
142
|
+
# Output scaling
|
|
143
|
+
if output_range == "integer":
|
|
144
|
+
rgb *= (1 << bit_depth) - 1
|
|
145
|
+
|
|
146
|
+
# Output dtype
|
|
147
|
+
if output_dtype is not None:
|
|
148
|
+
rgb = rgb.astype(output_dtype)
|
|
149
|
+
|
|
150
|
+
# Convert back to CHW if requested
|
|
151
|
+
if output_layout == "CHW":
|
|
152
|
+
rgb = np.transpose(rgb, (2, 0, 1))
|
|
153
|
+
|
|
154
|
+
return rgb
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def yuv420_to_rgb(
|
|
161
|
+
y: np.ndarray,
|
|
162
|
+
u: np.ndarray,
|
|
163
|
+
v: np.ndarray,
|
|
164
|
+
*,
|
|
165
|
+
standard: str = "bt709",
|
|
166
|
+
bit_depth: int = 8,
|
|
167
|
+
normalized: bool = False,
|
|
168
|
+
input_layout: str = "HWC",
|
|
169
|
+
output_layout: str = "HWC",
|
|
170
|
+
output_range: str = "normalized",
|
|
171
|
+
output_dtype=None,
|
|
172
|
+
) -> np.ndarray:
|
|
173
|
+
"""
|
|
174
|
+
Convert a YUV420 image to RGB.
|
|
175
|
+
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
y : numpy.ndarray
|
|
179
|
+
Luma plane.
|
|
180
|
+
|
|
181
|
+
u : numpy.ndarray
|
|
182
|
+
Chroma-U plane (subsampled 2x).
|
|
183
|
+
|
|
184
|
+
v : numpy.ndarray
|
|
185
|
+
Chroma-V plane (subsampled 2x).
|
|
186
|
+
|
|
187
|
+
Other Parameters
|
|
188
|
+
----------------
|
|
189
|
+
Same as yuv444_to_rgb().
|
|
190
|
+
|
|
191
|
+
Returns
|
|
192
|
+
-------
|
|
193
|
+
numpy.ndarray
|
|
194
|
+
RGB image.
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
# Convert CHW -> HWC if necessary
|
|
198
|
+
if input_layout == "CHW":
|
|
199
|
+
if y.ndim == 3:
|
|
200
|
+
y = y[0]
|
|
201
|
+
|
|
202
|
+
if u.ndim == 3:
|
|
203
|
+
u = u[0]
|
|
204
|
+
|
|
205
|
+
if v.ndim == 3:
|
|
206
|
+
v = v[0]
|
|
207
|
+
|
|
208
|
+
# Validate
|
|
209
|
+
if y.shape[0] != u.shape[0] * 2 or y.shape[1] != u.shape[1] * 2:
|
|
210
|
+
raise ValueError("U plane size is inconsistent with Y plane.")
|
|
211
|
+
|
|
212
|
+
if y.shape[0] != v.shape[0] * 2 or y.shape[1] != v.shape[1] * 2:
|
|
213
|
+
raise ValueError("V plane size is inconsistent with Y plane.")
|
|
214
|
+
|
|
215
|
+
# Upsample U and V (nearest neighbour)
|
|
216
|
+
u = np.repeat(np.repeat(u, 2, axis=0), 2, axis=1)
|
|
217
|
+
v = np.repeat(np.repeat(v, 2, axis=0), 2, axis=1)
|
|
218
|
+
|
|
219
|
+
# Build YUV444
|
|
220
|
+
yuv444 = np.stack((y, u, v), axis=-1)
|
|
221
|
+
|
|
222
|
+
# Reuse the YUV444 conversion
|
|
223
|
+
return yuv444_to_rgb(
|
|
224
|
+
yuv444,
|
|
225
|
+
standard=standard,
|
|
226
|
+
bit_depth=bit_depth,
|
|
227
|
+
normalized=normalized,
|
|
228
|
+
input_layout="HWC",
|
|
229
|
+
output_layout=output_layout,
|
|
230
|
+
output_range=output_range,
|
|
231
|
+
output_dtype=output_dtype,
|
|
232
|
+
)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/PyColorSpace/__init__.py
|
|
4
|
+
src/PyColorSpace/hsv.py
|
|
5
|
+
src/PyColorSpace/rgb.py
|
|
6
|
+
src/PyColorSpace/yuv.py
|
|
7
|
+
src/PyColorSpace.egg-info/PKG-INFO
|
|
8
|
+
src/PyColorSpace.egg-info/SOURCES.txt
|
|
9
|
+
src/PyColorSpace.egg-info/dependency_links.txt
|
|
10
|
+
src/PyColorSpace.egg-info/requires.txt
|
|
11
|
+
src/PyColorSpace.egg-info/top_level.txt
|
|
12
|
+
src/PyColorSpace/matrices/__init__.py
|
|
13
|
+
src/PyColorSpace/matrices/bt2020.py
|
|
14
|
+
src/PyColorSpace/matrices/bt601.py
|
|
15
|
+
src/PyColorSpace/matrices/bt709.py
|
|
16
|
+
src/PyColorSpace/utils/__init__.py
|
|
17
|
+
src/PyColorSpace/utils/get_rgb_to_yuv_matrix.py
|
|
18
|
+
src/PyColorSpace/utils/get_yuv_to_rgb_matrix.py
|
|
19
|
+
tests/test.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PyColorSpace
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
import PyColorSpace as pcs
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
patch_path = "/home/anukulmaity/nvme1n/Frame_Extraction/Milestone 2/M2 Patch Extractions/Datasets/New_Image_Dataset/Div2k/Div2k_patches/Patches/DIV2K__036_001.npy"
|
|
6
|
+
yuv = np.load(patch_path)
|
|
7
|
+
|
|
8
|
+
rgb = pcs.yuv444_to_rgb(yuv, input_layout="CHW", output_layout="CHW")
|
|
9
|
+
print(rgb.shape)
|