Commit 263e88a6 authored by Villena Guillaume's avatar Villena Guillaume
Browse files

Added main python code

parents
import re
from math import *
class CIEXYZ:
def __init__(self, filename):
f = open(filename)
self.Lambda = []
self.xc = []
self.yc = []
self.zc = []
self.S = []
self.Sxc = []
self.Syc = []
self.Szc = []
I = 0
for line in f.readlines():
li = line.strip()
t = re.split('[\s|,]+', li)
self.Lambda.append(float(t[0]))
self.xc.append(float(t[1]))
self.yc.append(float(t[2]))
self.zc.append(float(t[3]))
self.S.append(1.0)
self.Sxc.append(float(t[1]))
self.Syc.append(float(t[2]))
self.Szc.append(float(t[3]))
I += float(t[2])
self.K = 1.0 / I
f.close()
def fColor(self, L):
if ((L < 360) | (L > 829)):
return [0, 0, 0]
else:
i = int(floor(L - 360.0))
x = self.xc[i] + (L - float(i) - 360.0) * (self.xc[i + 1] - self.xc[i])
y = self.yc[i] + (L - float(i) - 360.0) * (self.yc[i + 1] - self.yc[i])
z = self.zc[i] + (L - float(i) - 360.0) * (self.zc[i + 1] - self.zc[i])
return [x, y, z]
def XYZ2xy(self, X, Y, Z):
return [X / (X + Y + Z), Y / (X + Y + Z)]
def xyY2XYZ(self, x, y, Y):
return [x / y * Y, Y, (1 - x - y) / y * Y]
def xyColor(self):
x = []
y = []
for k in range(len(self.xc)):
xy = self.XYZ2xy(self.xc[k], self.yc[k], self.zc[k])
x.append(xy[0])
y.append(xy[1])
return [x, y]
def corpsNoir(self, L, T):
return 100 * pow(560 / L, 5) * (exp(2.569e4 / T) - 1) / (exp(1.4388e7 / (L * T)) - 1)
def readA(self, filename):
f = open(filename)
self.illumALambda = []
self.illumASpectre = []
for line in f.readlines():
li = line.strip()
t = re.split('[\s|,]+', li)
self.illumALambda.append(float(t[0]))
self.illumASpectre.append(float(t[1]))
f.close()
def readD65(self, filename):
f = open(filename)
self.illumD65Lambda = []
self.illumD65Spectre = []
for line in f.readlines():
li = line.strip()
t = re.split('[\s|,]+', li)
self.illumD65Lambda.append(float(t[0]))
self.illumD65Spectre.append(float(t[1]))
f.close()
def SpectreD65(self, L):
L = floor(L)
if ((L < 300) | (L > 830)):
return 0
else:
i = int(L - 300)
return self.illumD65Spectre[i]
def setIlluminant(self, nom, T):
if nom == "CN":
for k in range(471):
L = float(360 + k)
self.S[k] = self.corpsNoir(L, T)
elif nom == "D65":
for k in range(471):
self.S[k] = self.illumD65Spectre[60 + k]
elif nom == "A":
for k in range(471):
L = float(360 + k)
self.S[k] = self.corpsNoir(L, 2855.5)
elif nom == 'E':
for k in range(471):
self.S[k] = 1
I = 0
for k in range(471):
self.Sxc[k] = self.S[k] * self.xc[k]
self.Syc[k] = self.S[k] * self.yc[k]
self.Szc[k] = self.S[k] * self.zc[k]
I += self.Syc[k]
self.K = 1.0 / I
def setFonctionIlluminant(self, f):
for k in range(471):
L = float(360 + k)
self.S[k] = f(L)
I = 0
for k in range(471):
self.Sxc[k] = self.S[k] * self.xc[k]
self.Syc[k] = self.S[k] * self.yc[k]
self.Szc[k] = self.S[k] * self.zc[k]
I += self.Syc[k]
self.K = 1.0 / I
def spectralF2XYZ(self, Rf):
X = 0
Y = 0
Z = 0
for k in range(471):
L = float(360 + k)
R = Rf(L)
X += self.Sxc[k] * R
Y += self.Syc[k] * R
Z += self.Szc[k] * R
return [self.K * X, self.K * Y, self.K * Z]
def XYZMonochrome(self, L):
if (L < 360) | (L > 830):
return [0, 0, 0]
k = int(floor(L - 360))
X = self.Sxc[k]
Y = self.Syc[k]
Z = self.Szc[k]
return [self.K * X, self.K * Y, self.K * Z]
def ener2lum(self, e, L):
xyz = self.fColor(L)
return e * 683.0 * xyz[1]
def lum2ener(self, lu, L):
xyz = self.fColor(L)
return lu / (683.0 * xyz[1])
def rgbColorim(self):
r = []
g = []
b = []
for k in range(len(self.xc)):
r.append(0.41846 * self.xc[k] - 0.15866 * self.yc[k] - 0.08283 * self.zc[k])
g.append(-0.09117 * self.xc[k] + 0.25242 * self.yc[k] + 0.01571 * self.zc[k])
b.append(0.00092 * self.xc[k] - 0.00255 * self.yc[k] + 0.17860 * self.zc[k])
return [r, g, b]
from matplotlib.pyplot import plot, imshow, text
from numpy import *
from math import *
from XYZ2RGB import *
from CieXYZ import *
class DiaChrom:
def __init__(self, ciexyz):
self.ciexyz = ciexyz
self.kmin = 400 - 360
self.kmax = 701 - 360
self.ns = self.kmax - self.kmin
spectre = ciexyz.xyColor()
self.ymin = spectre[1][self.kmin]
self.ymax = max(spectre[1])
self.xSpectre = []
self.ySpectre = []
for k in range(self.ns):
self.xSpectre.append(spectre[0][k + self.kmin])
self.ySpectre.append(spectre[1][k + self.kmin])
self.x1 = self.xSpectre[0]
self.y1 = self.ySpectre[0]
self.x2 = self.xSpectre[self.ns - 1]
self.y2 = self.ySpectre[self.ns - 1]
def plotSpectre(self):
plot(self.xSpectre, self.ySpectre, c='k', label='_nolegend_')
plot([self.x1, self.x2], [self.y1, self.y2], c='k', label='_nolegend_')
for L in [400, 480, 500, 520, 550, 600, 700]:
k = L - 400
if L < 520:
text(self.xSpectre[k], self.ySpectre[k], str(L), horizontalalignment='right')
else:
text(self.xSpectre[k], self.ySpectre[k], str(L), horizontalalignment='left')
def paintRGB(self, xyz2rgb, name, delta):
rgb = xyz2rgb
plot([rgb.red[0], rgb.green[0], rgb.blue[0], rgb.red[0]], [rgb.red[1], rgb.green[1], rgb.blue[1], rgb.red[1]],
color='k', marker='o', label=name)
img = []
largeur = rgb.red[0] - rgb.blue[0]
hauteur = rgb.green[1] - rgb.blue[1]
imax = int(floor(largeur / delta))
jmax = int(floor(hauteur / delta))
penteBG = (rgb.green[0] - rgb.blue[0]) / (rgb.green[1] - rgb.blue[1])
penteBR = (rgb.red[0] - rgb.blue[0]) / (rgb.red[1] - rgb.blue[1])
penteGR = (rgb.red[0] - rgb.green[0]) / (rgb.red[1] - rgb.green[1])
for j in range(jmax):
ligne = []
y = rgb.blue[1] + float(j) * delta
xmin = rgb.blue[0] + penteBG * (y - rgb.blue[1])
if y < rgb.red[1]:
xmax = rgb.blue[0] + penteBR * (y - rgb.blue[1])
else:
xmax = rgb.green[0] + penteGR * (y - rgb.green[1])
for i in range(imax):
x = rgb.blue[0] + float(i) * delta
if (x >= xmin) & (x < xmax):
RGB = rgb.xyL2rgb(x, y, 1.0)
ligne.append([RGB[0], RGB[1], RGB[2], 1])
else:
ligne.append([0, 0, 0, 0])
img.append(ligne)
imshow(img, origin='lower', extent=[rgb.blue[0], rgb.red[0], rgb.blue[1], rgb.green[1]])
def paintAll(self, xyz2rgb, name, delta, c='k', m='o'):
rgb = xyz2rgb
img = []
largeur = self.x2
hauteur = self.ymax
imax = int(floor(largeur / delta))
jmax = int(floor(hauteur / delta))
for j in range(jmax):
ligne = []
y = float(j) * delta
k = 0
while (y > self.ySpectre[k]):
k += 1
xmin = self.xSpectre[k]
k += 1
if y > self.y2:
while (y < self.ySpectre[k]):
k += 1
xmax = self.xSpectre[k]
else:
xmax = self.x1 + (y - self.y1) * (self.x2 - self.x1) / (self.y2 - self.y1)
for i in range(imax):
x = float(i) * delta
if (x >= xmin) & (x < xmax):
RGB = rgb.xyL2rgb(x, y, 1.0)
ligne.append([RGB[0], RGB[1], RGB[2], 1])
else:
ligne.append([0, 0, 0, 0])
img.append(ligne)
imshow(img, origin='lower', extent=[0, largeur, 0, hauteur])
plot([rgb.red[0], rgb.green[0], rgb.blue[0], rgb.red[0]], [rgb.red[1], rgb.green[1], rgb.blue[1], rgb.red[1]],
color=c, marker=m, label=name)
def corpsNoir(self, Tarray):
x = []
y = []
s = ""
for T in Tarray:
self.ciexyz.setIlluminant("CN", T)
def Rf(L):
return 1
XYZ = self.ciexyz.spectralF2XYZ(Rf)
xy = self.ciexyz.XYZ2xy(XYZ[0], XYZ[1], XYZ[2])
x.append(xy[0])
y.append(xy[1])
s += "%.0f " % T
plot(x, y, marker="+", color="k", linestyle="-", label="CN : %s K" % s)
from matplotlib.pyplot import *
from CieXYZ import CIEXYZ
from DiaChrom import DiaChrom
from XYZ2RGB import XYZ2RGB
if __name__ == '__main__':
adobeRGB = XYZ2RGB([0.64, 0.33], [0.21, 0.71], [0.15, 0.06], [0.3127, 0.329])
oneplus6t = XYZ2RGB([0.648, 0.348], [0.232, 0.671], [0.143, 0.034], [0.298, 0.314])
oneplus6tManufacturer = XYZ2RGB([0.680, 0.320], [0.265, 0.690], [0.150, 0.060], [0.314, 0.351])
ciexyz = CIEXYZ("./ciexyz31.txt")
diagram = DiaChrom(ciexyz)
clf()
figure(3, figsize=(9, 8))
xlabel('x')
ylabel('y')
diagram.plotSpectre()
diagram.paintAll(adobeRGB, "Adobe RGB(98)", 0.001)
diagram.paintAll(oneplus6t, "OnePlus 6T", 0.001, c='k', m='*')
diagram.paintAll(oneplus6tManufacturer, "DCI-P3", 0.001, c='k', m='>')
legend()
axis([0, 1, 0, 1])
grid(True)
show()
from numpy import *
from numpy.linalg import *
from math import *
class XYZ2RGB:
def __init__(self, red, green, blue, white):
self.red = red
self.green = green
self.blue = blue
self.white = white
P = mat([[red[0], green[0], blue[0]], [red[1], green[1], blue[1]],
[1 - red[0] - red[1], 1 - green[0] - green[1], 1 - blue[0] - blue[1]]])
U = inv(P) * mat([[white[0]], [white[1]], [1 - white[0] - white[1]]]) / white[1]
self.Q = P * mat([[U[0, 0], 0, 0], [0, U[1, 0], 0], [0, 0, U[2, 0]]])
self.T = inv(self.Q)
self.gamma = 2.2
def rgb(self, XYZ):
RGB = self.T * mat([[XYZ[0]], [XYZ[1]], [XYZ[2]]])
return [RGB[0, 0], RGB[1, 0], RGB[2, 0]]
def xyY2RGB(self, x, y, Y):
X = x / y * Y
Z = (1 - x - y) / y * Y
return self.rgb([X, Y, Z])
def XYZ(self, RGB):
XYZ0 = self.Q * mat([[RGB[0]], [RGB[1]], [RGB[2]]])
return [XYZ0[0, 0], XYZ0[1, 0], XYZ0[2, 0]]
def rgbN(self, XYZ):
RGB = self.rgb(XYZ)
m = max(RGB)
if m > 1.0:
return [RGB[0] / m, RGB[1] / m, RGB[2] / m]
else:
return RGB
def rgbN1(self, XYZ):
RGB = self.rgb(XYZ)
m = -min([0, RGB[0], RGB[1], RGB[2]])
RGB[0] += m
RGB[1] += m
RGB[2] += m
m = max(RGB)
if m > 1.0:
return [RGB[0] / m, RGB[1] / m, RGB[2] / m]
else:
return RGB
def rgbN2(self, XYZ):
RGB = self.rgb(XYZ)
for k in range(3):
if RGB[k] < 0:
RGB[k] = 0;
m = max(RGB)
if m > 1.0:
return [RGB[0] / m, RGB[1] / m, RGB[2] / m]
else:
return RGB
def rgbN2G(self, XYZ):
RGB = self.rgbN2(XYZ)
a = 1.0 / self.gamma
RGB[0] = math.pow(RGB[0], a)
RGB[1] = math.pow(RGB[1], a)
RGB[2] = math.pow(RGB[2], a)
return RGB
def rgbN1G(self, XYZ):
RGB = self.rgbN1(XYZ)
a = 1.0 / self.gamma
RGB[0] = math.pow(RGB[0], a)
RGB[1] = math.pow(RGB[1], a)
RGB[2] = math.pow(RGB[2], a)
return RGB
def XYZG(self, RGB):
RGB[0] = math.pow(RGB[0], self.gamma)
RGB[1] = math.pow(RGB[1], self.gamma)
RGB[2] = math.pow(RGB[2], self.gamma)
return self.XYZ(RGB)
def rgbN2G2(self, XYZ):
RGB = self.rgbN2(XYZ)
a = 1.0 / 2.4
for k in range(3):
if RGB[k] <= 0.00304:
RGB[k] *= 12.92
else:
RGB[k] = 1.055 * math.pow(RGB[k], a) - 0.055
return RGB
def xyL2rgb(self, x, y, Lu):
XYZ = [x / y, 1, (1 - x - y) / y]
RGB = self.rgbN2G(XYZ)
return [RGB[0] * Lu, RGB[1] * Lu, RGB[2] * Lu]
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment