我编写了这段代码来切换给定图像中RGB阵列中的红色和蓝色值:
from PIL import Image
import numpy as np
image = Image.open("image.jpg")
RGBarr = np.asarray(image)
newRGB = np.full_like(RGBarr, 1)
red = RGBarr[..., 0]
green = RGBarr[...,1]
blue = RGBarr[..., 2]
newRGB[..., 0] = blue
newRGB[..., 1] = green
newRGB[..., 2] = red
inv_image = Image.fromarray(newRGB, 'RGB')
inv_image.save('inv_image.png')
inv_image.show()
我尝试了多幅图像,并且几乎每次都能使用。但是,在某些情况下,我会收到以下错误:
raise ValueError("not enough image data")
ValueError: not enough image data
如果我未在Image.fromarray(obj, mode)
中指定模式,则可以解决,但是即使这样做,我也不确定所获得的结果是否为“正确”的模式。
是否有确定特定图像使用哪种模式的方法?
我希望这不是一个愚蠢的问题,但是在这个图像处理行业中我是新来的。
当您尝试读取非RGB的图像(例如灰度图像或RGBA图像)时,发生错误。要保持其余代码有效,最简单的方法是使用以下方法来强制执行RGB输入:
image = Image.open("image.jpg").convert('RGB')
然后,可能的灰度或RGBA图像将转换为RGB,并且可以作为常规RGB图像进行处理。
你发现自己,
inv_image = Image.fromarray(newRGB)
也可以,但是其余代码的处理现在不再正确(对所需的尺寸/轴进行适当的切片)。这将需要在代码上做进一步的工作,以尊重灰度或RGBA图像。
希望有帮助!
EDIT:要合并furas' idea to get rid of NumPy,这是交换通道的仅PIL方式。注意:您仍然需要强制的RGB输入。
from PIL import Image
image = Image.open('image.jpg').convert('RGB')
r, g, b = image.split()
inv_image = Image.merge('RGB', (b, g, r))
inv_image.save('inv_image.png')
inv_image.show()
如果要使用Numpy将RGB
通道重新排序为BGR
,则此操作要简单得多:
BGR = RGB[...,::-1]
只是反向处理最后一个索引(即通道)。它具有O(1)的优点,这意味着与数组大小无关,它花费相同的时间。在我的Mac上,要用10x10的图像进行BGR-> RGB,而用10,000x10,000的图像进行BGR-> RGB,则需要180ns。
通常,您可能需要一些其他排序方式,而不是直接冲销,因此,如果需要BGR-> BRG,可以执行以下操作:
BRG = BGR[...,(0,2,1)]
或者,如果您想通过重复绿色通道3次来制作3通道灰度图像(因为绿色通常是最不嘈杂的,请参见Wikipedia Bayer array article,则可以执行以下操作:
,则可以使用矩阵乘法直接在PIL / Pillow中进行:RGBgrey = BGR[...,(1,1,1)]
如果要摆脱Numpy
# Open image im = Image.open('image.jpg') # Define matrix to re-order RGB->BGR Matrix = ( 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0) # BGR -> RGB BGR = im.convert("RGB", Matrix)
您可以这样理解矩阵:
newR = 0*oldR + 0*oldG + 1*oldB + 0 offset newG = 0*oldR + 1*oldG + 0*oldB + 0 offset newB = 1*oldR + 0*oldG + 0*oldB + 0 offset
输入
结果