polished syntax here and there.
This commit is contained in:
parent
6cd6172c0c
commit
95c74961dd
|
@ -86,7 +86,7 @@ class Color():
|
|||
[c+m, m, x+m],
|
||||
][sextant],'d'))
|
||||
self.model = converted.model
|
||||
self.color = converted.color
|
||||
self.color = converted.color
|
||||
# ------------------------------------------------------------------
|
||||
# convert R(ed) G(reen) B(lue) to H(ue) S(aturation) L(uminance)
|
||||
# with S,L,H,R,G,B running from 0 to 1
|
||||
|
@ -106,14 +106,14 @@ class Color():
|
|||
if (HSL[2]<0.5):
|
||||
HSL[1] = (maxcolor - mincolor)/(maxcolor + mincolor)
|
||||
else:
|
||||
HSL[1] = (maxcolor - mincolor)/(2.0 -maxcolor -mincolor)
|
||||
HSL[1] = (maxcolor - mincolor)/(2.0 - maxcolor - mincolor)
|
||||
if (maxcolor == self.color[0]):
|
||||
HSL[0] = 0.0 + (self.color[1] - self.color[2])/(maxcolor - mincolor)
|
||||
elif (maxcolor == self.color[1]):
|
||||
HSL[0] = 2.0 + (self.color[2] - self.color[0])/(maxcolor - mincolor)
|
||||
elif (maxcolor == self.color[2]):
|
||||
HSL[0] = 4.0 + (self.color[0] - self.color[1])/(maxcolor - mincolor)
|
||||
HSL[0] = HSL[0]*60.0
|
||||
HSL[0] = HSL[0]*60.0 # is it necessary to scale to 360 hue values? might be dangerous for small values <1..!
|
||||
if (HSL[0] < 0.0):
|
||||
HSL[0] = HSL[0] + 360.0
|
||||
for i in xrange(2):
|
||||
|
@ -133,15 +133,13 @@ class Color():
|
|||
|
||||
XYZ = numpy.zeros(3,'d')
|
||||
RGB_lin = numpy.zeros(3,'d')
|
||||
|
||||
for i in xrange(3):
|
||||
if (self.color[i] > 0.04045):
|
||||
RGB_lin[i] = ((self.color[i]+0.0555)/1.0555)**2.4
|
||||
else:
|
||||
RGB_lin[i] = self.color[i]/12.92
|
||||
convert = numpy.array([[0.412453,0.357580,0.180423],
|
||||
[0.212671,0.715160,0.072169],
|
||||
[0.019334,0.119193,0.950227]])
|
||||
|
||||
for i in xrange(3):
|
||||
if (self.color[i] > 0.04045): RGB_lin[i] = ((self.color[i]+0.0555)/1.0555)**2.4
|
||||
else: RGB_lin[i] = self.color[i] /12.92
|
||||
XYZ = numpy.dot(convert,RGB_lin)
|
||||
for i in xrange(3):
|
||||
XYZ[i] = min(XYZ[i],1.0)
|
||||
|
@ -151,32 +149,28 @@ class Color():
|
|||
self.model = converted.model
|
||||
self.color = converted.color
|
||||
# ------------------------------------------------------------------
|
||||
# convert CIE XYZ R(ed) G(reen) B(lue)
|
||||
# convert CIE XYZ to R(ed) G(reen) B(lue)
|
||||
# with all values in the range of 0 to 1
|
||||
# from http://www.cs.rit.edu/~ncs/color/t_convert.html
|
||||
def _XYZ2RGB(self):
|
||||
import numpy
|
||||
if self.model != 'XYZ': return
|
||||
|
||||
RGB = numpy.zeros(3,'d')
|
||||
RGB_lin = numpy.zeros(3,'d')
|
||||
|
||||
convert = numpy.array([[ 3.240479,-1.537150,-0.498535],
|
||||
[-0.969256, 1.875992, 0.041556],
|
||||
[ 0.055648,-0.204043, 1.057311]])
|
||||
RGB_lin = numpy.dot(convert,self.color)
|
||||
RGB = numpy.zeros(3,'d')
|
||||
|
||||
for i in xrange(3):
|
||||
if (RGB_lin[i] > 0.0031308):
|
||||
RGB[i] = ((RGB_lin[i])**(1.0/2.4))*1.0555-0.0555
|
||||
else:
|
||||
RGB[i] = RGB_lin[i]*12.92
|
||||
if (RGB_lin[i] > 0.0031308): RGB[i] = ((RGB_lin[i])**(1.0/2.4))*1.0555-0.0555
|
||||
else: RGB[i] = RGB_lin[i] *12.92
|
||||
for i in xrange(3):
|
||||
RGB[i] = min(RGB[i],1.0)
|
||||
RGB[i] = max(RGB[i],0.0)
|
||||
|
||||
maxVal = max(RGB) # clipping colors according to the display gamut
|
||||
if (maxVal > 1.0):
|
||||
RGB /= maxVal
|
||||
if (maxVal > 1.0): RGB /= maxVal
|
||||
|
||||
converted = Color('RGB', RGB)
|
||||
self.model = converted.model
|
||||
|
@ -192,15 +186,13 @@ class Color():
|
|||
ref_white = numpy.array([.95047, 1.00000, 1.08883],'d') # Observer = 2, Illuminant = D65
|
||||
XYZ = numpy.zeros(3,'d')
|
||||
|
||||
XYZ[1] = (self.color[0] + 16 ) / 116
|
||||
XYZ[0] = XYZ[1] + self.color[1] / 500
|
||||
XYZ[2] = XYZ[1] - self.color[2] / 200
|
||||
XYZ[1] = (self.color[0] + 16.0 ) / 116.0
|
||||
XYZ[0] = XYZ[1] + self.color[1] / 500.0
|
||||
XYZ[2] = XYZ[1] - self.color[2] / 200.0
|
||||
|
||||
for i in xrange(len(XYZ)):
|
||||
if (XYZ[i] > 6./29. ):
|
||||
XYZ[i] = XYZ[i]**3.
|
||||
else:
|
||||
XYZ[i] = 108./2523.*(XYZ[i]-4./29.)
|
||||
if (XYZ[i] > 6./29. ): XYZ[i] = XYZ[i]**3.
|
||||
else: XYZ[i] = 108./2523. * (XYZ[i] - 4./29.)
|
||||
|
||||
converted = Color('XYZ', XYZ*ref_white)
|
||||
self.model = converted.model
|
||||
|
@ -217,12 +209,10 @@ class Color():
|
|||
XYZ = self.color/ref_white
|
||||
|
||||
for i in xrange(len(XYZ)):
|
||||
if (XYZ[i] > 216./24389 ):
|
||||
XYZ[i] = XYZ[i]**(1.0/3.0)
|
||||
else:
|
||||
XYZ[i] = ( 24389./27. * XYZ[i] + 16.0 ) / 116.0
|
||||
if (XYZ[i] > 216./24389 ): XYZ[i] = XYZ[i]**(1.0/3.0)
|
||||
else: XYZ[i] = (24389./27. * XYZ[i] + 16.0 ) / 116.0
|
||||
|
||||
converted = Color('CIELAB', numpy.array([ 116.0 * XYZ[1] - 16.0,
|
||||
converted = Color('CIELAB', numpy.array([ 116.0 * XYZ[1] - 16.0,
|
||||
500.0 * (XYZ[0] - XYZ[1]),
|
||||
200.0 * (XYZ[1] - XYZ[2]) ]))
|
||||
self.model = converted.model
|
||||
|
@ -236,16 +226,14 @@ class Color():
|
|||
|
||||
Msh = numpy.zeros(3,'d')
|
||||
Msh[0] = math.sqrt(numpy.dot(self.color,self.color))
|
||||
if (Msh[0] != 0.0) and (Msh[0] > 0.001):
|
||||
Msh[1] = math.acos(self.color[0]/Msh[0])
|
||||
if (self.color[1] != 0.0) and (Msh[1] > 0.001):
|
||||
Msh[2] = math.atan2(self.color[2],self.color[1])
|
||||
if (Msh[0] != 0.0) and (Msh[0] > 0.001): Msh[1] = math.acos( self.color[0]/Msh[0])
|
||||
if (self.color[1] != 0.0) and (Msh[1] > 0.001): Msh[2] = math.atan2(self.color[2],self.color[1])
|
||||
|
||||
converted = Color('MSH', Msh)
|
||||
self.model = converted.model
|
||||
self.color = converted.color
|
||||
# ------------------------------------------------------------------
|
||||
# convert msh colorspace to Cie Lab
|
||||
# convert msh colorspace to Cie Lab
|
||||
# s,h in radians
|
||||
# from http://www.cs.unm.edu/~kmorel/documents/ColorMaps/DivergingColorMapWorkshop.xls
|
||||
def _MSH2CIELAB(self):
|
||||
|
@ -264,8 +252,7 @@ class Color():
|
|||
|
||||
class Colormap():
|
||||
'''
|
||||
perceptually uniform diverging and sequential colormaps. colormap string exportable in the respective
|
||||
formats compatible to paraview,gmsh and raw.
|
||||
perceptually uniform diverging or sequential colormaps.
|
||||
'''
|
||||
|
||||
__slots__ = [
|
||||
|
@ -287,12 +274,17 @@ class Colormap():
|
|||
self.right = right.asModel('MSH')
|
||||
# ------------------------------------------------------------------
|
||||
def export(self,name='uniformPerceptualColorMap',format = 'paraview', steps = 10, crop = [-1.0,1.0]):
|
||||
# export method returns colormap as a string w.r.t the specified format eg, paraview,gmsh
|
||||
# the colormap can be cropped according to the range of specified values.
|
||||
# No need to differentiate between sequential and diverging colormaps
|
||||
# produces sequential colormaps if either of the colors in the Colormap-object is either white or black
|
||||
'''
|
||||
RGB colormap for use in paraview or gmsh, or as raw string, or array.
|
||||
arguments: name, format, steps, crop.
|
||||
format is one of (paraview, gmsh, raw, list).
|
||||
crop selects a (sub)range in [-1.0,1.0].
|
||||
generates
|
||||
sequential map if one limiting color is either white or black,
|
||||
diverging map otherwise.
|
||||
'''
|
||||
# ------------------------------------------------------------------
|
||||
import copy,numpy, math
|
||||
import copy,numpy,math
|
||||
|
||||
def interpolate_color(left,right,interp):
|
||||
def rad_dif(left,right):
|
||||
|
@ -316,57 +308,48 @@ class Colormap():
|
|||
if ((Msh1.color[1] > 0.05 and Msh2.color[1] > 0.05) and rad_dif(Msh1,Msh2) > math.pi/3.0):
|
||||
Msh_mid[0] = max(Msh1.color[0],Msh2.color[0],88.0)
|
||||
if interp < 0.5:
|
||||
Msh2.color[0] = Msh_mid[0]
|
||||
Msh2.color[1] = 0.0
|
||||
Msh2.color[2] = 0.0
|
||||
Msh2.color = [Msh_mid[0],0.0,0.0]
|
||||
interp = 2.0*interp
|
||||
else:
|
||||
Msh1.color[0] = Msh_mid[0]
|
||||
Msh1.color[1] = 0.0
|
||||
Msh1.color[2] = 0.0
|
||||
Msh1.color = [Msh_mid[0],0.0,0.0]
|
||||
interp = 2.0*interp - 1.0
|
||||
if (Msh1.color[1] < 0.05) and (Msh2.color[1] > 0.05):
|
||||
Msh1.color[2] = adjust_hue(Msh2,Msh1)
|
||||
elif (Msh2.color[1] < 0.05) and (Msh1.color[1] > 0.05):
|
||||
Msh2.color[2] = adjust_hue(Msh1,Msh2)
|
||||
for i in range(3):
|
||||
Msh_mid[i] = (1.0-interp)*Msh1.color[i] + interp* Msh2.color[i]
|
||||
if (Msh1.color[1] < 0.05) and (Msh2.color[1] > 0.05): Msh1.color[2] = adjust_hue(Msh2,Msh1)
|
||||
elif (Msh2.color[1] < 0.05) and (Msh1.color[1] > 0.05): Msh2.color[2] = adjust_hue(Msh1,Msh2)
|
||||
Msh_mid = (1.0-interp)*Msh1.color + interp*Msh2.color
|
||||
return Color('MSH',Msh_mid).to()
|
||||
|
||||
def write_paraview(RGB_vector):
|
||||
colormap ='<ColorMap name="'+ str(name)+ '" space="RGB">\n'
|
||||
colormap ='<ColorMap name="'+str(name)+'" space="RGB">\n'
|
||||
for i in range(len(RGB_vector)):
|
||||
colormap+='<Point x="'+str(i)+'" o="1" r="'+str(RGB_vector[i][0])+'" g="'+str(RGB_vector[i][1])+'" b="'+str(RGB_vector[i][2])+'"/>\n'
|
||||
colormap+='</ColorMap>'
|
||||
return colormap
|
||||
|
||||
def write_gmsh(RGB_vector):
|
||||
colormap = 'View.ColorTable = {\n'
|
||||
for i in range(len(RGB_vector)-1):
|
||||
colormap+='{'+str((RGB_vector[i][0])*255.0)+','+str((RGB_vector[i][1])*255.0)+','+str((RGB_vector[i][2])*255.0)+'},\n'
|
||||
colormap+='{'+str((RGB_vector[-1][0])*255.0)+','+str((RGB_vector[-1][1])*255.0)+','+str((RGB_vector[-1][2])*255.0)+'}}\n'
|
||||
return colormap
|
||||
return 'View.ColorTable = {\n' \
|
||||
+ ',\n'.join(['{%s}'%(','.join(map(lambda x:str(x*255.0),v))) for v in RGB_vector]) \
|
||||
+ '\n}'
|
||||
|
||||
def write_raw(RGB_vector):
|
||||
colormap = ('ColorMap name = ' + str(name)+'\n')
|
||||
for i in range(len(RGB_vector)):
|
||||
colormap+=str(RGB_vector[i][0])+'\t'+str(RGB_vector[i][1])+'\t'+str(RGB_vector[i][2])+'\n'
|
||||
return colormap
|
||||
return 'ColorMap name = '+str(name)+'\n' \
|
||||
+ '\n'.join(['%s'%('\t'.join(map(lambda x:str(x),v))) for v in RGB_vector])
|
||||
|
||||
|
||||
interpolationVector = [] # a list of equally spaced values(interpolator) between 0 and 1
|
||||
RGB_Matrix = []
|
||||
scaledSteps = int(steps/(crop[1] - crop[0])*2.0)
|
||||
for i in range(scaledSteps): interpolationVector.append(float(i)/scaledSteps)
|
||||
|
||||
totalSteps = int(2.0*steps/(crop[1] - crop[0]))
|
||||
for i in range(totalSteps): interpolationVector.append(float(i)/(totalSteps-1))
|
||||
for i in interpolationVector:
|
||||
copySelf = copy.deepcopy(self)
|
||||
color = interpolate_color(copySelf.left,copySelf.right,i)
|
||||
RGB_Matrix.append(color.color)
|
||||
|
||||
right = int((scaledSteps - 1)/2.0 + (scaledSteps - 1)/2.0*crop[1])
|
||||
|
||||
leftIndex = int(round((crop[0]-(-1.0))/(2.0/(totalSteps-1))))
|
||||
rightIndex = leftIndex + steps
|
||||
return {\
|
||||
'paraview': write_paraview,
|
||||
'gmsh': write_gmsh,
|
||||
'raw': write_raw,
|
||||
'list': lambda x: x,
|
||||
}[format.lower()](RGB_Matrix[max(right-steps,0):min(right,scaledSteps)])
|
||||
'gmsh': write_gmsh,
|
||||
'raw': write_raw,
|
||||
'list': lambda x: x,
|
||||
}[format.lower()](RGB_Matrix[max(leftIndex,0):min(rightIndex,totalSteps)])
|
||||
|
|
Loading…
Reference in New Issue