|
7 | 7 | Implementation is based on: |
8 | 8 | https://github.com/scikit-image/scikit-image/blob/00177e14097237ef20ed3141ed454bc81b308f82/skimage/color/colorconv.py#L704 |
9 | 9 | """ |
10 | | -def lab2rgb(lab): |
11 | | - lab = lab.astype("float32") |
| 10 | +def lab2rgb(lab: np.ndarray) -> np.ndarray: |
| 11 | + """ |
| 12 | + Convert an array of LAB values to RGB values. |
| 13 | +
|
| 14 | + Args: |
| 15 | + lab (np.ndarray): An array of shape (..., 3) containing LAB values. |
| 16 | +
|
| 17 | + Returns: |
| 18 | + np.ndarray: An array of shape (..., 3) containing RGB values. |
| 19 | + """ |
12 | 20 | # first rescale back from OpenCV format |
13 | 21 | lab[..., 0] /= 2.55 |
14 | | - lab[..., 1] -= 128 |
15 | | - lab[..., 2] -= 128 |
| 22 | + lab[..., 1:] -= 128 |
16 | 23 |
|
17 | 24 | # convert LAB -> XYZ color domain |
18 | | - L, a, b = lab[..., 0], lab[..., 1], lab[..., 2] |
19 | | - y = (L + 16.) / 116. |
20 | | - x = (a / 500.) + y |
21 | | - z = y - (b / 200.) |
| 25 | + y = (lab[..., 0] + 16.) / 116. |
| 26 | + x = (lab[..., 1] / 500.) + y |
| 27 | + z = y - (lab[..., 2] / 200.) |
22 | 28 |
|
23 | | - out = np.stack([x, y, z], axis=-1) |
| 29 | + xyz = np.stack([x, y, z], axis=-1) |
24 | 30 |
|
25 | | - mask = out > 0.2068966 |
26 | | - out[mask] = np.power(out[mask], 3.) |
27 | | - out[~mask] = (out[~mask] - 16.0 / 116.) / 7.787 |
| 31 | + mask = xyz > 0.2068966 |
| 32 | + xyz[mask] = np.power(xyz[mask], 3.) |
| 33 | + xyz[~mask] = (xyz[~mask] - 16.0 / 116.) / 7.787 |
28 | 34 |
|
29 | 35 | # rescale to the reference white (illuminant) |
30 | | - out *= np.array((0.95047, 1., 1.08883), dtype=out.dtype) |
31 | | - |
| 36 | + xyz *= np.array((0.95047, 1., 1.08883), dtype=xyz.dtype) |
| 37 | + |
32 | 38 | # convert XYZ -> RGB color domain |
33 | | - arr = out.copy() |
34 | | - arr = np.dot(arr, _xyz2rgb.T) |
35 | | - mask = arr > 0.0031308 |
36 | | - arr[mask] = 1.055 * np.power(arr[mask], 1 / 2.4) - 0.055 |
37 | | - arr[~mask] *= 12.92 |
38 | | - return np.clip(arr, 0, 1) |
| 39 | + rgb = np.matmul(xyz, _xyz2rgb.T) |
| 40 | + |
| 41 | + mask = rgb > 0.0031308 |
| 42 | + rgb[mask] = 1.055 * np.power(rgb[mask], 1 / 2.4) - 0.055 |
| 43 | + rgb[~mask] *= 12.92 |
| 44 | + |
| 45 | + return np.clip(rgb, 0, 1) |
0 commit comments