Python 如何有效地改变许多图像上的颜色?

Python 如何有效地改变许多图像上的颜色?,python,image,image-processing,colors,python-imaging-library,Python,Image,Image Processing,Colors,Python Imaging Library,我有这样一个巨大的图像数据集: 我想换一下这些衣服的颜色。所有白色应保持白色,所有紫色应变为白色,其他所有颜色应变为黑色。所需的输出如下所示: 我已经做了下面的代码,它正在做我想做的事情,但是我需要花很长的时间来浏览我拥有的大量图片。有没有另一种更快的方法 path = r"C:path" for f in os.listdir(path): f_name = (os.path.join(path,f)) if f_name.endswith(".png"): im = Image.

我有这样一个巨大的图像数据集:

我想换一下这些衣服的颜色。所有白色应保持白色,所有紫色应变为白色,其他所有颜色应变为黑色。所需的输出如下所示:

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

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

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

从PIL导入图像
将numpy作为np导入
#开放式PIL图像
im=Image.open('path/to/your/Image.png')。convert('RGBA'))
#转换为NumPy数组
像素=np.数组(im)
#获取所有白色和紫色像素的逻辑索引
idx_白色=(像素=(255、255、255、255))。全部(轴=2)
idx_紫色=(像素=(128,64,128,255))。全部(轴=2)
#生成黑色图像;将alpha通道设置为255
out=np.zero(像素.shape,np.uint8)
out[:,:,3]=255
#将白色和紫色像素设置为白色
out[idx_白色| idx_紫色]=(255、255、255、255)
#转换回PIL图像
im=Image.fromarray(out)
该代码生成所需的输出,在我的机器上大约需要1秒,而循环代码需要33秒


希望有帮助

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

从PIL导入图像
将numpy作为np导入
#开放式PIL图像
im=Image.open('path/to/your/Image.png')。convert('RGBA'))
#转换为NumPy数组
像素=np.数组(im)
#获取所有白色和紫色像素的逻辑索引
idx_白色=(像素=(255、255、255、255))。全部(轴=2)
idx_紫色=(像素=(128,64,128,255))。全部(轴=2)
#生成黑色图像;将alpha通道设置为255
out=np.zero(像素.shape,np.uint8)
out[:,:,3]=255
#将白色和紫色像素设置为白色
out[idx_白色| idx_紫色]=(255、255、255、255)
#转换回PIL图像
im=Image.fromarray(out)
该代码生成所需的输出,在我的机器上大约需要1秒,而循环代码需要33秒


希望有帮助

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

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

所以,你不需要迭代所有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')
这需要290ms,包括加载和保存图像


如果您有成千上万的图像要处理,并且您使用的是一个像样的操作系统,那么您可以使用gnupallel。更改上述代码以接受命令行参数,该参数是图像的名称,并将其另存为
recolour.py
,然后使用:

parallel ./recolour.py {} ::: *.png
它将使您的CPU上的所有CPU内核一直处于忙碌状态,直到它们都被处理完毕


关键词:图像处理、Python、Numpy、PIL、Pillow、palette、getpalette、putpalette、类、分类、标签、标签、标签图像。

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

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

所以,你不需要迭代所有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')
这需要290ms,包括加载和保存图像


如果您有成千上万的图像要处理,并且您使用的是一个像样的操作系统,那么您可以使用gnupallel。更改上述代码以接受命令行参数,该参数是图像的名称,并将其另存为
recolour.py
,然后使用:

parallel ./recolour.py {} ::: *.png
它将使您的CPU上的所有CPU内核一直处于忙碌状态,直到它们都被处理完毕


关键词:图像处理、Python、Numpy、PIL、枕头、调色板、getpalette、putpalette、类、分类、标签、标签、带标签的图像。

伟大的工作-现在一定会记住带调色板的图像!伟大的工作-将保持苍白的图像在脑海中肯定现在!