我想要达到与cv::mean for non black pixel
中相同的效果但是我正在使用PIL并将PIL图像转换为cv图像然后再转换回来,这会产生太多开销。
我尝试使用
mean_color = ImageStat.Stat(img).mean
得到平均颜色。但是,这也将包括所有透明像素。我想计算所有alpha值大于0的像素的均值。因此,所有非完全透明像素的均值。
由于要处理大量文件,我试图使代码保持美观和快速。我希望有一些内置的PIL函数来执行此操作,但是找不到任何内容。
答案 0 :(得分:0)
这可能不是最干净的解决方案,但我可以使用它。
def mean(rgb, a):
"""
Supply with an RGB PIL Image and Alpha Channel PIL Image.
Calculates the mean over all non-fully-transparent pixels in rgb.
"""
a_arr = np.array(a) # Convert Alpha values Image to array.
img_arr = np.array(rgb) # Convert Image RGB values to array.
mask = (a_arr > 0) # Create mask from all non-transparent pixels
stuff = img_arr[mask] # Array containing all pixels that aren't transparent
rows = len(stuff) # Get the row size.
if rows < 1: # If all pixels are transparent:
return (0, 0, 0) # The mean is simply black
cols = len(stuff[0]) # Else, continue with the size of cols
data = np.zeros([cols, rows, 3], dtype = np.uint8) # Create an array to contain the pixels
data[:] = stuff # Put the pixels with at least a > 0 into the created array.
c_img = Image.fromarray(data, 'RGB') # Convert back to RGB PIL Image
return ImageStat.Stat(c_img).mean # Calculate the mean over all pixels
就性能而言,就我的情况而言就足够了。
大约3.44秒可转换大约一千个16x16图像文件。 该过程是:
求平均值,然后保存Image.new('RGB', (16, 16), mean)
。