[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ff-cvs] libvob/vob color/spaces.py paper/colors.py
From: |
Janne V. Kujala |
Subject: |
[ff-cvs] libvob/vob color/spaces.py paper/colors.py |
Date: |
Sun, 14 Sep 2003 06:46:53 -0400 |
CVSROOT: /cvsroot/libvob
Module name: libvob
Branch:
Changes by: Janne V. Kujala <address@hidden> 03/09/14 06:46:53
Modified files:
vob/color : spaces.py
vob/paper : colors.py
Log message:
do gamma corrections explicitly and use proper per-component
gamma-corrections in libpaper; implement special cases in the CIELAB formulas
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/vob/color/spaces.py.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/vob/paper/colors.py.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
Patches:
Index: libvob/vob/color/spaces.py
diff -u libvob/vob/color/spaces.py:1.3 libvob/vob/color/spaces.py:1.4
--- libvob/vob/color/spaces.py:1.3 Thu Sep 4 08:47:04 2003
+++ libvob/vob/color/spaces.py Sun Sep 14 06:46:53 2003
@@ -25,23 +25,36 @@
import math
-# Gamma correction used with the perceptual non-linearity in
-# CIE XYZ and YtoL and LtoY conversion functions.
-#
+# The gamma used for converting linear RGB to monitor RGB
+
gamma = 2.2
-#
+
# The uncorrected display gamma of PC's is typically 2.2, i.e.,
# RGB values map to physical intensities with an exponent of 2.2.
-# So, gamma correction of 2.2 here should result in linear
-# intensity. (The CIE L* / Y computation assumes linear intensity).
+# So, gamma correction of 2.2 here should result in linear intensity.
+
+# These may later be changed to use the sRGB standard
+# (which is almost the same as the simple 2.2 gamma).
+
+def linear_to_monitor(rgb):
+ def f(x):
+ if x < 0: return 0
+ return x**(1.0/gamma)
+ return (f(rgb[0]), f(rgb[1]), f(rgb[2]))
+
+def monitor_to_linear(rgb):
+ def f(x):
+ if x < 0: return 0
+ return x**gamma
+ return (f(rgb[0]), f(rgb[1]), f(rgb[2]))
+
+# RGB709 <-> CIE XYZ conversions
def RGBtoXYZ(v):
mat = [[ 0.412453, 0.35758 , 0.180423],
[ 0.212671, 0.71516 , 0.072169],
[ 0.019334, 0.119193, 0.950227]];
- v = ( v[0]**gamma, v[1]**gamma, v[2]**gamma )
-
return [ mat[0][0] * v[0] + mat[0][1] * v[1] + mat[0][2] * v[2],
mat[1][0] * v[0] + mat[1][1] * v[1] + mat[1][2] * v[2],
mat[2][0] * v[0] + mat[2][1] * v[1] + mat[2][2] * v[2] ]
@@ -50,41 +63,49 @@
mat = [[ 3.240479,-1.53715 ,-0.498535],
[-0.969256, 1.875991, 0.041556],
[ 0.055648,-0.204043, 1.057311]];
- v = [ (mat[0][0] * v[0] + mat[0][1] * v[1] + mat[0][2] * v[2]),
- (mat[1][0] * v[0] + mat[1][1] * v[1] + mat[1][2] * v[2]),
- (mat[2][0] * v[0] + mat[2][1] * v[1] + mat[2][2] * v[2]) ]
- return ( v[0]**(1/gamma), v[1]**(1/gamma), v[2]**(1/gamma) )
+ return [ (mat[0][0] * v[0] + mat[0][1] * v[1] + mat[0][2] * v[2]),
+ (mat[1][0] * v[0] + mat[1][1] * v[1] + mat[1][2] * v[2]),
+ (mat[2][0] * v[0] + mat[2][1] * v[1] + mat[2][2] * v[2]) ]
+
+# CIE L*a*b* conversions
+
+def f(X):
+ """The perceptual nonlinearity used in the CIE L*a*b* color space"""
+ if X <= (216./24389):
+ return (841./108) * X + (16./116)
+ else:
+ return X**(1./3)
+
+def inv_f(X):
+ """Inverse of the the perceptual nonlinearity"""
+ if X <= (6./29):
+ return (X - 16./116) * (108./841)
+ else:
+ return X**3
+
def RGBtoLAB(RGB):
XYZ = RGBtoXYZ(RGB)
XYZn = RGBtoXYZ([1,1,1])
- X = XYZ[0] / XYZn[0]
- Y = XYZ[1] / XYZn[1]
- Z = XYZ[2] / XYZn[2]
-
- if Y <= (216./24389):
- L = Y * (24389./27)
- else:
- L = 116 * pow(Y, 1./3) - 16
-
- return [ L,
- 500 * (pow(X, 1./3.) - pow(Y, 1./3.)),
- 200 * (pow(Y, 1./3.) - pow(Z, 1./3.)) ]
+ X3 = f(XYZ[0] / XYZn[0])
+ Y3 = f(XYZ[1] / XYZn[1])
+ Z3 = f(XYZ[2] / XYZn[2])
+
+ return [ 116 * Y3 - 16,
+ 500 * (X3 - Y3),
+ 200 * (Y3 - Z3) ]
def LABtoRGB(LAB):
- L = LAB[0]
- if L <= 8:
- Y3 = pow(L * (27./24389), 1/3.0)
- else:
- Y3 = (L + 16.0) / 116
+ Y3 = (LAB[0] + 16.) / 116
+ X3 = LAB[1] / 500. + Y3
+ Z3 = Y3 - LAB[2] / 200.
XYZn = RGBtoXYZ([1,1,1])
- XYZ = [ XYZn[0] * pow(Y3 + LAB[1] / 500.0, 3),
- XYZn[1] * pow(Y3, 3),
- XYZn[2] * pow(Y3 - LAB[2] / 200.0, 3) ]
-
-
+ XYZ = [ XYZn[0] * inv_f(X3),
+ XYZn[1] * inv_f(Y3),
+ XYZn[2] * inv_f(Z3) ]
+
return XYZtoRGB(XYZ);
def LABhue(RGB):
@@ -243,7 +264,6 @@
Y: luminance between 0 and 1
returns: lightness between 0 and 100
"""
- Y = Y**gamma
if Y <= (216./24389):
return Y * (24389./27)
else:
@@ -256,6 +276,6 @@
returns: luminance between 0 and 1
"""
if L <= 8:
- return pow(L * (27./24389), 1.0 / gamma)
+ return pow(L * (27./24389), 1.0)
else:
- return pow((L + 16.0) / 116, 3.0 / gamma)
+ return pow((L + 16.0) / 116, 3.0)
Index: libvob/vob/paper/colors.py
diff -u libvob/vob/paper/colors.py:1.2 libvob/vob/paper/colors.py:1.3
--- libvob/vob/paper/colors.py:1.2 Tue May 6 23:43:57 2003
+++ libvob/vob/paper/colors.py Sun Sep 14 06:46:53 2003
@@ -23,9 +23,12 @@
# Choosing colors and 3-dotproduct factors for papers.
-from vob.color.spaces import
getRandomColor,getRandomColor2,YSTtoRGB,clampSat,LtoY
+from vob.color.spaces import YSTtoRGB,clampSat,LtoY,linear_to_monitor
from vob.color.spaces import RGBtoLAB,LABtoRGB,LABclamp
+def toLAB(rgb):
+ return RGBtoLAB(monitor_to_linear(rgb))
+
from math import sin,cos,atan2,pi,log,sqrt
from random import Random,shuffle
@@ -93,8 +96,8 @@
sats[i] * cos(hues[i]*pi/180),
sats[i] * sin(hues[i]*pi/180) )
for i in range(0,colors)]
-
- col = [clampSat(YSTtoRGB(c)) for c in yst]
+
+ col = [linear_to_monitor(clampSat(YSTtoRGB(c))) for c in yst]
shuffle(col, rnd.nextDouble)
if blend > 0:
@@ -127,7 +130,7 @@
def _AB_angle(self, cols):
#print cols
getangle = lambda lab: 180 / pi * atan2(lab[2], lab[1])
- angles = [ getangle(RGBtoLAB(col)) for col in cols ]
+ angles = [ getangle(toLAB(col)) for col in cols ]
#print angles
angles.sort()
#print angles
@@ -143,7 +146,7 @@
def _AB_avg_dot(self, cols):
print cols
- ab = [ (lab[1]/100.0,lab[2]/100.0) for lab in map(RGBtoLAB, cols) ]
+ ab = [ (lab[1]/100.0,lab[2]/100.0) for lab in map(toLAB, cols) ]
dot = lambda x,y: x[0] * y[0] + x[1] * y[1]
dots = [ dot(x,y) for x in ab for y in ab ]
@@ -151,7 +154,7 @@
return reduce(lambda x,y: x+y, dots) / len(dots)
def _AB_area(self, cols):
- ab = [ (lab[1]/100.0,lab[2]/100.0) for lab in map(RGBtoLAB, cols) ]
+ ab = [ (lab[1]/100.0,lab[2]/100.0) for lab in map(toLAB, cols) ]
#print [ (int(100*a),int(100*b)) for (a,b) in ab ]
ab = convex_hull(ab)
#print [ (int(100*a),int(100*b)) for (a,b) in ab ]
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [ff-cvs] libvob/vob color/spaces.py paper/colors.py,
Janne V. Kujala <=