前提

所有数据集图片的格式必须要求被PIL所支持。
详细信息请见此篇文章:

https://xq14183903.github.io/2020/07/24/DL_P2/

图片变换与增强

官方文档:

https://pytorch.org/docs/stable/torchvision/transforms.html

CenterCrop(中心裁剪)

transforms.CenterCrop(size)
size:(高,宽)或(边长)。当输入的是一组高和宽时,图片以中心为原点,设定的高和宽为基础,裁剪图片。当输入的size是一个边长时,裁剪的图片必定为正方形

ColorJitter(亮度、对比度、饱和度、色调)

transforms.ColorJitter(brightness=0, contrast=0, saturation=0, hue=0)
brightness:(min,max),输入必须为非负数。
contrast:同上
saturation:同上
hue:(min,max),且 -0.5 <= min <= max <= 0.5

Grayscale(灰度化)

transforms.Grayscale(num_output_channels=1)
num_output_channels:如果等于1,那么输出的单通道图片。如果等于3,那么输出的是RGB图片

Pad(填充)

transforms.Pad(padding, fill=0, padding_mode='constant')
padding:(int)填充上下左右四边。(num1,num2)num1对应填充左和右,num2对应填充上和下。(num1,num2,num3,num4),num1、num2、num3、num4分别对应左上右下。
fill:(R,G,B) 只能在padding_mode=’constant’时使用。用于选择填充颜色变换。
padding_mode:

  • constant:填充为fill设置好的颜色
  • edge:根据图片边缘最后一个值进行填充
  • reflect:根据图片的反射来填充图片,且不重复图片边缘最后一个值
  • symmetric:根据图片的反射来填充图片,且重复图片边缘最后一个值 (对称填充)

RandomAffine(随机仿射变换)

transforms.RandomAffine(degrees, translate=None, scale=None, shear=None, resample=False, fillcolor=0)
degrees:如果输入的是个int,那么变换角度为-int ~ +int,若输入是个元组(min,max),故变换范围为-min ~ +max
translate:(num1,num2),图像进行水平或垂直移动。计算公式为 -img_width * a < dx < img_width * a 和
-img_height * b < dy < img_height * b。
shear:平行于x轴剪裁,也是有点类似中心放大的感觉。三种种输入可选,(int)(num1,num2)(num1,num2,num3,num4)。前两种的裁剪范围是 -int ~ +int 和 num1 ~ num2,最后一种有点特殊,(num1,num2)是平行于x轴剪裁,(num3,num4)再组合成为另外一个范围,用于平行于y轴剪裁。
resample:重采样方式,支持 PIL.Image.NEAREST, PIL.Image.BILINEAR, PIL.Image.BICUBIC。
fillcolor:和transforms.Pad的一样。

RandomApply(随机变换应用)

transforms.RandomApply(transforms, p=0.5)
transforms:使用元组或列表把需要随机应用的变换组合在一起,如 transforms = [transforms.RandomAffine(30, translate=(0,0), scale=(1,2), shear=(1,10,3,4), resample=Image.NEAREST, fillcolor=255)],可以添加多个。
p:应用概率

RandomChoice(随机变换应用选择)

transforms.RandomChoice(transforms)
transforms:和RandomApply一样,效果是在设定好的元组或列表里选择一个变换进行应用

RandomCrop(随机裁剪)

torchvision.transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant')
size:(高,宽)或(边长)。当输入的是一组高和宽时,图片以中心为原点,设定的高和宽为基础,裁剪图片。当输入的size是一个边长时,裁剪的图片必定为正方形。
padding:(int)填充上下左右四边。(num1,num2)num1对应填充左和右,num2对应填充上和下。(num1,num2,num3,num4),num1、num2、num3、num4分别对应左上右下。
pad_if_needed:如果裁剪后的图片小于预期值,那么会进行自动填充。
fill:(R,G,B) 只能在padding_mode=’constant’时使用。用于选择填充颜色变换。
padding_mode:

  • constant:填充为fill设置好的颜色
  • edge:根据图片边缘最后一个值进行填充
  • reflect:根据图片的反射来填充图片,且不重复图片边缘最后一个值
  • symmetric:根据图片的反射来填充图片,且重复图片边缘最后一个值 (对称填充)

RandomGrayscale(随机灰度化)

transforms.RandomGrayscale(p=0.1)
p:随机灰度化图片的概率

RandomGrayscale(随机水平翻折)

transforms.RandomHorizontalFlip(p=0.5)
p:随机灰度化图片的概率

RandomOrder(随机变换应用顺序)

