【问题标题】:When converting an image into an array and viceversa, are there extra considerations one must take into account?在将图像转换为数组时,是否需要考虑额外的注意事项?
【发布时间】:2019-11-15 08:01:14
【问题描述】:

我编写了这段代码来切换给定图像的 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) 中指定模式,这可以解决,但即使这样做我也不确定我获得的结果是否是“正确”的。

有没有办法确定某个图像应该使用什么模式?

我希望这不是一个愚蠢的问题,但我是这个图像处理行业的新手。

【问题讨论】:

  • 总是将完整的错误消息(从单词“Traceback”开始)作为文本(不是屏幕截图)放在有问题的(不是评论)中。还有其他有用的信息。
  • 顺便说一句:OpenCV 具有将 BGR 转换为 RGB 的功能 - image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
  • 也许您没有RGB,而是grayscaleRGBA。你应该检查它的形状 - print(RGBarr.shape)
  • 顺便说一句:PIL 具有拆分通道(波段)并将它们加入图像的功能 - 所以你不需要 numpy - r,g,b = image.split() image = Image.merge('RGB', [b,g,r])
  • BTW:检查模式print(image.mode) - 给出RGBRGBAL(用于灰度)

标签: python colors python-imaging-library rgb


【解决方案1】:

当您尝试读取不是 RGB 的图像(如灰度图像或 RGBA 图像)时,会发生错误。要保持其余代码有效,最简单的方法是使用以下命令强制 RGB 输入:

image = Image.open("image.jpg").convert('RGB')

然后,可能的灰度或 RGBA 图像被转换为​​ RGB,并且可以作为常规 RGB 图像进行处理。

如你所见,

inv_image = Image.fromarray(newRGB)

也可以,但是您的其余代码的处理不再正确(没有正确切割所需的尺寸/轴)。这将需要对您的代码进行进一步的工作,以同时尊重灰度或 RGBA 图像。

希望有帮助!


编辑:要合并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()

【讨论】:

  • 谢谢!是的,我想有一种更经济的方式来做到这一点。我在学习
【解决方案2】:

如果你想用 NumpyRGB 频道重新排序为 BGR,这样做要简单得多:

BGR = RGB[...,::-1]

它只是反向处理最后一个索引(即通道)。它具有 O(1) 的好处,这意味着无论数组的大小如何,它都需要相同的时间。在我的 Mac 上,使用 10x10 图像执行 BGR->RGB 需要 180ns,而使用 10,000x10,000 图像则相同。


一般来说,您可能想要一些其他排序而不是直接反转,所以如果您想要 BGR->BRG,您可以这样做:

BRG = BGR[...,(0,2,1)]

或者,如果您想通过重复绿色通道 3 次来制作 3 通道灰度图像(因为绿色通常是最不嘈杂的 - 请参阅 Wikipedia Bayer array article),您可以简单地这样做:

RGBgrey = BGR[...,(1,1,1)]

如果你想摆脱 Numpy,你可以直接在 PIL/Pillow 中使用矩阵乘法:

# 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

输入

结果

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    • 2016-09-10
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多