Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PIL: Image.fromarray(img.astype('uint8'), mode='RGB') returns grayscale image

I have converted a pytorch tensor of size torch.Size([3, 28, 28]) to a numpy array of size (28, 28, 3), and there doesn't seem to be any problems with that. I then try to convert this to a PIL image using img = Image.fromarray(img.astype('uint8'), mode='RGB'), but the dimensions of the returned img are (28, 28), when I expect it to be (28, 28, 3) (or (3, 28, 28)). I cannot understand why this is the case. I made sure to convert to uint8 and use RGB mode, as other posters have suggested online, however neither of those (nor using np.ascontiguousarray) helped.

PIL version 1.1.7

# This code implements the __getitem__ function for a child class of datasets.MNIST in pytorch
# https://pytorch.org/docs/stable/_modules/torchvision/datasets/mnist.html#MNIST

img, label = self.data[index], self.targets[index]
assert img.shape == (3, 28, 28), \
       (f'[Before PIL] Incorrect image shape: expecting (3, 28, 28),'
        f'received {img.shape}')

print('Before reshape:', img.shape)    # torch.Size([3, 28, 28])
img = img.numpy().reshape(3, 28, 28)
img = np.stack([img[0,:,:], img[1,:,:], img[2,:,:]], axis=2)
print('After reshape:', img.shape)     # (28, 28, 3)

# doing this so that it is consistent with all other datasets
# to return a PIL Image
img = Image.fromarray(img.astype('uint8'), mode='RGB') # Returns 28 x 28 image

assert img.size == (3, 28, 28), \
       (f'[Before Transform] Incorrect image shape: expecting (3, 28, 28), '
        f'received {img.size}')

EDIT: Here is a minimal example. I'll leave the above for context in case it is of any help at all.

from PIL import Image
import numpy as np

img = np.random.randn(28, 28, 3)
img = Image.fromarray(img.astype('uint8'), mode='RGB') # Returns 28 x 28 image

assert img.size == (28, 28, 3), \
       (f'[Before Transform] Incorrect image shape: expecting (3, 28, 28), '
        f'received {img.size}')

AssertionError: [Before Transform] Incorrect image shape: expecting (3, 28, 28), received (28, 28)

like image 489
user14678939 Avatar asked May 27 '19 17:05

user14678939


1 Answers

I think you want this, where the ranges of the RGB vales are integers in range 0..255:

import numpy as np
from PIL import Image

# Make random 28x28 RGB image
img =np.random.randint(0,256,(28,28,3), dtype=np.uint8)

# Convert to PIL Image
pImg=Image.fromarray(img, mode='RGB')

Now check what we have:

In [19]: pImg                                                                                       
Out[19]: <PIL.Image.Image image mode=RGB size=28x28 at 0x120CE9CF8>

And save:

pImg.save('result.png')

enter image description here

like image 192
Mark Setchell Avatar answered Oct 17 '22 15:10

Mark Setchell