我在分割任务中尝试使用 transforms.Compose()
。但我不确定如何对图像和掩码应用几乎相同的随机变换。
在我的分割任务中,我有原始图片和对应的掩码,我想生成更多随机变换后的图像对用于训练。意思是,如果我对原始图片进行了某种变换,那么这种变换也应该应用到掩码图片上,然后这对图像可以输入到我的CNN中。我的变换器大致如下:
train_transform = transforms.Compose([ transforms.Resize(512), # 调整大小,小边将被匹配。 transforms.RandomHorizontalFlip(p=0.5), transforms.RandomVerticalFlip(p=0.5), transforms.RandomRotation(90), transforms.RandomResizedCrop(320,scale=(0.3, 1.0)), AddGaussianNoise(0., 1.), transforms.ToTensor(), # 将PIL图像或ndarray转换为张量。 transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)) # 标准化为Imagenet的均值和标准差])mask_transform = transforms.Compose([ transforms.Resize(512), # 调整大小,小边将被匹配。 transforms.RandomHorizontalFlip(p=0.5), transforms.RandomVerticalFlip(p=0.5), transforms.RandomRotation(90), transforms.RandomResizedCrop(320,scale=(0.3, 1.0)), ##---------------------!------------------ transforms.ToTensor(), # 将PIL图像或ndarray转换为张量。 transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)) # 标准化为Imagenet的均值和标准差])
注意,在代码块中,我添加了一个可以向原始图像变换添加随机噪声的类,这不在 mask_transformation
中,我希望我的掩码图像遵循原始图像的变换,但忽略随机噪声。那么,这两种变换如何成对发生(使用相同的随机行为)呢?
回答:
这个问题似乎在这里有答案: 如何对一对图片应用相同的变换。
基本上,你可以使用 torchvision
的函数式API来获取随机变换(如 RandomCrop
)的随机生成参数的句柄。然后使用相同的参数值对两个图像调用 torchvision.transforms.functional.crop()
。这看起来有点冗长,但能完成工作。你可以根据需要在某些图像上跳过某些变换。
我在其他地方看到的另一个选项是使用相同的种子重新设定随机生成器的种子,以强制生成两次相同的随机变换。我认为这种实现方式是临时性的,并且会随着pytorch版本的变化而变化(例如,是否需要重新设定 np.random
,random
,还是 torch.manual_seed()
?)