def plot_that_lut(lutfile, plot_type=None, count=None, inverse=False, prelutfile=None, postlutfile=None): """Plot a lut depending on its type and/or args Args: lutfile (str): path to a color transformation file (lut, matrix...) kwargs: plot_type (str): possible values are 'curve' or 'cube' count: possible values are curve size or curve samples count or 'auto' prelutfile (str): path to a pre LUT postlutfile (str): path to a post LUT Raises: PlotThatLutException Exception from OpenColorIO binding """ set_matplotlib_backend() # check if LUT format is supported fileext = os.path.splitext(lutfile)[1] if not fileext: raise PlotThatLutException(( "Error: Couldn't extract extension in this\n" "path : {0}" ).format(lutfile)) if fileext not in OCIO_LUTS_FORMATS: raise PlotThatLutException("Error: {0} file aren't supported.\n{1}" .format(fileext, supported_formats())) # create OCIO processor processor = create_ocio_processor(lutfile, 0, inverse, prelutfile, postlutfile) # init args if not plot_type or plot_type == 'auto': if is_3d_lut(processor, lutfile): plot_type = 'cube' else: plot_type = 'curve' if not count or count == 'auto': # set plot_type from the command line and init default count if plot_type == 'curve': count = DEFAULT_SAMPLE else: count = DEFAULT_CUBE_SIZE # plot print "Plotting a {0} with {1} samples...".format(plot_type, count) if plot_type == 'curve': return plot_curve(lutfile, count, processor) elif plot_type == 'cube': return plot_cube(lutfile, count, processor) else: raise PlotThatLutException(( "Unknown plot type : {0}\n" "Plot type should be curve or cube.\n" ).format(plot_type))
def plot_that_lut(lutfiles, plot_type=None, count=None, inverse=False, prelutfile=None, postlutfile=None, display_markers=False): """Plot a lut depending on its type and/or args Args: lutfiles (str): pathes to color transformation files (lut, matrix...) kwargs: plot_type (str): possible values are 'curve' or 'cube' count: possible values are curve size or curve samples count or 'auto' prelutfile (str): path to a pre LUT postlutfile (str): path to a post LUT display_markers (bool): should display markers on curve Raises: PlotThatLutException Exception from OpenColorIO binding """ if not isinstance(lutfiles, list): lutfiles = [lutfiles] mplh.set_matplotlib_backend() processors = [] for lutfile in lutfiles: # check if LUT format is supported fileext = os.path.splitext(lutfile)[1] if not fileext: raise PlotThatLutException( ("Error: Couldn't extract extension in this\n" "path : {0}").format(lutfile)) if fileext not in OCIO_LUTS_FORMATS: raise PlotThatLutException( "Error: {0} file aren't supported.\n{1}".format( fileext, supported_formats())) # create OCIO processor processors.append( create_ocio_processor(lutfile, INTERP_LINEAR, inverse, prelutfile, postlutfile)) # init args if not plot_type or plot_type == 'auto': # deduce plot type considering first lutfile if is_3d_lut(processors[0], lutfiles[0]): plot_type = 'cube' else: plot_type = 'curve' if not count or count == 'auto': # set plot_type from the command line and init default count if 'curve' in plot_type: count = DEFAULT_SAMPLE else: count = DEFAULT_CUBE_SIZE # plot print "Plotting a {0} with {1} samples...".format(plot_type, count) if 'curve' in plot_type: draw_red_curve = True draw_green_curve = True draw_blue_curve = True if 'red' in plot_type: #red_curve option draw_green_curve = False draw_blue_curve = False elif 'green' in plot_type: #green_curve option draw_red_curve = False draw_blue_curve = False elif 'blue' in plot_type: #blue_curve option draw_red_curve = False draw_green_curve = False return plot_curve(lutfiles, count, processors, draw_red_curve=draw_red_curve, draw_green_curve=draw_green_curve, draw_blue_curve=draw_blue_curve, display_markers=display_markers) elif plot_type == 'cube': # TODO support multiple cubes display return plot_cube(lutfiles[0], count, processors[0]) else: raise PlotThatLutException( ("Unknown plot type : {0}\n" "Plot type should be curve or cube.\n").format(plot_type))
def plot_that_lut(lutfiles, plot_type=None, count=None, inverse=False, prelutfile=None, postlutfile=None, display_markers=False): """Plot a lut depending on its type and/or args Args: lutfiles (str): pathes to color transformation files (lut, matrix...) kwargs: plot_type (str): possible values are 'curve' or 'cube' count: possible values are curve size or curve samples count or 'auto' prelutfile (str): path to a pre LUT postlutfile (str): path to a post LUT display_markers (bool): should display markers on curve Raises: PlotThatLutException Exception from OpenColorIO binding """ if not isinstance(lutfiles, list): lutfiles = [lutfiles] mplh.set_matplotlib_backend() processors = [] for lutfile in lutfiles: # check if LUT format is supported fileext = os.path.splitext(lutfile)[1] if not fileext: raise PlotThatLutException(( "Error: Couldn't extract extension in this\n" "path : {0}" ).format(lutfile)) if fileext not in OCIO_LUTS_FORMATS: raise PlotThatLutException("Error: {0} file aren't supported.\n{1}" .format(fileext, supported_formats())) # create OCIO processor processors.append(create_ocio_processor(lutfile, INTERP_LINEAR, inverse, prelutfile, postlutfile)) # init args if not plot_type or plot_type == 'auto': # deduce plot type considering first lutfile if is_3d_lut(processors[0], lutfiles[0]): plot_type = 'cube' else: plot_type = 'curve' if not count or count == 'auto': # set plot_type from the command line and init default count if 'curve' in plot_type: count = DEFAULT_SAMPLE else: count = DEFAULT_CUBE_SIZE # plot print "Plotting a {0} with {1} samples...".format(plot_type, count) if 'curve' in plot_type: draw_red_curve = True draw_green_curve = True draw_blue_curve = True if 'red' in plot_type: #red_curve option draw_green_curve = False draw_blue_curve = False elif 'green' in plot_type: #green_curve option draw_red_curve = False draw_blue_curve = False elif 'blue' in plot_type: #blue_curve option draw_red_curve = False draw_green_curve = False return plot_curve(lutfiles, count, processors, draw_red_curve=draw_red_curve, draw_green_curve=draw_green_curve, draw_blue_curve=draw_blue_curve, display_markers=display_markers) elif plot_type == 'cube': # TODO support multiple cubes display return plot_cube(lutfiles[0], count, processors[0]) else: raise PlotThatLutException(( "Unknown plot type : {0}\n" "Plot type should be curve or cube.\n" ).format(plot_type))
def lut_to_lut(inlutfiles, out_type=None, out_format=None, outlutfile=None, input_range=None, output_range=None, out_bit_depth=None, inverse=False, out_cube_size=None, verbose=False, smooth_size=None, preset=None, overwrite_preset=False): """ Concert a LUT in another LUT Arguments testing are delegated to LUT helpers Args: lutfiles (str or [str]): path to a LUT or list of LUT paths out_type (str): 1D, 2D or 3D out_format (str): '3dl', 'csp', 'cube', 'lut', 'spi', 'clcc', 'json'... Kwargs: outlutfile (str): path to output LUT input_range ([int/float, int/float]): input range. Ex: [0.0, 1.0] or [0, 4095] output_range ([int/float, int/float]): output range. Ex: [0.0, 1.0] or [0, 4095] out_bit_depth (int): output lut bit precision (1D only). Ex : 10, 16, 32. inverse (bool): inverse input LUT (1D only) out_cube_size (int): output cube size (3D only). Ex : 17, 32. verbose (bool): print log if true smooth_size (int): smooth exported LUT (1D only). Specify how many points are computed. A first subsampled curve is first processed and then resample with a smooth to fit input lutsize. So the smaller this value is, the smoother the curve will be. Ex: 10, 20,... preset (dict): lut generic and sampling informations """ if preset: write_function = get_write_function(preset, overwrite_preset, out_type, out_format, input_range, output_range, out_bit_depth, out_cube_size, verbose) elif out_type is None or out_format is None: raise LutToLutException("Specify out_type/out_format or a preset.") else: preset, write_function = get_preset_and_write_function( out_type, out_format, input_range, output_range, out_bit_depth, out_cube_size) ext = preset[presets.EXT] if not isinstance(inlutfiles, (list, tuple)): inlutfiles = [inlutfiles] if not outlutfile: outlutfile = get_default_out_path(inlutfiles, ext) elif os.path.isdir(outlutfile): filename = os.path.splitext(ntpath.basename(inlutfiles[0]))[0] + ext outlutfile = os.path.join(outlutfile, filename) else: check_extension(outlutfile, ext) # smooth if smooth_size: preset[presets.SMOOTH] = smooth_size if verbose: print "{0} will be converted into {1}.".format(inlutfiles, outlutfile) print "Final setting:\n{0}".format(presets.string_preset(preset)) processor = create_ocio_processor(inlutfiles, interpolation=INTERP_LINEAR, inverse=inverse) # change interpolation if 3D LUT if is_3d_lut(processor, inlutfiles[0]): processor = create_ocio_processor(inlutfiles, interpolation=INTERP_TETRAHEDRAL, inverse=inverse) # write LUT message = write_function(processor.applyRGB, outlutfile, preset) if verbose: print_success_message(message)
def lut_to_lut(inlutfiles, out_type=None, out_format=None, outlutfile=None, input_range=None, output_range=None, out_bit_depth=None, inverse=False, out_cube_size=None, verbose=False, smooth_size=None, preset=None, overwrite_preset=False): """ Concert a LUT in another LUT Arguments testing are delegated to LUT helpers Args: lutfiles (str or [str]): path to a LUT or list of LUT paths out_type (str): 1D, 2D or 3D out_format (str): '3dl', 'csp', 'cube', 'lut', 'spi', 'clcc', 'json'... Kwargs: outlutfile (str): path to output LUT input_range ([int/float, int/float]): input range. Ex: [0.0, 1.0] or [0, 4095] output_range ([int/float, int/float]): output range. Ex: [0.0, 1.0] or [0, 4095] out_bit_depth (int): output lut bit precision (1D only). Ex : 10, 16, 32. inverse (bool): inverse input LUT (1D only) out_cube_size (int): output cube size (3D only). Ex : 17, 32. verbose (bool): print log if true smooth_size (int): smooth exported LUT (1D only). Specify how many points are computed. A first subsampled curve is first processed and then resample with a smooth to fit input lutsize. So the smaller this value is, the smoother the curve will be. Ex: 10, 20,... preset (dict): lut generic and sampling informations """ if preset: write_function = get_write_function(preset, overwrite_preset, out_type, out_format, input_range, output_range, out_bit_depth, out_cube_size, verbose) elif out_type is None or out_format is None: raise LutToLutException("Specify out_type/out_format or a preset.") else: preset, write_function = get_preset_and_write_function(out_type, out_format, input_range, output_range, out_bit_depth, out_cube_size) ext = preset[presets.EXT] if not isinstance(inlutfiles, (list, tuple)): inlutfiles = [inlutfiles] if not outlutfile: outlutfile = get_default_out_path(inlutfiles, ext) elif os.path.isdir(outlutfile): filename = os.path.splitext(ntpath.basename(inlutfiles[0]))[0] + ext outlutfile = os.path.join(outlutfile, filename) else: check_extension(outlutfile, ext) # smooth if smooth_size: preset[presets.SMOOTH] = smooth_size if verbose: print "{0} will be converted into {1}.".format(inlutfiles, outlutfile) print "Final setting:\n{0}".format(presets.string_preset(preset)) processor = create_ocio_processor(inlutfiles, interpolation=INTERP_LINEAR, inverse=inverse) # change interpolation if 3D LUT if is_3d_lut(processor, inlutfiles[0]): processor = create_ocio_processor(inlutfiles, interpolation=INTERP_TETRAHEDRAL, inverse=inverse) # write LUT message = write_function(processor.applyRGB, outlutfile, preset) if verbose: print_success_message(message)
def extract_1d_lut(inlutfile, lutsize, outlutfile=None, smooth=False, smooth_size=17, display=False): """Extract the tone mapping curve of a 3D LUT Args: inlutfile (str): an input 3D LUT lutsize (int): out 1D LUT bit precision. Ex : 16 (bits) Kwargs: outlutfile (str): the output 1D lut. If not define, LUT is written in the input LUT directory and post-fixed with "_export" smooth (bool): smooth the resulting curve with a bicubic monotonic interpolation. See also smooth_size. smooth_size (int): only used when smooth is true. Specify how many points are sampled using OpenColorIO processor. The result curve is then smoothed and resample to fit input lutsize. So the smaller this value is, the smoother the curve will be. """ if not outlutfile: outlutfile = get_default_out_path(inlutfile, ".csp") # create OCIO processor processor = create_ocio_processor(inlutfile) if not is_3d_lut(processor, inlutfile): raise Ext1DLutException("Input lut must be a 3D LUT !") # init vars if smooth: # subsample OCIO processed curve count = smooth_size else: count = pow(2, lutsize) max_value = count - 1.0 red_values = [] green_values = [] blue_values = [] for n in range(0, 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]) if smooth: # get full range xnew = numpy.arange(0, max_value, float(count-1)/(pow(2, lutsize))) # get a monotonic cubic function from subsampled curve red_cubic_monotonic_func = PchipInterpolator(numpy.arange(0, count), red_values) green_cubic_monotonic_func = PchipInterpolator(numpy.arange(0, count), green_values) blue_cubic_monotonic_func = PchipInterpolator(numpy.arange(0, count), blue_values) # sample on the full range reds = red_cubic_monotonic_func(xnew) greens = green_cubic_monotonic_func(xnew) blues = blue_cubic_monotonic_func(xnew) else: reds = red_values greens = green_values blues = blue_values write_2d_csp_lut(outlutfile, reds, greens, blues) if display: try: # init plot from matplotlib.pyplot import (title, plot, grid, figure, show) except: raise Ext1DLutException("Install matplotlib to use display option") fig = figure() fig.canvas.set_window_title('Plot That 1D LUT') title("Compare") grid(True) # plot curves plot(reds, 'r-', label='numpy', linewidth=1) plot(greens, 'g-', label='numpy', linewidth=1) plot(blues, 'b-', label='numpy', linewidth=1) show()
def extract_1d_lut(inlutfile, lutsize, outlutfile=None, smooth=False, smooth_size=17, display=False): """Extract the tone mapping curve of a 3D LUT Args: inlutfile (str): an input 3D LUT lutsize (int): out 1D LUT bit precision. Ex : 16 (bits) Kwargs: outlutfile (str): the output 1D lut. If not define, LUT is written in the input LUT directory and post-fixed with "_export" smooth (bool): smooth the resulting curve with a bicubic monotonic interpolation. See also smooth_size. smooth_size (int): only used when smooth is true. Specify how many points are sampled using OpenColorIO processor. The result curve is then smoothed and resample to fit input lutsize. So the smaller this value is, the smoother the curve will be. """ if not outlutfile: outlutfile = get_default_out_path(inlutfile, ".csp") # create OCIO processor processor = create_ocio_processor(inlutfile) if not is_3d_lut(processor, inlutfile): raise Ext1DLutException("Input lut must be a 3D LUT !") # init vars if smooth: # subsample OCIO processed curve count = smooth_size else: count = pow(2, lutsize) max_value = count - 1.0 red_values = [] green_values = [] blue_values = [] for code_value in range(0, count): norm_value = code_value / max_value res = processor.applyRGB([norm_value, norm_value, norm_value]) red_values.append(res[0]) green_values.append(res[1]) blue_values.append(res[2]) if smooth: # get full range xnew = numpy.arange(0, max_value, float(count - 1) / (pow(2, lutsize))) # get a monotonic cubic function from subsampled curve red_cubic_monotonic_func = PchipInterpolator(numpy.arange(0, count), red_values) green_cubic_monotonic_func = PchipInterpolator(numpy.arange(0, count), green_values) blue_cubic_monotonic_func = PchipInterpolator(numpy.arange(0, count), blue_values) # sample on the full range reds = red_cubic_monotonic_func(xnew) greens = green_cubic_monotonic_func(xnew) blues = blue_cubic_monotonic_func(xnew) else: reds = red_values greens = green_values blues = blue_values write_2d_csp_lut(outlutfile, reds, greens, blues) if display: try: # init plot from matplotlib.pyplot import (title, plot, grid, figure, show) except: raise Ext1DLutException("Install matplotlib to use display option") fig = figure() fig.canvas.set_window_title('Plot That 1D LUT') title("Compare") grid(True) # plot curves plot(reds, 'r-', label='numpy', linewidth=1) plot(greens, 'g-', label='numpy', linewidth=1) plot(blues, 'b-', label='numpy', linewidth=1) show()