I am trying to invert the images in my dataset. I know it is possible using OpenCV but I don’t know whether it is possible using torchvision.transforms. Any pointers would be appreciated.
Hi,
Transforms internally does not provide such a transform but as its core is PIL image library, you can simply use functions available in PIL to create custom transforms. Here is the one I extended for Negative:
import PIL.ImageOps
def to_negative(img):
img = PIL.ImageOps.invert(img)
return img
class Negative(object):
"""Convert image to negative.
Args:
Returns:
PIL Image: Negative version of the input.
"""
def __init__(self):
pass
def __call__(self, img):
"""
Args:
img (PIL Image): Image to be converted to Negative.
Returns:
PIL Image: Negatived image.
"""
return to_negative(img)
t = transforms.Compose([transforms.CenterCrop(10),
Negative()])
Bests
You can use torchvision.transforms.functional.invert()
from the torchvision transforms library.
torchvision.transforms.functional.invert() seems to be discontinued or something. I get AttributeError: module ‘torchvision.transforms.functional’ has no attribute ‘invert’ when I try to use it. My torch version is 1.7.1
Most likely you are using an older torchvision
release. Note that torch
and torchvision
use different versioning and are not the same lib.
I’m trying to use torchvision.transforms.functional.invert()
on an entire dataset,
Like the following:
train_ds = datasets.MNIST('./data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.functional.invert()
]))
But I got error:
TypeError: invert() missing 1 required positional argument: 'img'
Is there a way to invert all images in a dataset without looping over each image?
You are trying to use the functional API operation in a transformation, which won’t work directly, so wrap it in e.g. transforms.Lambda
or write a custom transformation class.
This should work:
data = torch.randn(100, 3, 224, 224)
out = torchvision.transforms.functional.invert(data)
transform = torchvision.transforms.Compose([
torchvision.transforms.Lambda(lambda x: torchvision.transforms.functional.invert(x))
])
out = transform(data)
Also, since you are passing the current transform
to the MNIST
dataset, it will be applied on each sample, not the entire dataset.
Is torchvision.transforms.Lambda(transforms.functional.invert)
ok? It does what I want. I find I’m having issues with pickling the lambda in the above code snippet.
Yes, your code seems to work fine, too.