Skip to content

ToTensor cannot handle PIL Image with mode '1' #371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
IanChen83 opened this issue Dec 18, 2017 · 6 comments
Closed

ToTensor cannot handle PIL Image with mode '1' #371

IanChen83 opened this issue Dec 18, 2017 · 6 comments

Comments

@IanChen83
Copy link

img = torch.ByteTensor(torch.ByteStorage.from_buffer(pic.tobytes()))

If the image's mode is 1, image.tobytes is called to convert image to bytes. However, this will return a Tensor object with element size 8x of the original image, and result in RuntimeError.

Traceback (most recent call last):
  File "test.py", line 106, in <module>
    (0.2156, 0.2111, 0.2125)),
  File "test.py", line 80, in __init__
    img, pk = pk_loader(f'{fpath}/{path}')
  File "test.py", line 64, in pk_loader
    m = ToTensor(data[channel])
  File "/usr/lib/python3.6/site-packages/torchvision/transforms.py", line 58, in __call__
    img = img.view(pic.size[1], pic.size[0], nchannel)
RuntimeError: invalid argument 2: size '[1461 x 512 x 1]' is invalid for input of with 93504 elements at /pytorch/torch/lib/TH/THStorage.c:41
@amorgun
Copy link

amorgun commented Dec 19, 2017

I faced the same problem with image mode 'F'.
Sample code:

import numpy as np
import torchvision.transforms.functional as V
data = np.random.rand(10, 10, 1).astype(np.float32)
V.to_tensor(V.to_pil_image(data))

Error:

RuntimeError                              Traceback (most recent call last)
<ipython-input-113-0dca96e64534> in <module>()
      2 import torchvision.transforms.functional as V
      3 data = np.random.rand(10, 10, 1).astype(np.float32)
----> 4 V.to_tensor(V.to_pil_image(data))

.../lib/python3.6/site-packages/torchvision/transforms/functional.py in to_tensor(pic)
     69     else:
     70         nchannel = len(pic.mode)
---> 71     img = img.view(pic.size[1], pic.size[0], nchannel)
     72     # put it from HWC to CHW format
     73     # yikes, this transpose takes 80% of the loading time/CPU

RuntimeError: invalid argument 2: size '[10 x 10 x 1]' is invalid for input of with 400 elements at /pytorch/torch/lib/TH/THStorage.c:41

@amorgun
Copy link

amorgun commented Dec 19, 2017

I have found an ugly workaround:

import numpy as np
import torchvision.transforms.functional as V
data = np.random.rand(2, 2, 1).astype(np.float32)
V.to_tensor(
    np.asarray(V.to_pil_image(data))[:, :, None]
) * 255

@arturml
Copy link
Contributor

arturml commented Apr 14, 2018

I'm dealing with this issue working with masks for semantic segmentation. For some reason, some of the masks opened by Image.open are mode '1'. These are 1-bit images, so this line doesn't work:

img = torch.ByteTensor(torch.ByteStorage.from_buffer(pic.tobytes()))

Since there's no 1-bit tensor, the only solution I can think of is adding another elif for mode '1' with a convert to mode 'L':

elif pic.mode == '1':
    img = torch.ByteTensor(torch.ByteStorage.from_buffer(pic.convert('L').tobytes()))

I'll try to make this change and adjust the tests.

@fmassa
Copy link
Member

fmassa commented Apr 16, 2018

@arthurml in your case, I'd modify the dataset to always convert the masks to mode 'L' just after opening them. But I'll have a look at your PR now

@arturml
Copy link
Contributor

arturml commented Apr 16, 2018

Thank you, @fmassa! That's exactly what I'm doing right now.

@fmassa
Copy link
Member

fmassa commented Apr 16, 2018

Fixed via #471

@fmassa fmassa closed this as completed Apr 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants