Numpy array to PIL image conversion problem

Hi everyone!! :smile:

Could you help me with this issue:

Traceback (most recent call last):
  File "/home/mfcs/mestrado_projeto/Colorization-mfcs/code/train.py", line 134, in <module>
    main(args)
  File "/home/mfcs/mestrado_projeto/Colorization-mfcs/code/train.py", line 56, in main
    for i, (images, img_ab, filename) in enumerate(data_loader):
  File "/home/mfcs/.local/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 345, in __next__
    data = self._next_data()
  File "/home/mfcs/.local/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 856, in _next_data
    return self._process_data(data)
  File "/home/mfcs/.local/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 881, in _process_data
    data.reraise()
  File "/home/mfcs/.local/lib/python3.6/site-packages/torch/_utils.py", line 395, in reraise
    raise self.exc_type(msg)
TypeError: Caught TypeError in DataLoader worker process 0.
Original Traceback (most recent call last):
  File "/home/mfcs/.local/lib/python3.6/site-packages/torch/utils/data/_utils/worker.py", line 178, in _worker_loop
    data = fetcher.fetch(index)
  File "/home/mfcs/.local/lib/python3.6/site-packages/torch/utils/data/_utils/fetch.py", line 44, in fetch
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "/home/mfcs/.local/lib/python3.6/site-packages/torch/utils/data/_utils/fetch.py", line 44, in <listcomp>
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "/home/mfcs/mestrado_projeto/Colorization-mfcs/code/data_loader.py", line 52, in __getitem__
    img_l = self.tensor_to_PIL(img_l) # Convert to PIL object image to be possible apply the following transform
  File "/home/mfcs/.local/lib/python3.6/site-packages/torchvision/transforms/transforms.py", line 127, in __call__
    return F.to_pil_image(pic, self.mode)
  File "/home/mfcs/.local/lib/python3.6/site-packages/torchvision/transforms/functional.py", line 167, in to_pil_image
    raise TypeError('Input type {} is not supported'.format(npimg.dtype))
TypeError: Input type int64 is not supported

All code that I am using works fine when I run it on Microsoft Windows 10, but on Linux Ubuntu this error happens…Does anyone know what the problem might be?

The DataLoader code is showed below:

#######################################
########## DATA LOADER ###############
#######################################

from torchvision import datasets, transforms
from torch.utils.data import Dataset
from skimage.color import rgb2lab, rgb2gray
from skimage import io
import torch.utils.data as data
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from PIL import Image
import os

scale_transform = transforms.Compose([
    transforms.Resize((256,256),2),
    #transforms.RandomCrop(224),
    #transforms.ToTensor()
])

class CustomDataset(Dataset):
    """Custom Dataset."""

    def __init__(self, root_dir, transform=None):
        """
        Args:
            root_dir (string): Directory with all the images.
            transform (callable, optional): Optional transform to be applied
                on a sample.
        """
        self.root_dir = root_dir
        self.transform = transform
        self.file_list=os.listdir(root_dir)
        self.tensor_to_PIL = transforms.ToPILImage()

    def __len__(self):
        return len(self.file_list)

    def __getitem__(self, idx):
        img = Image.open(self.root_dir+'/'+self.file_list[idx]).convert('RGB') # Read the image
        
        if self.transform is not None:
            img_rgb_resized = transforms.Resize((56,56),2)(img)
            img_rgb_ori = np.array(img)
            
            img_lab_ori = rgb2lab(img_rgb_ori) # Convert to CIE Lab color space
            img_lab_resized = rgb2lab(img_rgb_resized) # Convert to CIE Lab color space
            
            img_rgb_transposed = img_rgb_ori.transpose(2, 0, 1) #(C, W, H)    
            img_lab_transposed = img_lab_ori.transpose(2, 0, 1) #(C, W, H)
            img_lab_resized_transposed = img_lab_resized.transpose(2, 0, 1) #(C, W, H)
            
            img_l = (np.round(img_lab_transposed[0,:,:])).astype(np.int) # L channel
            img_l = self.tensor_to_PIL(img_l) # Convert to PIL object image to be possible apply the following transform
            img_l_resized = self.transform(img_l)
            img_l_resized = np.array(img_l_resized) # Convert to numpy array
            img_l_resized = img_l_resized - 50
            img_l_resized = torch.from_numpy(img_l_resized) # Convert to torch tensor
            
            img_ab_resized = (np.round(img_lab_resized_transposed[1:3, :, :])).astype(np.int) # (a,b) channels with int intensity values            
            img_ab_resized = np.array(img_ab_resized) # Convert to numpy array            
            img_ab_resized = torch.from_numpy(img_ab_resized) # Convert to torch tensor

            filename = self.root_dir+'/'+self.file_list[idx]
            
            return img_l_resized, img_ab_resized, filename # img_l_resized -> 1x256x256 and img_ab_resized -> 2x64x64

Best regards,

Matheus Santos.

It seems that ToPILImage doesn’t accept Int64 input tensors.
If you just want to resize the numpy array, you could also use a skimage or opencv method (which might accept this data type) instead of transforming the tensor to a PIL.Image and back to a tensor.

I see! I will try this, thanks!! :smiley:
Do you think, if I change the numpy array type to int32, the values in the array will change a lot and impact the image?

It depends on the value range. int32 has a value range pf [-2,147,483,648, 2,147,483,647], which could be enough for your inputs, but of course it depends on your actual use case.

Ow yeah, make sense. I understood.
I will try to resize using opencv or skimage.

Thanks!!