Prechádzať zdrojové kódy

Move conversion logic to separate module

Kirk Trombley 3 rokov pred
rodič
commit
cff6145ce1
2 zmenil súbory, kde vykonal 56 pridanie a 54 odobranie
  1. 55 0
      convert.py
  2. 1 54
      ingest.py

+ 55 - 0
convert.py

@@ -0,0 +1,55 @@
+# I could not find a single decent RGB -> CIELUV conversion library out there
+
+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)

+ 1 - 54
ingest.py

@@ -3,60 +3,7 @@ from collections import namedtuple
 
 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: