Skip to content
This repository was archived by the owner on Nov 22, 2019. It is now read-only.

Commit 7b59ae1

Browse files
author
mfe
committed
Merge branch 'feature/add_3Dcube_export' into develop
2 parents a6d4965 + 3398196 commit 7b59ae1

File tree

3 files changed

+82
-20
lines changed

3 files changed

+82
-20
lines changed

lutLab/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ It uses [OpenColorIO](http://opencolorio.org/) to read and process input LUTs.
88

99
Available scripts :
1010

11-
- **lut_to_lut**: convert a lut into another format. For now, only conversion to 1D/2D cube or 1D/2D csp is supported
11+
- **lut_to_lut**: convert a lut into another format. For now, only conversion to 1D/2D/3D cube or 1D/2D csp is supported
1212

1313
- **ext_1d_lut**: extract the tone mapping curve of a 3D LUT using a bicubic interpolation (or not)
1414

lutLab/lut_to_lut.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@
88
import argparse
99
from utils.ocio_helper import OCIO_LUTS_FORMATS, create_ocio_processor
1010
from utils.csp_helper import write_2d_csp_lut
11-
from utils.cube_helper import write_2d_cube_lut
11+
from utils.cube_helper import write_2d_cube_lut, write_3d_cube_lut
1212
from utils.lut_utils import get_default_out_path
13+
from PyOpenColorIO.Constants import (
14+
INTERP_LINEAR, INTERP_TETRAHEDRAL
15+
)
1316

1417

1518
class LutToLutException(Exception):
1619
pass
1720

1821

1922
def lut_to_lut(inlutfile, outlutfile=None, type='1D_CUBE',
20-
lutsize=16):
23+
lutsize=16, cubesize=17):
2124
"""Extract the tone mapping curve of a 3D LUT
2225
2326
Args:
@@ -27,38 +30,48 @@ def lut_to_lut(inlutfile, outlutfile=None, type='1D_CUBE',
2730
outlutfile (str): the output 1D LUT. If not define, LUT is written in
2831
the input LUT directory and post-fixed with "_export"
2932
30-
type (str): specify output LUT format. For now only 2D csp and 2D cube
31-
are available.
33+
type (str): specify output LUT format. For now only 2D/3D csp and 2D
34+
cube are available.
3235
33-
lutsize (int): out LUT bit precision. Ex : 16 (bits)
36+
lutsize (int): out LUT bit precision for 1D. Ex : 16 (bits)
3437
3538
"""
3639
samples_count = pow(2, lutsize)
3740
if type == '1D_CUBE':
3841
ext = ".cube"
3942
write_function = write_2d_cube_lut
43+
interp = INTERP_LINEAR
44+
elif type == '3D_CUBE':
45+
ext = ".cube"
46+
write_function = write_3d_cube_lut
47+
interp = INTERP_TETRAHEDRAL
4048
elif type == '1D_CSP':
4149
ext = ".csp"
4250
write_function = write_2d_csp_lut
51+
interp = INTERP_LINEAR
4352
else:
4453
raise LutToLutException("Unsupported export format!")
4554
if not outlutfile:
4655
outlutfile = get_default_out_path(inlutfile, ext)
47-
processor = create_ocio_processor(inlutfile)
48-
# init vars
56+
processor = create_ocio_processor(inlutfile, interpolation=interp)
57+
# init vars
4958
max_value = samples_count - 1.0
5059
red_values = []
5160
green_values = []
5261
blue_values = []
53-
# process color values
54-
for n in range(0, samples_count):
55-
x = n/max_value
56-
res = processor.applyRGB([x, x, x])
57-
red_values.append(res[0])
58-
green_values.append(res[1])
59-
blue_values.append(res[2])
60-
# write
61-
write_function(outlutfile, red_values, green_values, blue_values)
62+
if "1D" in type:
63+
# process color values
64+
for n in range(0, samples_count):
65+
x = n/max_value
66+
res = processor.applyRGB([x, x, x])
67+
red_values.append(res[0])
68+
green_values.append(res[1])
69+
blue_values.append(res[2])
70+
# write
71+
write_function(outlutfile, red_values, green_values, blue_values)
72+
elif "3D" in type:
73+
# write
74+
write_function(outlutfile, cubesize, processor)
6275

6376

6477
def __get_options():
@@ -83,16 +96,21 @@ def __get_options():
8396
parser.add_argument("-t", "--out-type",
8497
help=("Output LUT type."),
8598
type=str,
86-
choices=['1D_CSP', '1D_CUBE'], default='1D_CUBE')
99+
choices=['1D_CSP', '1D_CUBE', '3D_CUBE'],
100+
default='1D_CUBE')
87101
# out lut size
88-
parser.add_argument("-os", "--outlut-size", help=(
102+
parser.add_argument("-os", "--out-lut-size", help=(
89103
"Output lut bit precision. Ex : 10, 16, 32."
90104
), default=16, type=int)
105+
# out cube size
106+
parser.add_argument("-ocs", "--out-cube-size", help=(
107+
"Output cube size (3D only). Ex : 17, 32."
108+
), default=17, type=int)
91109
return parser.parse_args()
92110

93111
if __name__ == '__main__':
94112
""" Command line interface
95113
"""
96114
args = __get_options()
97115
lut_to_lut(args.inlutfile, args.outlutfile, args.out_type,
98-
args.outlut_size)
116+
args.out_lut_size, args.out_cube_size)

utils/cube_helper.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,49 @@ def write_1d_cube_lut(filename, values, comment=None, title="Iridas LUT"):
6767
comment (str): an optionnal comment
6868
6969
title (str): title of the LUT
70+
7071
"""
7172
write_2d_cube_lut(filename, values, comment, title)
73+
74+
75+
def write_3d_cube_lut(filename, cubesize, processor,
76+
comment=None, title="Cube LUT"):
77+
"""Write a 3D Cube LUT
78+
79+
Args:
80+
filename (str): out LUT path
81+
82+
cubesize (int): cube size. Ex: 17, 32...
83+
84+
processor (PyOpenColorIO.config.Processor): an OpenColorIO processor
85+
86+
Kwargs:
87+
comment (str): an optionnal comment
88+
89+
title (str): title of the LUT
90+
91+
"""
92+
f = open(filename, 'w+')
93+
# comment
94+
if comment:
95+
f.write("#{0}\n".format(comment))
96+
# title
97+
f.write("TITLE {0}\n\n".format(title))
98+
# lut size
99+
f.write("{0} {1}\n\n".format(CUBE_3D, cubesize))
100+
input_range = range(0, cubesize)
101+
max_value = cubesize - 1.0
102+
# process color values
103+
for b in input_range:
104+
for g in input_range:
105+
for r in input_range:
106+
# get a value between [0..1]
107+
norm_r = r/max_value
108+
norm_g = g/max_value
109+
norm_b = b/max_value
110+
# apply correction via OCIO
111+
res = processor.applyRGB([norm_r, norm_g, norm_b])
112+
f.write("{0:.6f} {1:.6f} {2:.6f}\n".format(res[0],
113+
res[1],
114+
res[2]))
115+
f.close()

0 commit comments

Comments
 (0)