how do i find the brightness of pixels on an image using a line profile

128 Views Asked by At

I'm trying to find the brightness of pixels along a horizontal line across an image but I'm stuck on how to get either an array of numbers or maybe using a loop to change the x values and output the values of the pixels so I can calculate the brightness of each and then I can average across that line. This is what I got so far:

from PIL import Image
from math import sqrt
import os 
image = Image.open(os.path.join("mypath", "a.jpg"))
import numpy as np
image = imag.convert ('RGB')
X,Y = (137, 137) #this is where i dont know what else to add
pixelRGB = imag.getpixel((X,Y))
R,G,B = pixelRGB
brightness =([R,G,B])/3
print(brightness)

I don't know how to add a loop.

2

There are 2 best solutions below

1
Anna Andreeva Rogotulka On

You should iterate from 0 to width with a loop:

from PIL import Image

image = Image.open("1.png")
width, height = image.size
y = 137

brightness_values = []

# Loop through the horizontal line
for x in range(width):
    pixelRGB = image.getpixel((x, y))
    R, G, B = pixelRGB
    brightness = (R + G + B) / 3  
    brightness_values.append(brightness)

print(brightness_values)

average_brightness = sum(brightness_values) / len(brightness_values)
print(f"Average brightness: {average_brightness}")
0
Mark Setchell On

Processing images with for loops in Python is slow and error-prone. Try to use Pillow's built-in functions or vectorised Numpy functions instead.


Firstly, using Pillow:

from PIL import Image, ImageStat

# Create 256x256 image whose rows will have different means depending on the y-value
im = Image.radial_gradient('L').convert('RGB')

enter image description here

# Crop out row 64
row64 = im.crop((0,64,im.width,65))

# Get statistics for that row
stats = ImageStat.Stat(row64)

# Print means
print(stats.mean)

Output:

[133.3984375, 133.3984375, 133.3984375]

And secondly using Numpy:

from PIL import Image
import numpy as np

# Create 256x256 image whose rows will have different means depending on the y-value
im = Image.radial_gradient('L').convert('RGB')

enter image description here

# Convert to Numpy array
na = np.array(im)

# print mean of row 0, row 64 and row 128
print(np.mean(na[0]), np.mean(na[64]), np.mean(na[128]))

Printed values:

207.3203125 133.3984375 90.01171875

If you should wish to calculate the mean (or a line profile) along any line, not necessarily vertical or horizontal, you can use scikit-image.

from PIL import Image
import numpy as np
from skimage.draw import line

# Create 256x256 image whose rows will have different means depending on the y-value
im = Image.radial_gradient('L').convert('RGB')

enter image description here

# Convert to Numpy array
na = np.array(im)

# Get row/column coordinates of diagonal line from top-left to bottom-right
rr, cc = line(0,0, 255,255)

# Get means of points along diagonal
result = np.mean(na[rr,cc])