Home > Software engineering >  Gamma correction with Pillow Image turning to Grayscale
Gamma correction with Pillow Image turning to Grayscale

Time:12-18

Trying to perform gamma correction on an image in a dash app. But original color images turn to grayscale after going through my function. I'm using Pillow Image.new("P", ...) for color instead of "L" which would be for gray scale. And if I use Image.new("RGB",...) the returned image is red. Please help.

def gamma_correct(gamma, url):
    im = Image.open(requests.get(url, stream=True).raw)
    
    gamma1 = gamma
    row = im.size[0]
    col = im.size[1]
    result_img1 = Image.new("RGB", (row, col))
    for x in range(1 , row):
        for y in range(1, col):
            r = pow(im.getpixel((x,y))[0]/255, (1/gamma1))*255
            g = pow(im.getpixel((x,y))[1]/255, (1/gamma1))*255
            b = pow(im.getpixel((x,y))[2]/255, (1/gamma1))*255
            result_img1.putpixel((x,y)[0], int(r))
            result_img1.putpixel((x,y)[1], int(g))
            result_img1.putpixel((x,y)[2], int(b))

CodePudding user response:

Bear in mind "P" and "RGB" are not the same. P is palette mode, and is limited to 256 colours.

Colour images have these dimensions: (width, tall, channels), with channels usually being = 3.

It seems like you are saving the image, with all colour values in a single channel, meaning you end up with an image like (width, tall, channels) with channel = 1. This is also the reason why you get a red image when you use Image.new("RGB",...), since your image has data only in the first channel (R)


@ChristophRackwitz is correct in both his comments. Most often, libraries handling images actually handle the dimensions (height, width, channels), so if you load an image from disk which is, say, (1920,1080,3), the object in memory actually has dimensions (1080,1920,3). Additionally, some software (like opencv) even treat channels as BGR isntead of RGB by default

RGB images have 3 channels, which are the values of each colour. This means that for each pixel in the image, there are 3 colour values, one for red channel (R), one for green (G) and one for blue (B)

try debugging the image modification process, i.e:

for x in range(1 , row):
    for y in range(1, col):
            print(im.getpixel(x,y))
            r = pow(im.getpixel((x,y))[0]/255, (1/gamma1))*255
            g = pow(im.getpixel((x,y))[1]/255, (1/gamma1))*255
            b = pow(im.getpixel((x,y))[2]/255, (1/gamma1))*255
            print(im.getpixel(x,y))

The two print statements will print a 3-dimension array. Check that the values of each channel are as expected, both before and after

  • Related