Data transform for single channel images

When using RGB images i wrote the transform like

transform_list = [transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]

And it worked perfectly.

But for grayscale images when I writing it like

transform_list = [transforms.ToTensor(),
transforms.Normalize(0.5, 0.5)]
I am getting an error:

File “train_2.py”, line 171, in
train(epoch)
File “train_2.py”, line 90, in train
for iteration, batch in enumerate(training_data_loader, 1):
File “/home/iiitd/.local/lib/python2.7/site-packages/torch/utils/data/dataloader.py”, line 201, in next
return self._process_next_batch(batch)
File “/home/iiitd/.local/lib/python2.7/site-packages/torch/utils/data/dataloader.py”, line 221, in _process_next_batch
raise batch.exc_type(batch.exc_msg)
TypeError: Traceback (most recent call last):
File “/home/iiitd/.local/lib/python2.7/site-packages/torch/utils/data/dataloader.py”, line 40, in _worker_loop
samples = collate_fn([dataset[i] for i in batch_indices])
File “/home/iiitd/soumyadeep/pix2pix-pytorch_2/dataset.py”, line 29, in getitem
input = self.transform(input)
File “/usr/local/lib/python2.7/dist-packages/torchvision/transforms.py”, line 34, in call
img = t(img)
File “/usr/local/lib/python2.7/dist-packages/torchvision/transforms.py”, line 155, in call
for t, m, s in zip(tensor, self.mean, self.std):
TypeError: zip argument #2 must support iteration

How should I write the transform for grayscale images ??

2 Likes

Could you post a minimal example (or just an example) that I can run to see how the error happens?

This should be correct:

transform_list = [transforms.ToTensor(),
transforms.Normalize([0.5], [0.5])]

6 Likes

Hi @richard,

This is my code, where ‘a’ and ‘b’ are two folders containing grayscale images. For RGB images i have commented out the line for the transform.

 class DatasetFromFolder(data.Dataset):
    def __init__(self, image_dir):
        super(DatasetFromFolder, self).__init__()
        self.photo_path = join(image_dir, "a")
        self.sketch_path = join(image_dir, "b")
        self.image_filenames = [x for x in listdir(self.photo_path) if is_image_file(x)]

        transform_list = [transforms.ToTensor(),
                          transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]   
	#the above line was there for RGB #images


   
        self.transform = transforms.Compose(transform_list)

    def __getitem__(self, index):
        # Load Image
        input = load_img(join(self.photo_path, self.image_filenames[index]))
        input = self.transform(input)
        target = load_img(join(self.sketch_path, self.image_filenames[index]))
        target = self.transform(target)

        return input, target

Hi @qi_chang

I tried this but its giving me the following error:

RuntimeError: CUDNN_STATUS_INTERNAL_ERROR

it’s possible that torchvision’s normalize doesn’t support 1-channel images.
Open an issue here https://github.com/pytorch/vision

I had same issue, then adding brackets to the mean and std value inside transform.Normalize fixed this.

As @qi_chang replied this should work:

1 Like

Add to your transforms list this transformation:

transforms.Grayscale(num_output_channels=1)

3 Likes

I am loading gray scale image using ImageFolder and using transform.Normalize((0.5, ),(0.5, )). But i am still receiving the images as 3 channel images.