使用 torch 或 torchvision,我如何调整和裁剪图像批次,并获得调整大小的比例和新图像?
With torch or torchvision, how can I resize and crop an image batch, and get both the resizing scales and the new images?
我想转换一批图像,使它们随机裁剪(固定比例)和调整大小(缩放)。但是,我不仅需要新图像,还需要应用于每个图像的比例因子的张量。例如,此 torchvision 转换将执行我想要的裁剪和调整大小:
scale_transform = torchvision.transforms.RandomResizedCrop(224, scale=(0.08, 1.0), ratio=(1.0, 1.0))
images_scaled = scale_transform(images_original)
但我也想知道比例因子。我如何获得这些比例因子,或者以不同的方式解决这个问题?
如果我没理解错的话,你想知道裁剪部分的调整比例。您可以通过计算裁剪部分的xy尺寸并将其除以您想要获得的尺寸来获得它。
class MyRandomResizedCrop(object):
def __init__(self, size, scale, ratio):
self.t = torchvision.transforms.RandomResizedCrop(size, scale=scale, ratio=ratio)
self.size = size
self.scale = scale
self.ratio = ratio
def __call__(self, sample):
sample = F.to_pil_image(sample)
crop_size = self.t.get_params(sample, self.scale, self.ratio)
x_size = crop_size[2] - crop_size[0]
y_size = crop_size[3] - crop_size[1]
x_ratio = sample.size[0] / x_size
y_ratio = sample.size[1] / y_size
ratio = (x_ratio, y_ratio)
output = F.crop(sample, *crop_size)
output = F.resize(output, self.size)
return ratio, output
import torchvision
from PIL import Image
import torchvision.transforms.functional as F
size = 244
scale = (0.08, 1.0)
ratio = (1.0, 1.0)
t = MyRandomResizedCrop(size, scale, ratio)
img = torch.rand((3,1024,1024), dtype=torch.float32)
r, img = t(img)
阅读 RandomResizedCrop
源代码后,我意识到它是以相同的方式裁剪和调整批处理中所有图像的大小,如果没问题的话。我也处于这种情况(未在我的原始问题中指定),我知道我的原始图像是正方形的,因此 resized/scaled 图像也是正方形,因为我保持 height/width 比率。下面是我编写的函数来执行我需要的操作(但是对批次中的所有图像进行了样本缩放)。我还定义了 scale
,如果它大于 1.0,图像将被裁剪,调整大小后结果看起来“更大”。这是 RandomResizedCrop
.
的 scale
参数的倒数
import torchvision.transforms.functional as F
from torchvision.transforms.functional import InterpolationMode
def scale_batch(imgs, max_scale):
# imgs shape is (batch, channel, height, width) and height must equal width
assert imgs.shape[2]==imgs.shape[3]
assert max_scale >= 1.0
scale_approximate = torch.rand(1).item() * (max_scale-1.0) + 1.0
hw_original = imgs.shape[2]
hw_crop = int(round(hw_original / scale_approximate))
scale_actual = hw_original / hw_crop
top, left = torch.randint(0, hw_original-hw_crop+1, (2,))
imgs_scaled = F.resized_crop(imgs, top, left, hw_crop, hw_crop, (hw_original, hw_original), InterpolationMode.BILINEAR)
return imgs_scaled, scale_actual
我想转换一批图像,使它们随机裁剪(固定比例)和调整大小(缩放)。但是,我不仅需要新图像,还需要应用于每个图像的比例因子的张量。例如,此 torchvision 转换将执行我想要的裁剪和调整大小:
scale_transform = torchvision.transforms.RandomResizedCrop(224, scale=(0.08, 1.0), ratio=(1.0, 1.0))
images_scaled = scale_transform(images_original)
但我也想知道比例因子。我如何获得这些比例因子,或者以不同的方式解决这个问题?
如果我没理解错的话,你想知道裁剪部分的调整比例。您可以通过计算裁剪部分的xy尺寸并将其除以您想要获得的尺寸来获得它。
class MyRandomResizedCrop(object):
def __init__(self, size, scale, ratio):
self.t = torchvision.transforms.RandomResizedCrop(size, scale=scale, ratio=ratio)
self.size = size
self.scale = scale
self.ratio = ratio
def __call__(self, sample):
sample = F.to_pil_image(sample)
crop_size = self.t.get_params(sample, self.scale, self.ratio)
x_size = crop_size[2] - crop_size[0]
y_size = crop_size[3] - crop_size[1]
x_ratio = sample.size[0] / x_size
y_ratio = sample.size[1] / y_size
ratio = (x_ratio, y_ratio)
output = F.crop(sample, *crop_size)
output = F.resize(output, self.size)
return ratio, output
import torchvision
from PIL import Image
import torchvision.transforms.functional as F
size = 244
scale = (0.08, 1.0)
ratio = (1.0, 1.0)
t = MyRandomResizedCrop(size, scale, ratio)
img = torch.rand((3,1024,1024), dtype=torch.float32)
r, img = t(img)
阅读 RandomResizedCrop
源代码后,我意识到它是以相同的方式裁剪和调整批处理中所有图像的大小,如果没问题的话。我也处于这种情况(未在我的原始问题中指定),我知道我的原始图像是正方形的,因此 resized/scaled 图像也是正方形,因为我保持 height/width 比率。下面是我编写的函数来执行我需要的操作(但是对批次中的所有图像进行了样本缩放)。我还定义了 scale
,如果它大于 1.0,图像将被裁剪,调整大小后结果看起来“更大”。这是 RandomResizedCrop
.
scale
参数的倒数
import torchvision.transforms.functional as F
from torchvision.transforms.functional import InterpolationMode
def scale_batch(imgs, max_scale):
# imgs shape is (batch, channel, height, width) and height must equal width
assert imgs.shape[2]==imgs.shape[3]
assert max_scale >= 1.0
scale_approximate = torch.rand(1).item() * (max_scale-1.0) + 1.0
hw_original = imgs.shape[2]
hw_crop = int(round(hw_original / scale_approximate))
scale_actual = hw_original / hw_crop
top, left = torch.randint(0, hw_original-hw_crop+1, (2,))
imgs_scaled = F.resized_crop(imgs, top, left, hw_crop, hw_crop, (hw_original, hw_original), InterpolationMode.BILINEAR)
return imgs_scaled, scale_actual