|
|
@@ -86,9 +86,35 @@ def chromaticity_xy(x: float, y: float, z: float) -> tuple[float, float]:
|
|
|
return x / total, y / total
|
|
|
|
|
|
|
|
|
-def analyze(channels: dict[str, float]) -> dict:
|
|
|
- """Tagastab tuletatud värviväljad ClickHouse'i rea jaoks."""
|
|
|
+# D65 valgepunkt (CIE XYZ)
|
|
|
+D65_WHITE = (0.95047, 1.0, 1.08883)
|
|
|
+
|
|
|
+
|
|
|
+def _white_reference_xyz() -> tuple[float, float, float]:
|
|
|
+ """XYZ, kui kõik kanalid = 1 (st ühtlane/valge spekter)."""
|
|
|
+ x = y = z = 0.0
|
|
|
+ for wavelength in CHANNEL_WAVELENGTHS.values():
|
|
|
+ cx, cy, cz = cie_xyz_cmf(wavelength)
|
|
|
+ x += cx
|
|
|
+ y += cy
|
|
|
+ z += cz
|
|
|
+ return x, y, z
|
|
|
+
|
|
|
+
|
|
|
+_WHITE_XYZ = _white_reference_xyz()
|
|
|
+
|
|
|
+
|
|
|
+def analyze(channels: dict[str, float], white_balance: bool = True) -> dict:
|
|
|
+ """Tagastab tuletatud värviväljad ClickHouse'i rea jaoks.
|
|
|
+
|
|
|
+ white_balance=True korral skaleeritakse XYZ nii, et ühtlased kanalid
|
|
|
+ (valge) vastavad D65 valgele — muidu annab mudel kerge roosa nihke.
|
|
|
+ """
|
|
|
x, y, z = channels_to_xyz(channels)
|
|
|
+ if white_balance and _WHITE_XYZ[0] > 0 and _WHITE_XYZ[1] > 0 and _WHITE_XYZ[2] > 0:
|
|
|
+ x *= D65_WHITE[0] / _WHITE_XYZ[0]
|
|
|
+ y *= D65_WHITE[1] / _WHITE_XYZ[1]
|
|
|
+ z *= D65_WHITE[2] / _WHITE_XYZ[2]
|
|
|
cx, cy = chromaticity_xy(x, y, z)
|
|
|
r, g, b = xyz_to_srgb(x, y, z)
|
|
|
return {
|