PIL中是否有一个Image.point()方法可以同时操作所有三个通道?

4

我想编写一个基于每个像素的红、绿和蓝通道的点过滤器,但似乎这可能达不到point()的能力 - 它似乎一次仅在单个通道的单个像素上操作。我想做类似这样的事情:

def colorswap(pixel):
    """Shifts the channels of the image."""
    return (pixel[1], pixel[2], pixel[0])
image.point(colorswap)

有没有一种等效的方法让我使用一个接受RGB值的3元组的过滤器并输出一个新的3元组?

2个回答

3
你可以使用load方法快速访问所有像素。
def colorswap(pixel):
    """Shifts the channels of the image."""
    return (pixel[1], pixel[2], pixel[0])

def applyfilter(image, func):
    """ Applies a function to each pixel of an image."""
    width,height = im.size
    pixel = image.load()
    for y in range(0, height):
        for x in range(0, width):
            pixel[x,y] = func(pixel[x,y])

applyfilter(image, colorswap)

image.load() 方法正是我所需要的。谢谢! - Haldean Brown

2

根据目前的回应,我猜答案是否定的。

但你可以使用numpy来高效地完成这种工作:

def colorswap(pixel):
    """Shifts the channels of the image."""
    return (pixel[1], pixel[2], pixel[0])

def npoint(img, func):
    import numpy as np
    a = np.asarray(img).copy()
    r = a[:,:,0]
    g = a[:,:,1]
    b = a[:,:,2]
    r[:],g[:],b[:] = func((r,g,b))
    return Image.fromarray(a,img.mode)

img = Image.open('test.png')
img2 = npoint(img, colorswap)
img2.save('test2.png')

奖励:看起来Image类不是只读的,这意味着你可以让你的新的npoint函数更像point(除非你喜欢让人迷惑,否则不建议这样做):
Image.Image.npoint = npoint

img = Image.open('test.png')
img2 = img.npoint(colorswap)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接