Skip to content

Instantly share code, notes, and snippets.

@fladd
Last active February 2, 2022 01:42
Show Gist options
  • Save fladd/e860089ab2f9e4066e38b4643e7c821e to your computer and use it in GitHub Desktop.
Save fladd/e860089ab2f9e4066e38b4643e7c821e to your computer and use it in GitHub Desktop.
Change the luminance of an image

Changing the luminance of an image

The following Python script allows to change the (overall) luminance of an image. This can be interesting when trying to match the luminance of several images (to their mean luminance for instance).

def change_image_luminance(image, luminance, precision=4):
    """Change the luminance of an image.

    Parameters
    ----------
    image : PIL.Image
        the image to change the luminance of
    luminance : float
        the luminance to change the image to (value between 0 and 1)
    precision : int, optional
        the precision of resulting luminance (in decimals; default=4)

    Returns
    -------
    new_image : PIL.Image
        the new image with the changed luminance

    """

    # Convert to HLS
    pix = np.asarray(image)[:,:,:3] / 255
    for x in range(pix.shape[0]):
        for y in range(pix.shape[1]):
            pix[x, y] = rgb_to_hls(*pix[x, y])

    # Iteratively approach target luminance
    mean = np.mean(pix[:,:,1])
    while round(mean, precision) != round(luminence, precision):
        for x in range(pix.shape[0]):
            for y in range(pix.shape[1]):
                new = pix[x, y, 1] + (luminance - mean)
                if new > 1:
                    new = 1
                if new < 0:
                    new = 0
                pix[x, y, 1] = new
        mean = np.mean(pix[:,:,1])

    # Convert back to RGB
    for x in range(pix.shape[0]):
        for y in range(pix.shape[1]):
            pix[x, y] = hls_to_rgb(*pix[x, y])

    return Image.fromarray((pix * 255).astype(np.uint8))

Example

Let's take the following two images:

pexels-artem-beliaikin-2691478 pexels-porapak-apichodilok-346804

Notice how the second image is brighter than the first one. Now let's change the luminance of both to 0.5:

from PIL import Image

change_image_luminance(Image.open("pexels-artem-beliaikin-2691478.jpg"), 0.5).save("pexels-artem-beliaikin-2691478_lum-0.5.jpg")
change_image_luminance(Image.open("pexels-porapak-apichodilok-346804.jpg"), 0.5).save("pexels-porapak-apichodilok-346804-0.5.jpg")

pexels-artem-beliaikin-2691478_lum-0 5 pexels-porapak-apichodilok-346804-0 5

And now they are matched!

Please note that the actual luminence depends on the gamma curve of the monitor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment