summaryrefslogtreecommitdiff
path: root/test_coeff.py
blob: c2a89703e23941e411d138c954cbf0d89e72bbb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import numpy as np, struct
from scipy.interpolate import RegularGridInterpolator
from colour import *
from colour.plotting import *
from colour.models import eotf_inverse_sRGB
from colour.difference import delta_E_CIE1976
from jakob_hanika import jakob_hanika, model_sd
from test_colorchecker import plot_comparison



illuminant = "D65"
ill_xy = ILLUMINANTS["CIE 1931 2 Degree Standard Observer"][illuminant]
ill_sd = SpectralDistribution(ILLUMINANT_SDS[illuminant])



class JakobHanikaInterpolator:
	def __init__(self):
		pass

	def read_file(self, path):
		with open(path, "rb") as fd:
			if fd.read(4).decode("ISO-8859-1") != "SPEC":
				raise ValueError("bad magic number")

			self.res = struct.unpack("i", fd.read(4))[0]
			self.scale = np.fromfile(fd, count=self.res, dtype=np.float32) # FIXME: default dtype
			coeffs = np.fromfile(fd, count=3*self.res**3*3, dtype=np.float32) # FIXME: default dtype
			coeffs = coeffs.reshape(3, self.res, self.res, self.res, 3)

		t = np.linspace(0, 1, self.res)
		axes = [[0, 1, 2], self.scale, t, t]
		self.cubes = RegularGridInterpolator(axes, coeffs[:, :, :, :, :], bounds_error=False)

	def __call__(self, RGB):
		RGB = np.asarray(RGB, dtype=np.float) # FIXME: default dtype
		vmax = np.max(RGB, axis=-1)
		imax = np.argmax(RGB, axis=-1)
		chroma = RGB / (np.expand_dims(vmax, -1) + 1e-10) # Avoid division by zero
		vmax = np.max(RGB, axis=-1)
		v2 = np.take_along_axis(chroma, np.expand_dims((imax + 2) % 3, axis=-1), axis=-1).squeeze(axis=-1)
		v3 = np.take_along_axis(chroma, np.expand_dims((imax + 1) % 3, axis=-1), axis=-1).squeeze(axis=-1)
		coords = np.stack([imax, vmax, v2, v3], axis=-1)
		return self.cubes(coords).squeeze()



if __name__ == "__main__":
	jh = JakobHanikaInterpolator()
	jh.read_file("data/srgb.coeff")

	RGBs = np.random.random((7, 6, 5, 4, 3))
	ccs = jh(RGBs)

	RGB = eotf_inverse_sRGB(RGBs[0, 0, 0, 0, :])
	XYZ = sRGB_to_XYZ(RGB)
	Lab = XYZ_to_Lab(XYZ, ill_xy)
	cc = ccs[0, 0, 0, 0, :]

	matched_sd = model_sd(cc, primed=False)
	matched_XYZ = sd_to_XYZ(matched_sd, illuminant=ill_sd)
	matched_Lab = XYZ_to_Lab(matched_XYZ, ill_xy)
	error = delta_E_CIE1976(Lab, matched_Lab)

	print(matched_sd)

	plot_comparison(XYZ, matched_sd, "Model", error, ill_sd, ill_xy)