RGBA图像中所有非透明/黑色像素的PIL平均值 [英] PIL mean of all non-transparent/black pixels in RGBA image

查看:131
本文介绍了RGBA图像中所有非透明/黑色像素的PIL平均值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想达到与以下相同的效果: cv ::表示非黑色像素

I want to achieve the same effect as in: cv::mean for non black pixel

但是我正在使用PIL并将PIL图像转换为cv图像然后再转换回来,这会产生太多开销.

However I am using PIL and converting a PIL image to cv image and back is too much overhead.

我尝试使用 mean_color = ImageStat.Stat(img).mean 得到平均颜色.但是,这也将包括所有透明像素.我想计算alpha值大于0的所有像素的均值.因此,所有非完全透明像素的均值.

I have tried using mean_color = ImageStat.Stat(img).mean to get the mean color. However, this will include all transparent pixels too. I would like to calculate the mean of all pixels that have an alpha value above 0. So the mean over all non-completely-transparent pixels.

由于要处理大量文件,我试图使代码保持美观和快速.我希望有一些内置的PIL函数可以执行此操作,但是找不到任何内容.

I am trying to keep the code nice and quick as I have to process a bunch of files. I was hoping for some built-in PIL function to do this, but couldn't find any.

推荐答案

这可能不是最干净的解决方案,但我可以使用它.

It might not be the cleanest solution, but I got it to work.

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

就性能而言,就我的情况而言就足够了.

Performance-wise, it was enough for my case.

大约3.44秒可转换大约一千个16x16图像文件. 该过程是:

About 3.44 seconds to convert about a thousand 16x16 image files. The process was:

取平均值,然后保存一个Image.new('RGB', (16, 16), mean).

Taking the mean then saving a Image.new('RGB', (16, 16), mean).

这篇关于RGBA图像中所有非透明/黑色像素的PIL平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