Python 在将图像转换为数组和反之亦然时,是否必须考虑其他因素?

Python 在将图像转换为数组和反之亦然时,是否必须考虑其他因素?,python,colors,python-imaging-library,rgb,Python,Colors,Python Imaging Library,Rgb,我编写此代码是为了从给定图像切换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]

我编写此代码是为了从给定图像切换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.fromarrayobj,mode中指定模式,则可以修复此问题,但即使这样做,我也不确定获得的结果是否正确

有没有办法确定某个图像应该使用哪种模式


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

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

image=image.openimage.jpg.convert'RGB' 然后,可能的灰度或RGBA图像转换为RGB,并可以作为常规RGB图像处理

正如你自己发现的那样

inv_image=image.fromArrayNewWrgb 同样有效,但是代码其余部分的处理不再正确,没有对所需的尺寸/轴进行正确的切片。这将需要对代码进行进一步的工作,以同时尊重灰度或RGBA图像

希望有帮助

编辑:为了合并,这里有一个只有PIL才能交换频道的方法。注意:您仍然需要强制的RGB输入

从PIL导入图像 image=image.open'image.jpg'。转换为'RGB' r、 g,b=image.split inv_image=image.merge'RGB',b,g,r inv_image.保存'inv_image.png' inv_image.show
当您尝试读取与灰度图像或RGBA图像不同的RGB图像时,会发生错误。要使其余代码保持有效,最简单的方法是使用以下命令强制RGB输入:

image=image.openimage.jpg.convert'RGB' 然后,可能的灰度或RGBA图像转换为RGB,并可以作为常规RGB图像处理

正如你自己发现的那样

inv_image=image.fromArrayNewWrgb 同样有效,但是代码其余部分的处理不再正确,没有对所需的尺寸/轴进行正确的切片。这将需要对代码进行进一步的工作,以同时尊重灰度或RGBA图像

希望有帮助

编辑:为了合并,这里有一个只有PIL才能交换频道的方法。注意:您仍然需要强制的RGB输入

从PIL导入图像 image=image.open'image.jpg'。转换为'RGB' r、 g,b=image.split inv_image=image.merge'RGB',b,g,r inv_image.保存'inv_image.png' inv_image.show 如果要使用Numpy将RGB通道重新排序到BGR,则执行此操作要简单得多:

BGR = RGB[...,::-1]
它只处理最后一个索引,即反向的通道。它的优点是O1,这意味着无论阵列大小如何,它都需要相同的时间。在我的Mac电脑上,用10x10的图像做BGR->RGB需要180ns,用10000x1000的图像也一样

一般来说,您可能需要一些其他顺序,而不是直接反转,因此如果您需要BGR->BRG,您可以执行以下操作:

BRG = BGR[...,(0,2,1)]
或者,如果您想通过重复绿色通道三次来制作3通道灰度图像,因为绿色通常是噪音最小的-请参见,您可以简单地执行以下操作:

RGBgrey = BGR[...,(1,1,1)]
如果你想摆脱Numpy,你可以直接在PIL/枕头中使用矩阵乘法:

# 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
输入

结果

如果要使用Numpy将RGB通道重新排序到BGR,则执行此操作要简单得多:

BGR = RGB[...,::-1]
它只处理最后一个索引,即反向的通道。它的优点是O1,这意味着无论阵列大小如何,它都需要相同的时间。在我的Mac电脑上,用10x10的图像做BGR->RGB需要180ns,用10000x1000的图像也一样

一般来说,您可能需要一些其他顺序,而不是直接反转,因此如果您需要BGR->BRG,您可以执行以下操作:

BRG = BGR[...,(0,2,1)]
或者,如果您想通过重复绿色通道三次来制作3通道灰度图像,因为绿色通常是噪音最小的-请参见,您可以简单地执行以下操作:

RGBgrey = BGR[...,(1,1,1)]
如果你想摆脱Numpy,你可以直接在PIL/枕头中使用矩阵乘法:

# 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
输入

结果


始终将完整的错误消息从有问题的单词回溯开始,而不是作为文本而不是屏幕截图进行注释。还有其他有用的信息。顺便说一句:OpenCV具有将BGR转换为RGB的功能-image=cv.cvtColorimage,cv.COLOR\u BGR2RGB可能您没有RGB,而是灰度或RGBA。您应该检查它的形状-printRGBarr.shapeBTW:PIL具有分割通道带并将它们连接回图像的功能-因此您不需要numpy-r,g,b=image.split image=image.merge'RGB',[b,g,r]顺便说一句:要检查模式printimage.mode-give RGB,RGBA或L表示灰度总是将完整的错误消息从有问题的单词回溯开始,而不是作为文本注释而不是scre
恩肖特。还有其他有用的信息。顺便说一句:OpenCV具有将BGR转换为RGB的功能-image=cv.cvtColorimage,cv.COLOR\u BGR2RGB可能您没有RGB,而是灰度或RGBA。你应该检查它的形状-printRGBarr.shapeBTW:PIL具有分割通道带并将它们连接回图像的功能-因此你不需要numpy-r,g,b=image.split image=image.merge'RGB',[b,g,r]顺便说一句:要检查模式printimage.mode-为灰度图像提供RGB,RGBA或L!是的,我觉得这样做更经济。我在学习,谢谢!是的,我觉得这样做更经济。我在学习