更改 PIL 中的像素亮度

问题描述 投票:0回答:1

对于不准确的术语或问题描述表示歉意。我对 Python 还很陌生。对于眼球追踪实验,我需要在灰度上转换一组刺激(花朵图像)并使它们等亮度。我还需要保留图像的 Alpha 通道,尽管这似乎相当简单。

对于等亮度,我目前有3个步骤:

  1. 使用 alpha 通道作为掩模计算每个图像的平均亮度:

  2. 计算当前图像的平均亮度与所有图像的平均值之间的差异

  3. 将此差异添加到当前图像的每个像素,并舍入为整数。

这是我解决这个问题的方法:

# 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))

正如我所说,虽然这个解决方案确实有效,但效率非常低,因为它必须迭代每个图像的每个像素。有没有更简单的方法来做到这一点?

python-imaging-library
1个回答
0
投票

向每个像素添加 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)
© www.soinside.com 2019 - 2024. All rights reserved.