How to store 3 channel numpy array as image

I have a numpy array with a shape (3, 256, 256)

which is a 3-channel (RGB) image with a 256x256 resolution. I am trying to save this to disk using 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 saves the 256x3 image on disk

+3


source to share


3 answers


@ Dietrich's answer is valid, however it will flip the image in some cases. Since the transpose operator changes the index if the image is stored in RGB x rows x cols

, the transpose operator will give cols x rows x RGB

(this is the rotated image, not the desired result).

>>> arr = np.random.uniform(size=(3,256,257))*255

      

Pay attention to 257

for visualization purposes.

>>> arr.T.shape
(257, 256, 3)

>>> arr.transpose(1, 2, 0).shape
(256, 257, 3)

      



The last thing you might want in some cases, as it reorders the image ( rows x cols x RGB

in the example) rather than completely wrapping 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')

      

It is probably not even necessary to cast to a contiguous array, but it's best to make sure the image is contiguous before saving it.

+7


source


Try to transpose arr

that array gives you (256, 256, 3)

:



arr = np.random.uniform(size=(3,256,256))*255
img = Image.fromarray(arr.T, 'RGB')
img.save('out.png')

      

+4


source


You can use opencv to combine three pipes and save as img.

import cv2
import numpy as np
arr = np.random.uniform(size=(3,256,256))*255 # It 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) 

      

-2


source







All Articles