Implement Gimp's luminance layer mode in Python

Viewed 235

Gimp has a "Luminance" mode in the layer settings:

luminance

I use it to overlay a high-resolution grayscale image on an upscaled low-resolution color image to make the color image sharper. E.g., given a grayscale image and a color image

enter image description here, enter image description here

the result of applying the grayscale image as a luminance "mask" on the blurry color image creates a sharp color image:

enter image description here

How does the luminance filter work, and how would I implement this in Python (e.g. using Pillow)?

2 Answers

Experimentally, using an image like this:

enter image description here

  • Over white, the layer in luminance mode renders a copy of itself, so the bottom part of the composite image has exactly the same luminance as the top layer.

  • If you move along a vertical (using a guide for instance) from one of the halves to the other, and look at the Pointer values for the xyY model (where Y is the luminance), you find that the luminance value doesn't change much, so on the whole, you can assume that the luminance blend mode:

  • converts the bottom image to some color model with a luminance component (xyY perhaps),

  • converts the top image to the same color model

  • creates pixel values using the luminance component from the top and the other two components from the bottom.

  • converts the pixel values back to RGB

This is also coherent with how the LCh lightness works, checking the CIE LCh values in the Pointer dialog.

In simple terms, the human eye is more sensitive to small changes in brightness (luminance) than to small changes in colour. Incidentally, that is why JPEG does chroma-downsampling but retains full luminance data.

So, basically, you take your low-res colour image and convert it to a colourspace such as Lab or HSV or any that contains an L or V component. You then replace that component with your (high quality/high resolution) luminance data and convert back to RGB. That way you retain the lower quality colour data but combine it with the higher quality luminance data.

It's late here so I may write the code tomorrow, but it looks roughly like this:

from PIL import Image

# Load low quality colour image and convert to HSV
lowQualColour = Image.open('colour.png')
HSV = lowQualColour.convert('HSV')
# Split channels, discarding Luminance
H, S, _ = HSV.split()

# Load high quality luminance as single channel
hiQualLuminance = Image.open('luminance.png').convert('L')

# Merge with colour channels and revert to RGB
result = Image.merge('HSV', (H,S,hiQualLuminance)).convert('RGB')
Related