|
@@ -3,60 +3,7 @@ from collections import namedtuple
|
|
|
|
|
|
from PIL import Image
|
|
from PIL import Image
|
|
|
|
|
|
-
|
|
|
|
-def rescale_and_linearize(component: int) -> float:
|
|
|
|
- # takes an sRGB color component [0,255]
|
|
|
|
- # first rescales to [0,1]
|
|
|
|
- # then linearizes according to some CIEXYZ stuff I don't understand
|
|
|
|
- # then rescales to [0, 100]
|
|
|
|
- component /= 255
|
|
|
|
- linearized = component / 12.92 if component <= 0.04045 else ((component + 0.055) / 1.055) ** 2.4
|
|
|
|
- return 100 * linearized
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-# conversion values I also do not understand
|
|
|
|
-# pulled from https://www.image-engineering.de/library/technotes/958-how-to-convert-between-srgb-and-ciexyz
|
|
|
|
-# instead of easy rgb, since it seemed to give more accurate values
|
|
|
|
-rgb_to_xyz_matrix = [
|
|
|
|
- [0.4124564, 0.3575761, 0.1804375],
|
|
|
|
- [0.2126729, 0.7151522, 0.0721750],
|
|
|
|
- [0.0193339, 0.1191920, 0.9503041],
|
|
|
|
-]
|
|
|
|
-
|
|
|
|
-# reference values I also also do not understand
|
|
|
|
-# pulled from easy rgb
|
|
|
|
-# note X and Y here have nothing to do with the X and Y metrics below
|
|
|
|
-ref_x = 95.047
|
|
|
|
-ref_y = 100.000
|
|
|
|
-ref_z = 108.883
|
|
|
|
-ref_denom = ref_x + 15 * ref_y + 3 * ref_z
|
|
|
|
-ref_u = 4 * ref_x / ref_denom
|
|
|
|
-ref_v = 9 * ref_y / ref_denom
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-def rgb_to_cieluv(r: int, g: int, b: int) -> tuple[float, float, float]:
|
|
|
|
- # accepts RGB (components [0, 255])
|
|
|
|
- # converts to CIE LUV (components [0, 1])
|
|
|
|
- # math taken from http://www.easyrgb.com/en/math.php
|
|
|
|
-
|
|
|
|
- # RGB (components [0, 255]) -> XYZ (components [0, 100])
|
|
|
|
- # X, Y and Z output refer to a D65/2° standard illuminant.
|
|
|
|
- sr, sg, sb = (rescale_and_linearize(c) for c in (r, g, b))
|
|
|
|
- x, y, z = (cr * sr + cg * sg + cb * sb for cr, cg, cb in rgb_to_xyz_matrix)
|
|
|
|
-
|
|
|
|
- # XYZ (components [0, 100]) -> LUV (components [0, 100])
|
|
|
|
- uv_denom = x + 15 * y + 3 * z
|
|
|
|
- u = 4 * x / uv_denom
|
|
|
|
- v = 9 * y / uv_denom
|
|
|
|
-
|
|
|
|
- if y > 0.8856:
|
|
|
|
- yprime = (y / 100) ** (1/3)
|
|
|
|
- else:
|
|
|
|
- yprime = (y / 100) * 7.787 + (16/116)
|
|
|
|
-
|
|
|
|
- lstar = 116 * yprime - 16
|
|
|
|
- lstar_factor = 13 * lstar
|
|
|
|
- return lstar, lstar_factor * (u - ref_u), lstar_factor * (v - ref_v)
|
|
|
|
|
|
+from convert import rgb_to_cieluv
|
|
|
|
|
|
|
|
|
|
def is_outline(r: int, g: int, b: int, a: int) -> bool:
|
|
def is_outline(r: int, g: int, b: int, a: int) -> bool:
|