MathJax 3

Saturday, 17 July 2021

What is brightness and why we care

In this tutorial, we'll learn about brightness and contrast in greyscale and RGB images, and how these properties, can be optimized to our advantage. This is the second part of a series on image processing in python and this is the first part.


What is brightness?
 

The brightness is the intensity of the light represented at a pixel. This brightness is related to the amount of light energy a pixel adds to the scene at its location. In grayscale images, 0 is the smallest amount, and 255 is the greatest. In a colour image, like an RGB image, the value of brightness is computed by averaging the three channels. Thus, we can say that the brightness of pure red in an RGB image is 85 ((255+0+0)/3).
 

Sometimes, an image can be either too bright or too dark, so we need to apply some correction. All we need to do in such cases is increasing or decreasing the value of the pixels. In a greyscale image we would apply the following formula:


\[P0(x,y)  =  P1(x,y) + 10\]

  

where P1 is the pixel in the original image at (x,y) position and P0 is the pixel in the corrected image at the same position. For an RGB image, we should apply the operation on each channel, paying attention not to desaturate the image. Desaturation happens when the value of the three channels become more or less similar. Let's consider a pixel which triplet is (235,160,200). Adding 50 would give us this new triplet: (255,210,250). Red would be set to 255, as it cannot go further, while the brightness of green and blue would increase disproportionately. Things would get even worse when we are dealing with primary colours, as these colours would lose their purity.

To mitigate the effects of desaturation, we can use multiplication:


\[P0(x,y)  =  P1(x,y)*1.3\]

 

Switching to multiplication doesn't always work as we can still desaturate an image, and in the end, we must trust our judgement when trying to obtain the best result.

Brightness correction implementation

The following code implements a simple function to increase or decrease an image brightness. 

from PIL import Image, ImageTk
import tkinter as tk

 

def brightness(input_image, value):
    if input_image.mode != 'L' and input_image.mode != 'P':
        return None
    else:
        output_image = Image.new('L', (input_image.width,
                                     input_image.height))

        for x in range(input_image.width):
            for y in range(input_image.height):
                pix = input_image.getpixel((x, y))
                output_image.putpixel((x,y), int(pix + value))
    
        return output_image    

 
def main():
    root = tk.Tk()
    img = Image.open("retriver_gray.png", formats=['PNG'])

    width = img.width*2+20
    height = img.height
    root.geometry(f'{width}x{height}')
    
    output_im = brightness(img, 50)
     
    if output_im != None:
        output_im = ImageTk.PhotoImage(output_im)
        input_im = ImageTk.PhotoImage(img)
     
        canvas = tk.Canvas(root, width=width, height=height, bg="#ffffff")
        canvas.create_image(width/4-1, height/2-1, image=input_im, state="normal")
        canvas.create_image(20+3*img.width/2-1, img.height/2-1, image=output_im, state="normal")
        canvas.place(x=0, y=0)
        canvas.pack()
        
        root.mainloop()
    else:
        print("Input image's mode must be 'L' or 'P'"\
              "Check https://pillow.readthedocs.io/en/"\
              "latest/handbook/concepts.html#concept-modes")
 
if __name__ == "__main__":
    main() 

 

This is the result of increasing the image's brightness of 50:

 


There is very little to say about the code apart from that I used addition to increase brightness. I leave to the reader experimenting with multiplication. If you are interested in more image processing algorithms, read the next post about contrast stretching in Python. 

 

No comments:

Post a Comment