Back to Publications

bLUe: An Extensible 3D LUT Editor

Table of contents

bLUe: An Extensible 3D LUT Editor

Author: Bernard Virot

Abstract

The "bLUe" editor is a Python-based platform designed to simplify the
development and testing of image processing techniques. Leveraging PySide6
for GUI construction and Numpy for computational tasks, it provides a modular,
layer-based architecture that enables real-time parameter adjustments
and seamless integration with Python-compatible image libraries.
With features like stackable layers, advanced color management,
and an intuitive GUI, "bLUe" facilitates both professional and experimental
workflows for image editing. Its extensibility allows users to incorporate
new image processing techniques with ease, making it a robust tool for
developers and researchers alike.

Introduction

"bLUe" is a powerful editor for 3D LUT (Look-Up Table)
manipulation, designed to bridge the gap between advanced
image processing and user-friendly interfaces.
Built on Python technologies such as PySide6 and Numpy,
the platform offers a modular, extensible framework
that supports Python-compatible libraries.
By allowing real-time visualization of adjustments, "bLUe"
enhances user productivity and enables rapid experimentation with
image processing workflows.

Key Features

Modular Architecture with Layer Stack

"bLUe" employs a layer-based processing system. Each layer represents a
processing step : it processes an
input image, and stores the output image. A layer can be visible or hidden.
Each layer holds an opacity value, a blending mode, and a mask.
Several layers can be stacked.
They act as a pipeline, computing the final image by blending the visible layers,
from bottom to top.

A background layer, holding the initial image, is added at the
bottom of the stack, and all layers must be the same size.

For large-scale images or computationally intensive tasks,
a preview mode speeds up processing without compromising the workflow.

Intuitive GUI

The GUI is designed for seamless interaction with processing parameters.
Each layer has a dedicated view that reflects real-time changes,
ensuring immediate feedback. The platform’s user-friendly interface
is built with Qt for Python (PySide6), offering features like contextual
help for accessibility.

Flexible Data Structures

The editor’s core data structures include:

  • bImage: Extends QImage to handle image processing workflows.
  • QLayer: Represents a processing layer, inheriting from QImage and providing
    transformation methods.
  • baseForm and baseGraphicsForm: Simplify GUI interactions,
    supporting standard widgets and graphical elements, respectively.
  • imImage: Extends bImage to handle the stack of processing layers.

The following UML diagram illustrates the relationship between these classes:

classDiagram class `imImage` imImage: layersStack class `bImage` class `baseForm` class baseGraphicsForm class `QLayer` QLayer: execute QLayer: rPixmap QLayer: parentImage QLayer: getGraphicsForm() QLayer: getCurrentImage() QLayer: getCurrentMaskedImage() QLayer: inputImg() `bImage` --> `QLayer` `bImage` --> `imImage`

Code Example

The following Python code snippet illustrates how layers are blended to
produce the final output image:

def getCurrentMaskedImage(self):
    """
    
    Blend the layer stack up to the current layer (included), considering 
    blending modes, opacities and masks.

    :return: Blended image
    :rtype: bImage
    """
    # Initialization
    if self.maskedThumbContainer is None:
        self.maskedThumbContainer = bImage.fromImage(self.getThumb(), parentImage=self.parentImage)
    # Reset container
    img = self.maskedThumbContainer
    img.fill(QColor(0, 0, 0, 0))
    # Blend layers
    qp = QPainter(img)
    for layer in self.parentImage.layersStack[:self.stackIndex + 1]:
        if layer.visible:
            qp.setOpacity(layer.opacity)
            qp.drawPixmap(QRect(0, 0, img.width(), img.height()), layer.rPixmap)
    qp.end()
    return img

This approach ensures efficiency by maintaining containers that are instantiated
only once and updated dynamically.

Adding New Processing Techniques

Adding a new technique involves three steps:

1. Design the GUI

Create a form for user interaction, leveraging existing forms as templates.
For example, use graphicsFormAuto3DLUT.

Input items like sliders and checkboxes can be customized as needed.

  • Add items to the form attributes :
    self.slider1 = QbLUeSlider(Qt.Orientation.Horizontal)
    ...
  • For each item, connect the signal indicating that a new state or a new value
    is available to self.dataChanged :
    for s in sliders:
                    s.sliderReleased.connect(self.dataChanged)

Note. To be able to save and restore their state, input item classes
must override the methods
_getstate()_ and __setstate()__.

2. Implement the Processing Logic

Define the transformation function in the QLayer class (or a subclass).
For example, the following function
builds a 3D LUT for automatic image enhancement. It uses
three user-defined parameters for testing purpose.

def applyAuto3DLUT(self):

    # Get the user interface
    
    ui = self.getGraphicsForm()

    # Generate an automatic 3D LUT, applying three correction coefficients.
    
    coeffs = [ui.slider1.value(), ui.slider2.value(), ui.slider3.value()]
    lutarray = generateLUTfromQImage(self.inputImg(), coeffs)
    
    # Interpolate the input image with LUT
    
    interp = chosenInterp()
    outputArray = interp(lutarray, self.inputImg())  
    
    # Copy outputArray to the image data buffer (alpha channel excluded)

    QImageBuffer(self.getCurrentImage())[..., :3] = outputArray

    # Convert the image to QPixmap.
    
    self.updatePixmap()

3. Integrate into the main Menu

Add the new functionality as an action in the menu Layer:

elif name == 'actionAuto_3D_LUT':
    layer = window.label.img.addAdjustmentLayer(role='AutoLUT')
    layer.execute = lambda: layer.tLayer.applyAuto3DLUT()

Color Management

A dedicated class (QPresentationLayer) handles advanced color management.
It enables compatibility with image and monitor profiles,
ensuring accurate color rendering.

Conclusion

The "bLUe" editor offers a cutting-edge environment for developing
and testing image processing techniques.
Its modular design, real-time visualization,
and seamless extensibility make it a powerful tool for both
developers and researchers.

Models

There are no models linked

Datasets

There are no datasets linked