In [ ]:
import colour
EXPRESSION_TEMPLATE = """
Expression {{
inputs 0
expr0 "{0}"
expr1 "{0}"
expr2 "{0}"
name {1}_luminance_Expression
selected true
xpos {2}
ypos 0
}}"""[1:-1]
SWITCH_TEMPLATE = """
Switch {{
inputs {0}
which {{{{colourspace_Pulldown_Choice}}}}
name colourspace_Switch
selected true
xpos 0
ypos 100
addUserKnob {{20 User}}
addUserKnob {{4 colourspace_Pulldown_Choice l Colourspace M {1}}}
}}
"""[1:-1]
def luminance_expression(colourspace):
equation = colour.RGB_luminance_equation(
colourspace.primaries, colourspace.whitepoint).split('=')[1]
equation = equation.strip().lower().replace('(', ' * ').replace(')', '')
return equation
EXPRESSIONS = []
RGB_COLOURSPACES = []
for i, (name, colourspace) in enumerate(
sorted(colour.RGB_COLOURSPACES.items())):
if name in ('aces', 'adobe1998', 'prophoto'):
continue
EXPRESSIONS.append(EXPRESSION_TEMPLATE.format(
luminance_expression(colourspace), name.replace(' ', '_'), i * 150))
RGB_COLOURSPACES.append('"{0}"'.format(name))
for expression in reversed(EXPRESSIONS):
print(expression)
print(SWITCH_TEMPLATE.format(len(RGB_COLOURSPACES),
'{{{0}}}'.format(' '.join(RGB_COLOURSPACES))))
In [ ]:
import numpy as np
import colour
SAMPLE_TEMPLATE = """
Group {{
inputs 0
name "{0}"
selected true
xpos {1}
ypos {2}
postage_stamp true
addUserKnob {{20 sample_Tab l Sample}}
addUserKnob {{20 parameters_Group l Parameters n 1}}
addUserKnob {{19 colour_RGBA_Color_Knob l Colour}}
colour_RGBA_Color_Knob {{{3} 1}}
addUserKnob {{6 colour_RGBA_Color_Knob_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}}
addUserKnob {{1 name_Text_Knob l Name}}
name_Text_Knob "{4}"
addUserKnob {{1 index_Text_Knob l Index}}
index_Text_Knob {5}
addUserKnob {{18 label_colour_RGB_Color_Knob l "Label Colour"}}
label_colour_RGB_Color_Knob 1
addUserKnob {{6 label_colour_RGB_Color_Knob_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}}
addUserKnob {{7 label_opacity_Floating_Point_Slider l "Label Opacity"}}
label_opacity_Floating_Point_Slider {{{{parent.label_opacity_Floating_Point_Slider}}}}
addUserKnob {{20 endGroup n -1}}
}}
Constant {{
inputs 0
color {{{{parent.colour_RGBA_Color_Knob.r}} {{parent.colour_RGBA_Color_Knob.g}} {{parent.colour_RGBA_Color_Knob.b}} {{parent.colour_RGBA_Color_Knob.a}}}}
format "512 512 0 0 512 512 1 square_512"
name Constant
xpos 262
ypos 53
}}
Text {{
opacity {{{{parent.label_opacity_Floating_Point_Slider}}}}
message "\[knob parent.name_Text_Knob]"
font "\[python nuke.defaultFontPathname()]"
xjustify center
yjustify bottom
Transform 1
box {{0 0 512 512}}
scale 1.15
center {{256 -256}}
color {{{{parent.label_colour_RGB_Color_Knob.r}} {{parent.label_colour_RGB_Color_Knob.g}} {{parent.label_colour_RGB_Color_Knob.b}} 1}}
name name_Text
xpos 262
ypos 125
}}
Text {{
opacity {{{{parent.label_opacity_Floating_Point_Slider}}}}
message "\[knob parent.index_Text_Knob]"
font "\[python nuke.defaultFontPathname()]"
xjustify center
yjustify center
Transform 1
box {{0 0 512 512}}
scale 3
center {{256 256}}
color {{{{parent.label_colour_RGB_Color_Knob.r}} {{parent.label_colour_RGB_Color_Knob.g}} {{parent.label_colour_RGB_Color_Knob.b}} 1}}
name index_Text
xpos 262
ypos 149
}}
Output {{
name Output
xpos 262
ypos 173
}}
end_group
"""[1:-1]
name, data, illuminant = colour.COLOURCHECKERS['ColorChecker24 - After November 2014']
x_pos = y_pos = 0
for i, (name, xyY) in enumerate(data.items()):
XYZ = colour.xyY_to_XYZ(xyY)
print(SAMPLE_TEMPLATE.format(name.replace(' ', '_'),
x_pos,
y_pos,
'{0} {1} {2}'.format(*XYZ),
name,
i + 1))
x_pos += 100
In [ ]:
import numpy as np
import colour
name, data, illuminant = colour.COLOURCHECKERS['ColorChecker 2005']
for name, xyY in data.items():
RGB = colour.XYZ_to_RGB(
colour.xyY_to_XYZ(xyY),
illuminant,
colour.ILLUMINANTS[
'CIE 1931 2 Degree Standard Observer']['D60'],
colour.ACES_2065_1_COLOURSPACE.XYZ_to_RGB_matrix,
'CAT02')
print('"{0}": {1}'.format(name, RGB))
In [ ]:
import numpy as np
import colour
ACES_ENCODINGS = {
'ACES2065-1': colour.RGB_COLOURSPACES['ACES2065-1'],
'ACEScc': colour.RGB_COLOURSPACES['ACEScc'],
'ACEScg': colour.RGB_COLOURSPACES['ACEScg'],
'ACESproxy': colour.RGB_COLOURSPACES['ACESproxy']}
NUKE_TEMPLATE = """
ColorMatrix {{
inputs 0
matrix {{
{0}
}}
name "{1}"
selected true
xpos {2}
ypos 100
}}
"""[1:-1]
SWITCH_TEMPLATE = """
Switch {{
inputs {0}
which {{{{colourspace_Pulldown_Choice}}}}
name colourspace_Switch
selected true
addUserKnob {{20 User}}
addUserKnob {{4 colourspace_Pulldown_Choice l Colourspace M {1}}}
}}
"""[1:-1]
def ACES_to_RGB(colourspace,
encoding='ACES2065-1',
transform='CAT02'):
encoding = ACES_ENCODINGS[encoding]
cat = colour.adaptation.chromatic_adaptation_matrix_VonKries(
colour.xy_to_XYZ(encoding.whitepoint),
colour.xy_to_XYZ(colourspace.whitepoint),
transform)
return (np.dot(colourspace.XYZ_to_RGB_matrix,
np.dot(cat, encoding.RGB_to_XYZ_matrix)))
def nk_format_matrix(M, precision=7):
pretty = lambda x: ' '.join(
map('{{:0.{}f}}'.format(precision).format, x))
nk = '{{{0}}}\n'.format(pretty(M[0]))
nk += '\t {{{0}}}\n'.format(pretty(M[1]))
nk += '\t {{{0}}}'.format(pretty(M[2]))
return nk
MATRICES = []
RGB_COLOURSPACES = []
for i, (name, colourspace) in enumerate(
sorted(colour.RGB_COLOURSPACES.items())):
if name in ('aces', 'adobe1998', 'prophoto'):
continue
M = ACES_to_RGB(colourspace)
MATRICES.append(NUKE_TEMPLATE.format(nk_format_matrix(M),
'ACES2065-1_to_{0}_ColorMatrix'.format(name.replace(' ', '_')),
i * 150))
RGB_COLOURSPACES.append('"{0}"'.format(name))
for matrices in reversed(MATRICES):
print(matrices)
print(SWITCH_TEMPLATE.format(len(RGB_COLOURSPACES),
'{{{0}}}'.format(' '.join(RGB_COLOURSPACES))))
In [ ]:
import numpy as np
import colour
NUKE_OUTER_GROUP_INPUT_TEMPLATE = """
Group {{
name XYZ_D50_to_RGB
selected true
xpos 0
ypos 0
addUserKnob {{20 XYZ_D50_to_RGB_Tab l "XYZ D50 to RGB"}}
addUserKnob {{20 colourspace_parameters_Begin_Group l "Colourspace Parameters" n 1}}
addUserKnob {{4 colourspace_Pulldown_Choice l Colourspace M {0}}}
addUserKnob {{20 parameters_endGroup l endGroup n -1}}
addUserKnob {{20 about_Tab l About}}
addUserKnob {{26 description_Text l "" +STARTLINE T "XYZ D50 to RGB v0.1.3\\n\\ncolour-science.org - November 25, 2018\\n\\nThis Gizmo / Group tranforms from CIE XYZ D50 tristimulus values to RGB colourspace using CAT02 chromatic adaptation transform."}}
}}
Input {{
inputs 0
name Input
xpos 0
ypos -150
}}
"""[1:-1]
NUKE_OUTER_GROUP_OUTPUT_TEMPLATE = """
Output {
name Output
xpos 0
ypos 150
}
end_group
"""[1:-1]
NUKE_INNER_GROUP_TEMPLATE = """
Group {{
name XYZ_D50_to_{0}
selected true
xpos {1}
ypos {2}
addUserKnob {{20 XYZ_D50_to_RGB_Tab l "XYZ D50 to {0}"}}
addUserKnob {{20 parameters_endGroup l endGroup n -1}}
addUserKnob {{20 about_Tab l About}}
addUserKnob {{26 description_Text l "" +STARTLINE T "XYZ D50 to {0} v0.1.3\\n\\ncolour-science.org - November 25, 2018\\n\\nThis Gizmo / Group transforms from CIE XYZ D50 tristimulus values to {0} colourspace using CAT02 chromatic adaptation transform."}}
}}
Input {{
inputs 0
name Input
xpos 0
ypos -150
}}
ColorMatrix {{
matrix {{
{3}
}}
name {4}_to_{5}_CAT02_ColorMatrix
xpos 0
ypos -125
}}
ColorMatrix {{
matrix {{
{6}
}}
name XYZ_to_{0}_ColorMatrix
xpos 0
ypos -100
}}
Output {{
name Output
xpos 0
ypos -75
}}
end_group
"""[1:-1]
SWITCH_TEMPLATE = """
Switch {{
inputs {0}
xpos 0
ypos 200
which {{{{parent.colourspace_Pulldown_Choice}}}}
name colourspace_Switch
selected true
addUserKnob {{20 User}}
addUserKnob {{4 colourspace_Pulldown_Choice l Colourspace M {1}}}
}}
"""[1:-1]
def nk_format_matrix(M, precision=7):
pretty = lambda x: ' '.join(map('{{:0.{}f}}'.format(precision).format, x))
nk = '{{{0}}}\n'.format(pretty(M[0]))
nk += '\t {{{0}}}\n'.format(pretty(M[1]))
nk += '\t {{{0}}}'.format(pretty(M[2]))
return nk
GROUPS = []
RGB_COLOURSPACES = []
for i, (name, colourspace) in enumerate(
sorted(colour.RGB_COLOURSPACES.items())):
if name in ('aces', 'adobe1998', 'prophoto'):
continue
M = colour.chromatic_adaptation_matrix_VonKries(
colour.xy_to_XYZ(colour.ILLUMINANTS['cie_2_1931']['D50']),
colour.xy_to_XYZ(colourspace.whitepoint),
transform='CAT02')
GROUPS.append(
NUKE_INNER_GROUP_TEMPLATE.format(
name.replace(' ', '_'), i * 150, 0, nk_format_matrix(M), 'D50',
colourspace.illuminant,
nk_format_matrix(colourspace.XYZ_to_RGB_matrix)))
RGB_COLOURSPACES.append('"{0}"'.format(name))
print(NUKE_OUTER_GROUP_INPUT_TEMPLATE.format('{{{0}}}'.format(' '.join(RGB_COLOURSPACES)), len(RGB_COLOURSPACES)))
print('set f3716e02 [stack 0]')
for i, group in enumerate(reversed(GROUPS)):
print(group)
if i == len(GROUPS) - 1:
break
print('push $f3716e02')
print(SWITCH_TEMPLATE.format(
len(RGB_COLOURSPACES), '{{{0}}}'.format(' '.join(RGB_COLOURSPACES))))
print(NUKE_OUTER_GROUP_OUTPUT_TEMPLATE)
In [ ]:
import numpy as np
import colour
NUKE_TEMPLATE = """
ColorMatrix {{
inputs 0
matrix {{
{0}
}}
name "{1}"
selected true
xpos {2}
ypos 100
}}
"""[1:-1]
SWITCH_TEMPLATE = """
Switch {{
inputs {0}
which {{{{colourspace_Pulldown_Choice}}}}
name colourspace_Switch
selected true
addUserKnob {{20 User}}
addUserKnob {{4 colourspace_Pulldown_Choice l Colourspace M {1}}}
}}
"""[1:-1]
def nk_format_matrix(M, precision=7):
pretty = lambda x: ' '.join(
map('{{:0.{}f}}'.format(precision).format, x))
nk = '{{{0}}}\n'.format(pretty(M[0]))
nk += '\t {{{0}}}\n'.format(pretty(M[1]))
nk += '\t {{{0}}}'.format(pretty(M[2]))
return nk
MATRICES = []
RGB_COLOURSPACES = []
for i, (name, colourspace) in enumerate(
sorted(colour.RGB_COLOURSPACES.items())):
if name in ('aces', 'adobe1998', 'prophoto'):
continue
M = colour.chromatic_adaptation_matrix_VonKries(
colour.xy_to_XYZ(colour.ILLUMINANTS['cie_2_1931']['D50']),
colour.xy_to_XYZ(colourspace.whitepoint),
transform='CAT02')
print(NUKE_TEMPLATE.format(nk_format_matrix(M),
'D50_to_{0}_CAT02_ColorMatrix'.format(colourspace.illuminant),
i * 150))
print(NUKE_TEMPLATE.format(nk_format_matrix(colourspace.XYZ_to_RGB_matrix),
'XYZ_to_{0}_CAT02_ColorMatrix'.format(name.replace(' ', '_')),
i * 150))
break
# MATRICES.append(NUKE_TEMPLATE.format(nk_format_matrix(M),
# 'D50_to_{0}_CAT02_ColorMatrix'.format(colourspace.illuminant),
# i * 150))
# RGB_COLOURSPACES.append('"{0}"'.format(name))
for matrices in reversed(MATRICES):
print(matrices)
# print(SWITCH_TEMPLATE.format(len(RGB_COLOURSPACES),
# '{{{0}}}'.format(' '.join(RGB_COLOURSPACES))))
In [ ]:
DIRECTORY = '/Users/kelsolaar/Documents/Development/colour-science/colour-nuke/colour_nuke/resources/images/TMP'
def sanitise(string):
return string.replace('/', '_').replace(' ', '_')
cc = nuke.toNode('Colour_Rendition_Chart')
for value in cc.knob('colourspace_Pulldown_Choice').values():
cc.knob('colourspace_Pulldown_Choice').setValue(value)
cc.knob('label_opacity_Floating_Point_Slider').setValue(0)
write = nuke.toNode('Write')
filename = os.path.join(DIRECTORY, '{0}_ColorChecker2005.exr'.format(sanitise(value)))
write.knob('file').setValue(filename)
nuke.execute(write, 1, 1, 1)
cc.knob('label_opacity_Floating_Point_Slider').setValue(1)
filename = os.path.join(DIRECTORY, '{0}_Labels_ColorChecker2005.exr'.format(sanitise(value)))
write.knob('file').setValue(filename)
nuke.execute(write, 1, 1, 1)