From 2389dd46c42bd0a218efcfce4180b3dfd37249ba Mon Sep 17 00:00:00 2001 From: mfe Date: Fri, 18 Oct 2013 18:19:35 +0200 Subject: [PATCH 1/2] Add 3D cube export to lut_to_lut #6 --- lutLab/lut_to_lut.py | 52 +++++++++++++++++++++++++++++--------------- utils/cube_helper.py | 43 ++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 17 deletions(-) diff --git a/lutLab/lut_to_lut.py b/lutLab/lut_to_lut.py index 5870e8d..37e4982 100755 --- a/lutLab/lut_to_lut.py +++ b/lutLab/lut_to_lut.py @@ -8,8 +8,11 @@ import argparse from utils.ocio_helper import OCIO_LUTS_FORMATS, create_ocio_processor from utils.csp_helper import write_2d_csp_lut -from utils.cube_helper import write_2d_cube_lut +from utils.cube_helper import write_2d_cube_lut, write_3d_cube_lut from utils.lut_utils import get_default_out_path +from PyOpenColorIO.Constants import ( + INTERP_LINEAR, INTERP_TETRAHEDRAL +) class LutToLutException(Exception): @@ -17,7 +20,7 @@ class LutToLutException(Exception): def lut_to_lut(inlutfile, outlutfile=None, type='1D_CUBE', - lutsize=16): + lutsize=16, cubesize=17): """Extract the tone mapping curve of a 3D LUT Args: @@ -30,35 +33,45 @@ def lut_to_lut(inlutfile, outlutfile=None, type='1D_CUBE', type (str): specify output LUT format. For now only 2D csp and 2D cube are available. - lutsize (int): out LUT bit precision. Ex : 16 (bits) + lutsize (int): out LUT bit precision for 1D. Ex : 16 (bits) """ samples_count = pow(2, lutsize) if type == '1D_CUBE': ext = ".cube" write_function = write_2d_cube_lut + interp = INTERP_LINEAR + elif type == '3D_CUBE': + ext = ".cube" + write_function = write_3d_cube_lut + interp = INTERP_TETRAHEDRAL elif type == '1D_CSP': ext = ".csp" write_function = write_2d_csp_lut + interp = INTERP_LINEAR else: raise LutToLutException("Unsupported export format!") if not outlutfile: outlutfile = get_default_out_path(inlutfile, ext) - processor = create_ocio_processor(inlutfile) - # init vars + processor = create_ocio_processor(inlutfile, interpolation=interp) + # init vars max_value = samples_count - 1.0 red_values = [] green_values = [] blue_values = [] - # process color values - for n in range(0, samples_count): - x = n/max_value - res = processor.applyRGB([x, x, x]) - red_values.append(res[0]) - green_values.append(res[1]) - blue_values.append(res[2]) - # write - write_function(outlutfile, red_values, green_values, blue_values) + if "1D" in type: + # process color values + for n in range(0, samples_count): + x = n/max_value + res = processor.applyRGB([x, x, x]) + red_values.append(res[0]) + green_values.append(res[1]) + blue_values.append(res[2]) + # write + write_function(outlutfile, red_values, green_values, blue_values) + elif "3D" in type: + # write + write_function(outlutfile, cubesize, processor) def __get_options(): @@ -83,11 +96,16 @@ def __get_options(): parser.add_argument("-t", "--out-type", help=("Output LUT type."), type=str, - choices=['1D_CSP', '1D_CUBE'], default='1D_CUBE') + choices=['1D_CSP', '1D_CUBE', '3D_CUBE'], + default='1D_CUBE') # out lut size - parser.add_argument("-os", "--outlut-size", help=( + parser.add_argument("-os", "--out-lut-size", help=( "Output lut bit precision. Ex : 10, 16, 32." ), default=16, type=int) + # out cube size + parser.add_argument("-ocs", "--out-cube-size", help=( + "Output cube size (3D only). Ex : 17, 32." + ), default=17, type=int) return parser.parse_args() if __name__ == '__main__': @@ -95,4 +113,4 @@ def __get_options(): """ args = __get_options() lut_to_lut(args.inlutfile, args.outlutfile, args.out_type, - args.outlut_size) + args.out_lut_size, args.out_cube_size) diff --git a/utils/cube_helper.py b/utils/cube_helper.py index 6be36af..9ce3631 100644 --- a/utils/cube_helper.py +++ b/utils/cube_helper.py @@ -69,3 +69,46 @@ def write_1d_cube_lut(filename, values, comment=None, title="Iridas LUT"): title (str): title of the LUT """ write_2d_cube_lut(filename, values, comment, title) + + +def write_3d_cube_lut(filename, cubesize, processor, + comment=None, title="Cube LUT"): + """Write a 3D Cube LUT + + Args: + filename (str): out LUT path + + cubesize (int): cube size. Ex: 17, 32... + + processor (PyOpenColorIO.config.Processor): an OpenColorIO processor + + Kwargs: + comment (str): an optionnal comment + + title (str): title of the LUT + + """ + f = open(filename, 'w+') + # comment + if comment: + f.write("#{0}\n".format(comment)) + # title + f.write("TITLE {0}\n\n".format(title)) + # lut size + f.write("{0} {1}\n\n".format(CUBE_3D, cubesize)) + input_range = range(0, cubesize) + max_value = cubesize - 1.0 + # process color values + for b in input_range: + for g in input_range: + for r in input_range: + # get a value between [0..1] + norm_r = r/max_value + norm_g = g/max_value + norm_b = b/max_value + # apply correction via OCIO + res = processor.applyRGB([norm_r, norm_g, norm_b]) + f.write("{0:.6f} {1:.6f} {2:.6f}\n".format(res[0], + res[1], + res[2])) + f.close() From 33981961276a3da9c6059029150987ad0663c1ab Mon Sep 17 00:00:00 2001 From: mfe Date: Fri, 18 Oct 2013 18:23:13 +0200 Subject: [PATCH 2/2] Update doc fixes #6 --- lutLab/README.md | 2 +- lutLab/lut_to_lut.py | 4 ++-- utils/cube_helper.py | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lutLab/README.md b/lutLab/README.md index 0cbd0ca..f05b257 100644 --- a/lutLab/README.md +++ b/lutLab/README.md @@ -8,7 +8,7 @@ It uses [OpenColorIO](http://opencolorio.org/) to read and process input LUTs. Available scripts : -- **lut_to_lut**: convert a lut into another format. For now, only conversion to 1D/2D cube or 1D/2D csp is supported +- **lut_to_lut**: convert a lut into another format. For now, only conversion to 1D/2D/3D cube or 1D/2D csp is supported - **ext_1d_lut**: extract the tone mapping curve of a 3D LUT using a bicubic interpolation (or not) diff --git a/lutLab/lut_to_lut.py b/lutLab/lut_to_lut.py index 37e4982..a272e1e 100755 --- a/lutLab/lut_to_lut.py +++ b/lutLab/lut_to_lut.py @@ -30,8 +30,8 @@ def lut_to_lut(inlutfile, outlutfile=None, type='1D_CUBE', outlutfile (str): the output 1D LUT. If not define, LUT is written in the input LUT directory and post-fixed with "_export" - type (str): specify output LUT format. For now only 2D csp and 2D cube - are available. + type (str): specify output LUT format. For now only 2D/3D csp and 2D + cube are available. lutsize (int): out LUT bit precision for 1D. Ex : 16 (bits) diff --git a/utils/cube_helper.py b/utils/cube_helper.py index 9ce3631..fde02cf 100644 --- a/utils/cube_helper.py +++ b/utils/cube_helper.py @@ -67,6 +67,7 @@ def write_1d_cube_lut(filename, values, comment=None, title="Iridas LUT"): comment (str): an optionnal comment title (str): title of the LUT + """ write_2d_cube_lut(filename, values, comment, title)