示例来源:PyTorch 深度学习实战 (geekbang.org)
1、图像裁剪
torchvision.transforms提供了多种剪裁方法,例如中心剪裁、随机剪裁、四角和中心剪裁等。我们依次来看下它们的定义。
- 先说中心剪裁,顾名思义,在中心裁剪指定的 PIL Image 或 Tensor,其定义如下:
torchvision.transforms.CenterCrop(size)
其中,size表示期望输出的剪裁尺寸。如果 size 是一个像 (h, w) 这样的元组,则剪裁后的图像尺寸将与之匹配。如果 size 是 int 类型的整数,剪裁出来的图像是 (size, size) 的正方形。
- 然后是随机剪裁,就是在一个随机位置剪裁指定的 PIL Image 或 Tensor,定义如下:
torchvision.transforms.RandomCrop(size, padding=None)
其中,size代表期望输出的剪裁尺寸,用法同上。而padding表示图像的每个边框上的可选填充。默认值是 None,即没有填充。通常来说,不会用padding这个参数,至少对于我来说至今没用过。
- 最后要说的是FiveCrop,我们将给定的 PIL Image 或 Tensor ,分别从四角和中心进行剪裁,共剪裁成五块,定义如下:
torchvision.transforms.FiveCrop(size)
size可以是int或tuple,用法同上。
掌握了各种剪裁的定义和参数用法以后,我们来看一下这些剪裁操作具体如何调用,代码如下。
from PIL import Image
from torchvision import transforms
# 定义剪裁操作
center_crop_oper = transforms.CenterCrop((60,70))
random_crop_oper = transforms.RandomCrop((80,80))
five_crop_oper = transforms.FiveCrop((60,70))
# 原图
orig_img = Image.open('jike.png')
orig_img.show()
# 中心剪裁
img1 = center_crop_oper(orig_img)
img1.show()
# 随机剪裁
img2 = random_crop_oper(orig_img)
img2.show()
# 四角和中心剪裁
imgs = five_crop_oper(orig_img)
for img in imgs:
img.show()
流程和Resize类似,都是先定义剪裁操作,然后使用裁剪操作对象对图像进行操作,将返回对应裁剪操作后的图像,具体剪裁效果如下表所示
2、图像翻转
torchvision.transforms提供了两种翻转操作,分别是:以某一概率随机水平翻转图像和以某一概率随机垂直翻转图像。我们分别来看它们的定义。
- 以概率p随机水平翻转图像,定义如下:
torchvision.transforms.RandomHorizontalFlip(p=0.5)
- 以概率p随机垂直翻转图像,定义如下:
torchvision.transforms.RandomVerticalFlip(p=0.5)
其中,p表示随机翻转的概率值,默认为0.5
这里的随机翻转,是为数据增强提供方便。如果想要必须执行翻转操作的话,将p设置为1即可
以极客时间的LOGO图片为例,图片翻转的代码如下
from PIL import Image
from torchvision import transforms
# 定义翻转操作
h_flip_oper = transforms.RandomHorizontalFlip(p=1)
v_flip_oper = transforms.RandomVerticalFlip(p=1)
# 原图
orig_img = Image.open('jike.png')
display(orig_img)
# 水平翻转
img1 = h_flip_oper(orig_img)
display(img1)
# 垂直翻转
img2 = v_flip_oper(orig_img)
display(img2)
流程与裁剪一致,都是先定义操作,然后使用操作对象对图像进行操作(此处为翻转操作对象),将返回对应操作后的结果,翻转效果如下表所示
3、图像标准化(只能对Tensor操作,不可对PIL Image对象操作)
标准化是指每一个数据点减去所在通道的平均值,再除以所在通道的标准差,数学的计算公式如下:
而对图像进行标准化,就是对图像的每个通道利用均值和标准差进行正则化。这样做的目的,是为了保证数据集中所有的图像分布都相似,这样在训练的时候更容易收敛,既加快了训练速度,也提高了训练效果
torchvision.transforms.Normalize(mean, std, inplace=False)
# 每个参数的含义为:
# mean:表示各通道的均值;
# std:表示各通道的标准差;
# inplace:表示是否原地操作,默认为否。
以极客时间的LOGO图片为例,以(R, G, B)均值和标准差均为(0.5, 0.5, 0.5)来标准化图片后的代码实现为:
from PIL import Image
from torchvision import transforms
# 定义标准化操作
norm_oper = transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
# 原图
orig_img = Image.open('jk.jpg')
orig_img.show()
# 图像转化为Tensor
img_tensor = transforms.ToTensor()(orig_img)
# 标准化
tensor_norm = norm_oper(img_tensor)
# Tensor转化为图像
img_norm = transforms.ToPILImage()(tensor_norm)
img_norm.show()
上面代码的过程是,首先定义了均值和标准差均为(0.5, 0.5, 0.5)的标准化操作,然后将原图转化为Tensor,接着对Tensor进行标准化,最后再将Tensor转化为图像输出,图像输出结果为:
4、组合变换
- 上述对图像的变换操作都可以用 Compose 类组合起来,进行连续操作,Compose类是将多个变换组合到一起,它的定义如下
torchvision.transforms.Compose(transforms)
# transforms是一个Transform对象的列表,表示要组合的变换列表
比如,如果我们想要将图片变为200*200像素大小,并且随机裁切成80像素的正方形。那么我们可以组合Resize和RandomCrop变换,具体代码如下所示
from PIL import Image
from torchvision import transforms
# 原图
orig_img = Image.open('jike.png')
display(orig_img)
# 定义组合操作
composed = transforms.Compose([transforms.Resize((200, 200)),
transforms.RandomCrop(80)])
# 组合操作后的图
img = composed(orig_img)
运行结果为:
- Compose操作常常与数据集读取操作同时使用,使数据在读取的同时做类型转换,这样读取出的数据直接就是完成预处理、增强等操作之后的了
以读取MNIST数据集为例,看下如何在读取数据的同时,完成数据预处理等操作。具体代码如下:
from torchvision import transforms
from torchvision import datasets
# 定义一个transform
my_transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5), (0.5))
])
# 读取MNIST数据集 同时做数据变换
mnist_dataset = datasets.MNIST(root='./data',
train=False,
transform=my_transform,
target_transform=None,
download=True)
可以看到,在读取数据集,即获取DataSet抽象类的派生类实例时,可以直接传入transforms.Compose类型的参数,表示读取数据的同时做对应的变换
标签:DL,torchvision,img,0.5,transforms,操作,剪裁,orig From: https://blog.csdn.net/weixin_44351244/article/details/142488638