【问题标题】:How to efficiently change colors on a lot of images?如何有效地改变大量图像的颜色?
【发布时间】:2019-11-13 11:44:21
【问题描述】:

我有一个庞大的图像数据集,如下所示:

我想改变这些颜色。所有的白色都应该保持白色,所有的紫色都应该变成白色,其他一切都应该变成黑色。所需的输出如下所示:

我已经在下面编写了代码,它正在做我想做的事情,但是浏览我拥有的大量图片需要很长时间。还有另一种更快的方法吗?

path = r"C:path"
for f in os.listdir(path):
f_name = (os.path.join(path,f))
if f_name.endswith(".png"):
    im = Image.open(f_name)
    fn, fext = os.path.splitext(f_name)
    print (fn)
    im =im.convert("RGBA")
    for x in range(im.size[0]):
        for y in range(im.size[1]):
            if im.getpixel((x, y)) == (255, 255, 255, 255):
                im.putpixel((x, y),(255, 255, 255,255))
            elif im.getpixel((x, y)) == (128, 64, 128, 255):
                im.putpixel((x, y),(255, 255, 255,255))
            else:
                im.putpixel((x, y),(0, 0, 0,255))

    im.show()

【问题讨论】:

    标签: python image image-processing colors python-imaging-library


    【解决方案1】:

    您的图像似乎是调色板,因为它们代表分割或标记类,并且通常少于 256 个类。因此,每个像素只是一个标签(或类号),实际颜色在 256 元素表中查找,即调色板。

    如果您不熟悉托盘化图像,请查看here

    因此,您不需要遍历所有 1200 万像素,而只需遍历只有 256 个元素长的调色板...

    #!/usr/bin/env python3
    
    import sys
    import numpy as np
    from PIL import Image
    
    # Load image
    im = Image.open('image.png')
    
    # Check it is palettised as expected
    if im.mode != 'P':
        sys.exit("ERROR: Was expecting a palettised image")
    
    # Get palette and make into Numpy array of 256 entries of 3 RGB colours
    palette = np.array(im.getpalette(),dtype=np.uint8).reshape((256,3))
    
    # Name our colours for readability
    purple = [128,64,128]
    white  = [255,255,255]
    black  = [0,0,0]
    
    # Go through palette, setting purple to white
    palette[np.all(palette==purple, axis=-1)] = white
    
    # Go through palette, setting anything not white to black
    palette[~np.all(palette==white, axis=-1)] = black
    
    # Apply our modified palette and save
    im.putpalette(palette.ravel().tolist())
    im.save('result.png')
    

    这需要 290 毫秒,包括加载和保存图像。


    如果您有成千上万的图像要做,并且您使用的是不错的操作系统,则可以使用 GNU Parallel。把上面的代码改成接受一个命令行参数,也就是图片的名字,保存为recolour.py然后使用:

    parallel ./recolour.py {} ::: *.png
    

    它会让你的 CPU 上的所有 CPU 核心保持忙碌,直到它们都被处理完。

    关键字:图像处理、Python、Numpy、PIL、Pillow、调色板、getpalette、putpalette、类、分类、标签、标签、标签图像。

    【讨论】:

    • 伟大的工作 - 现在肯定会记住调色板的图像!
    【解决方案2】:

    如果您愿意使用 NumPy,则可以大大加快像素操作:

    from PIL import Image
    import numpy as np
    
    # Open PIL image
    im = Image.open('path/to/your/image.png').convert('RGBA')
    
    # Convert to NumPy array
    pixels = np.array(im)
    
    # Get logical indices of all white and purple pixels
    idx_white = (pixels == (255, 255, 255, 255)).all(axis=2)
    idx_purple = (pixels == (128, 64, 128, 255)).all(axis=2)
    
    # Generate black image; set alpha channel to 255
    out = np.zeros(pixels.shape, np.uint8)
    out[:, :, 3] = 255
    
    # Set white and purple pixels to white
    out[idx_white | idx_purple] = (255, 255, 255, 255)
    
    # Convert back to PIL image
    im = Image.fromarray(out)
    

    该代码生成所需的输出,在我的机器上大约需要 1 秒,而您的循环代码需要 33 秒。

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2013-10-27
      • 1970-01-01
      • 2015-05-28
      • 2013-03-26
      • 1970-01-01
      • 2013-05-26
      • 2016-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多