对于不准确的术语或问题描述表示歉意。我对 Python 还很陌生。对于眼球追踪实验,我需要在灰度上转换一组刺激(花朵图像)并使它们等亮度。我还需要保留图像的 Alpha 通道,尽管这似乎相当简单。
对于等亮度,我目前有3个步骤:
使用 alpha 通道作为掩模计算每个图像的平均亮度:
计算当前图像的平均亮度与所有图像的平均值之间的差异
将此差异添加到当前图像的每个像素,并舍入为整数。
这是我解决这个问题的方法:
# For simplicity, I set this to a constant for now. Represents mean brightness across all images
grandMean = 138
for pic in myFiles:
picPath = myPath + '/' + pic
img = Image.open(picPath).convert('LA')
alpha, grayScale = img.split() # Will use alpha as a mask to compute the mean brightness
imgStat = ImageStat.Stat(img, mask=alpha)
meanBrightness = imgStat.mean[0] # Returns mean level of L-channel
# Compute difference between grandMean and mean of the current img
meanDiff = abs(grandMean - meanBrightness)
# Now add meanDiff to each pixel in L-channel
grayPx = grayScale.load()
size = grayScale.size
for row in range(0,size[0]):
for col in range(0,size[1]):
grayPx[row, col] = round(grayPx[row, col] + meanDiff)
imFinal = Image.merge('LA', (grayScale, alpha))
正如我所说,虽然这个解决方案确实有效,但效率非常低,因为它必须迭代每个图像的每个像素。有没有更简单的方法来做到这一点?
向每个像素添加 N 是一个“点过程”,并且可以使用 PIL 的
point()
方法轻松实现。您需要注意剪切,以防您向像素添加太多以致于溢出 255。向每个像素添加 55 的示例:
from PIL import Image
# Make a linear gradient
im = Image.linear_gradient('L')
res = im.point(lambda i:255 if i>=200 else i + 55)
您还可以转换为 Numpy,升级为 16 位,添加并确保无裁剪:
import Numpy as np
# Convert PIL Image to Numpy array and promote
na = np.array(im).astype(np.uint16)
res = na + 55
res = np.clip(res, 0, 255).astype(np.uint8)
# Convert back to PIL Image
im = Image.fromarray(res)