transforms.RandomOrder(transforms)
如果列表里有[1,2,3,4]4种变换,随机进行排序应用。
transforms:使用元组或列表把需要随机应用的变换组合在一起,如 transforms = [transforms.RandomAffine(30, translate=(0,0), scale=(1,2), shear=(1,10,3,4), resample=Image.NEAREST, fillcolor=255)],可以添加多个。

RandomPerspective(随机透视变换)

transforms.RandomPerspective(distortion_scale=0.5, p=0.5, interpolation=3, fill=0)
interpolation:Default- Image.BICUBIC(不懂,没用过,直接上官网原版,后续用到了再补)
p:随机灰度化图片的概率
distortion_scale:形变范围,取值范围是[0,1],默认为0.5
fill:(R,G,B) ,用于选择填充颜色变换。

RandomResizedCrop(随机调整图像大小裁剪)

transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=2)(size, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=2)
size:(高,宽)或(边长)。当输入的是一组高和宽时,图片以中心为原点,设定的高和宽为基础,裁剪图片。当输入的size是一个边长时,裁剪的图片必定为正方形。
scale:原图尺寸裁剪范围,默认为(0.08,1.0)
ratio:原图长宽比裁剪范围,默认为(3/4,4/3)
interpolation: Default- PIL.Image.BILINEAR

RandomRotation(随机旋转)

transforms.RandomRotation(degrees, resample=False, expand=False, center=None, fill=None)
degrees:如果输入的是个int,那么变换角度为-int ~ +int,若输入是个元组(min,max),故变换范围为-min ~ +max
resample:重采样方式,支持 PIL.Image.NEAREST, PIL.Image.BILINEAR, PIL.Image.BICUBIC。
expand:true,确保旋转后的图片能全部显示在原尺寸。false,旋转后可能丢失些图片边缘信息。
center:(x,y)确定旋转中心。默认为图片中心。
fill:(R,G,B) ,用于选择填充颜色变换。

RandomVerticalFlip(随机垂直翻转)

transforms.RandomVerticalFlip(p=0.5)
p:随机灰度化图片的概率

Resize(修剪图片尺寸)

transforms.Resize(size, interpolation=2)
size:(高,宽)或(边长)。当输入的是一组高和宽时,图片以中心为原点,设定的高和宽为基础,裁剪图片。当输入的size是一个边长时,裁剪的图片必定为正方形。
interpolation: Default- PIL.Image.BILINEAR

LinearTransformation(线性变换)

transforms.LinearTransformation(transformation_matrix, mean_vector)
没用过,直接翻译官方应用:白化变换:假设X是一个列向量并中心为0的数据,然后计算该数据的协方差矩阵[D x D](使用
torch.mm(X.t(), X)),计算出来的协方差矩阵再进行奇异值分解然后传入transformation_matrix。
mean_vector:平均向量

Normalize(归一化)

transforms.Normalize(mean, std, inplace=False)
mean:每个通道的均值
std:每个通道的标准差
通常为:transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])

RandomErasing(随机擦除)

transforms.RandomErasing(p=0.5, scale=(0.02, 0.33), ratio=(0.3, 3.3), value=0, inplace=False)
p:随机灰度化图片的概率
scale:擦除比率范围
ratio:擦除长宽高比率范围
value:擦除后填补的颜色,同样使用(R,G,B)模式
通常放在transforms.Normalize后面

ToPILImage(PIL图片格式转换)

transforms.ToPILImage(mode=None)
把一个tensor或narray转换为PIL图片
mode:如果输入有4通道,那么建议为RGBA,3通道-RGB,2通道-LA,单通道由数据类型决定,如int、float、short

ToTensor(张量格式转换)

transforms.ToTensor()

Lambda(应用用户自定义的变换)

transforms.Lambda(lambd)

Compose(存放各种变换应用)

transforms.Compose([])

效果可视化

完整代码(例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from torchvision import transforms
from torchvision.datasets import ImageFolder

defined_transform = transforms.Compose([transforms.Resize((32,32)),
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomRotation(30),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
train = ImageFolder('C:/Users/Arthur/Desktop/sum/tempu/train/',defined_transform)
valid = ImageFolder('C:/Users/Arthur/Desktop/sum/tempu/valid/',defined_transform)
def imshow(input_img):
input_img = input_img.numpy().transpose((1, 2, 0))
mean = np.array([0.485, 0.456, 0.406])
std = np.array([0.229, 0.224, 0.225])
input_img = std * input_img + mean
input_img = np.clip(input_img, 0, 1)
plt.imshow(input_img)
imshow(train[0][0])

效果显示