Reputation: 16295
I have a numpy array with shape (3, 256, 256)
which is a 3 channel (RGB) image of resoulution 256x256. I am trying to save this to disk with Image
from PIL
by doing the following:
from PIL import Image
import numpy as np
#... get array s.t. arr.shape = (3,256, 256)
img = Image.fromarray(arr, 'RGB')
img.save('out.png')
However this is saving an image of dimensions 256x3 to disk
Upvotes: 17
Views: 38111
Reputation: 69
You can use opencv to do merge three channel and save as img.
import cv2
import numpy as np
arr = np.random.uniform(size=(3,256,256))*255 # It's a r,g,b array
img = cv2.merge((arr[2], arr[1], arr[0])) # Use opencv to merge as b,g,r
cv2.imwrite('out.png', img)
Upvotes: 0
Reputation: 15909
The @Dietrich answer is valid, however in some cases it will flip the image. Since the transpose operator reverses the index, if the image is stored in RGB x rows x cols
the transpose operator will yield cols x rows x RGB
(which is the rotated image and not the desired result).
>>> arr = np.random.uniform(size=(3,256,257))*255
Note the 257
for visualization purposes.
>>> arr.T.shape
(257, 256, 3)
>>> arr.transpose(1, 2, 0).shape
(256, 257, 3)
The last one is what you might want in some cases, since it reorders the image (rows x cols x RGB
in the example) instead of fully transpose it.
>>> arr = np.random.uniform(size=(3,256,256))*255
>>> arr = np.ascontiguousarray(arr.transpose(1,2,0))
>>> img = Image.fromarray(arr, 'RGB')
>>> img.save('out.png')
Probably the cast to contiguous array is not even needed, but is better to be sure that the image is contiguous before saving it.
Upvotes: 22
Reputation: 5551
Try transposing arr
which gives you an (256, 256, 3)
array:
arr = np.random.uniform(size=(3,256,256))*255
img = Image.fromarray(arr.T, 'RGB')
img.save('out.png')
Upvotes: 10