在Python中将3个独立的numpy数组合并成一个RGB图像

83

我有一组数据,可以将其转换成分别包含红色(R)、绿色(G)和蓝色(B)的numpy数组。现在我需要将它们合并成RGB图像。

我试过使用 'Image' 完成这项工作,但它需要指定 'mode' 属性。

我尝试了一个小技巧。我会使用 Image.fromarray() 将数组转化为图像,但默认情况下它会以 'F' 模式获得,而 Image.merge 需要 'L' 模式的图像进行合并。如果我首先将 fromarray() 中的属性声明为 'L',则所有的 R G B 图像都会变形。

但是,如果我保存这些图像,然后再打开它们并合并,就能够正常工作。Image 会读取带有 'L' 模式的图像。

现在我有两个问题。

首先,我认为这不是一种优雅的方式来完成工作。如果有人知道更好的方法,请告诉我。

其次,Image.SAVE 没有正常工作。以下是我遇到的错误:

In [7]: Image.SAVE(imagefile, 'JPEG')
----------------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

/media/New Volume/Documents/My own works/ISAC/SAMPLES/<ipython console> in <module>()

TypeError: 'dict' object is not callable
请提出解决方案。
请注意,图像大小约为4000x4000的数组。
6个回答

101
rgb = np.dstack((r,g,b))  # stacks 3 h x w arrays -> h x w x 3

为了将0到1之间的浮点数转换为uint8,

rgb_uint8 = (np.dstack((r,g,b)) * 255.999) .astype(np.uint8)  # right, Janna, not 256

80

我其实不太理解你的问题,但这是我最近做过类似事情的一个例子,看起来可能会有所帮助:

# r, g, and b are 512x512 float arrays with values >= 0 and < 1.
from PIL import Image
import numpy as np
rgbArray = np.zeros((512,512,3), 'uint8')
rgbArray[..., 0] = r*256
rgbArray[..., 1] = g*256
rgbArray[..., 2] = b*256
img = Image.fromarray(rgbArray)
img.save('myimg.jpeg')

15
@IshanTomar - 如果答案有帮助的话,你可以考虑接受它。 - Bach
谢谢大家 感谢你们的回答 - Ishan Tomar
6
你真的应该接受最有帮助的答案,这是维持StackOverflow运转的重要部分。 - Walter Tross
1
三个点(...)是什么意思? - Lei Yang
2
@LeiYang 它的意思是切片所有先前的维度。请参考此链接:https://python-reference.readthedocs.io/en/latest/docs/brackets/ellipsis.html - jtb
显示剩余4条评论

10
rgb = np.dstack((r,g,b))  # stacks 3 h x w arrays -> h x w x 3

这段代码如果你传入3个通道,它不会创建一个3D数组,只有2个通道会保留。

6

在将numpy数组传递给Image.fromarray之前,请将其转换为uint8

例如,如果您的浮点数范围为[0..1]:

r = Image.fromarray(numpy.uint8(r_array*255.999))

你好,你能帮忙解决这个问题吗:https://dev59.com/-cLra4cB1Zd3GeqPM5ar - Coder

3

我认为您的扭曲问题是由于将原始图像拆分为各个波段,然后在放入合并之前重新调整大小所导致的。

`
image=Image.open("your image")

print(image.size) #size is inverted i.e columns first rows second eg: 500,250

#convert to array
li_r=list(image.getdata(band=0))
arr_r=np.array(li_r,dtype="uint8")
li_g=list(image.getdata(band=1))
arr_g=np.array(li_g,dtype="uint8")
li_b=list(image.getdata(band=2))
arr_b=np.array(li_b,dtype="uint8")

# reshape 
reshaper=arr_r.reshape(250,500) #size flipped so it reshapes correctly
reshapeb=arr_b.reshape(250,500)
reshapeg=arr_g.reshape(250,500)

imr=Image.fromarray(reshaper,mode=None) # mode I
imb=Image.fromarray(reshapeb,mode=None)
img=Image.fromarray(reshapeg,mode=None)

#merge
merged=Image.merge("RGB",(imr,img,imb))
merged.show()
`

这个很好用!


0
如果使用PIL图像,请将其转换为数组,然后继续以下步骤;否则,直接使用matplotlib或cv2进行操作。
image = cv2.imread('')[:,:,::-1]
image_2 = image[10:150,10:100]
print(image_2.shape)

img_r = image_2[:,:,0]
img_g = image_2[:,:,1]
img_b = image_2[:,:,2]

image_2 = img_r*0.2989 + 0.587*img_g + 0.114*img_b 

image[10:150,10:100,0] = image_2
image[10:150,10:100,1] = image_2
image[10:150,10:100,2] = image_2

plt.imshow(image,cmap='gray')

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