文章目录
图像预处理(图像增强)——transforms
1、transforms
运行机制
torchvision
是Pytorch
的计算机视觉工具包,在torchvision
中有三个主要的模块:torchvision.transforms
:常用的图像预处理方法,在transforms
中提供了一系列的图像预处理方法,例如数据的标准化,中心化,旋转,翻转等等torchvision.datasets
:定义了一系列常用的公开数据集的datasets,比如常用的MNIST,CIFAR-10,ImageNet等等;torchvision.model
,提供大量常用的预训练模型,例如AlexNet,VGG,ResNet,GoogLeNet等等;- 深度学习是由数据驱动的,数据的数量以及分布对模型的优劣起到决定性作用,所以需要对数据进行一定的预处理以及数据增强,用来提升模型的泛化能力,
torchvision.transforms
中常用的图像预处理方法包括:- 数据中心化
- 数据标准化
- 缩放
- 裁剪
- 旋转
- 翻转
- 填充
- 噪声添加
- 灰度变换
- 线性变换
- 仿射变换
- 亮度、饱和度及对比度变换
之所以需要对数据做数据增强,是为了提高模型的泛化能力,(做数据增强,如果生成了与测试样本很相似的图片,那么模型的泛化能力自然可以得到提高)
2、数据标准化——transforms.normalize
- 功能:逐channel的对图像进行标准化: o u t p u t = i n p u t − m e a n s t d output = \frac{input - mean}{std} output=stdinput−mean
- 参数:
mean
:各通道的均值std
:各通道的标准差inplace
:是否原地操作
3、裁剪:transform——Crop
Pytorch
中通过裁剪达到数据增强的目的
(1)transforms.CenterCrop
- 功能:从图像中心裁剪图片
- 参数:
size
:所需裁剪图片尺寸- 示例:
transforms.Resize((224, 224)),
transforms.CenterCrop(196), # 512
第一步行代码将原始图片限制在
224
×
224
224\times224
224×224的范围,第二行是将图片裁剪为
196
×
196
196\times196
196×196,最后再尝试将图片裁剪为
512
×
512
512\times512
512×512,得到下面从左到右的三张图片:
从左到右依次为
224
×
224
224\times224
224×224,
196
×
196
196\times196
196×196,
512
×
512
512\times512
512×512
(2)transforms.RandomCrop
transforms.RandomCrop(size, padding=None,
pad_if_needed=False,
fill=0,
padding_mode='constant')
- 功能:从图片中随机裁剪出尺寸为size的图片
- 参数:
size
:所需裁剪图片尺寸padding
:设置填充大小(有三种模式)- 当为一个整数a时,上下左右均填充a个像素
- 当为一个元组(a,b)时,上下填充b个像素,左右填充a个像素
- 当为一个列表(a,b,c,d)时,左,上,右,下分别填充a,b,c,d(记忆对应关系:顺时针转动)
pad_if_need
:若图像小于设定size,则填充padding_mode
:填充模式,共4种模式constant
:像素值由fill
设定edge
:像素值由图像边缘像素决定reflect
:镜像填充,最后一个像素不镜像,例如:[1,2,3,4] -> [3,2,1,2,3,4,3,2]
(由于最后一个像素不镜像,所以跳过1和4,分别从2和3开始进行镜像填充);symmetric
:镜像填充,最后一个像素镜像, 例如:[1,2,3,4] -> [2,1,1,2,3,4,4,3]
(最后一个像素镜像,所以不会跳过1和4,分别从1和4开始进行镜像填充)
- 示例:
padding
为一个整数a
transforms.RandomCrop(224, padding=16)
左图为原始图片,右图为裁剪后的图片,裁剪出来的图片左边和上边都有一块黑色的填充区域。为什么右边和下边没有呢?这是因为经过填充之后的图片的尺寸应该是
224
+
16
+
16
224+16+16
224+16+16,比
224
224
224大
32
32
32个像素。在这个大的图片上进行
(
224
,
224
)
(224,224)
(224,224)的随机选取,由于图像选取左上角的这一部分,所以右边和下边是没有黑色的填充区域的
padding
为一个元组(a,b)
transforms.RandomCrop(224, padding=(16, 64))
左图为原始图片,右图为裁剪后的图片,分别对左右、上下设置不同的填充,可以看到左右的填充区域相比于上下是更小的
fill
参数
transforms.RandomCrop(224, padding=16) # 左图
transforms.RandomCrop(224, padding=16, fill=(255, 0, 0)) # 右图
fill
参数用于控制填充的颜色,如果不写fill
参数,则默认为黑色,如果需要自定义填充颜色,需要往fill
传入一个表示RGB
的三元组
pad_if_needed
参数
transforms.RandomCrop(512, pad_if_needed=True)
当size
大于图片尺寸的时候,pad_if_needed
参数必须打开(为True
),否则会报错,可以看到在超出图片的范围全部填充上像素值为0的像素点,也就是黑色的
padding_mode
为constant
模式
transforms.RandomCrop(224, padding=64, padding_mode='constant')
padding_mode
默认采用constant
模式,在采用constant
的时候,采用fill
参数去设置填充的像素点的像素值
padding_mode
为edge
模式
transforms.RandomCrop(224, padding=64, padding_mode='edge')
这种模式是采用图片的边界值对图片进行填充,上图中填充的区域是左边和上边,左边和上边的每一个像素值,都是用图片的最边缘的像素点进行填充,
padding_mode
为reflect
模式
transforms.RandomCrop(224, padding=64, padding_mode='reflect')
padding_mode='reflect’
就是对图片进行镜像操作,填充区域是对原始图片的边缘区域进行镜像。padding_mode='symmetric’
和padding_mode='reflect’
功能相差不多,只是相差一个像素值点
padding_mode
为symmetric
模式
transforms.RandomCrop(1024, padding=1024, padding_mode='symmetric')
(3)transforms.RandomResizedCrop
RandomResizedCrop(size,
scale=(0.08, 1.0),
ratio=(3 / 4, 4 / 3),
interpolation)
- 功能:随机大小、长宽比裁剪图片
- 参数:
size
:所需裁剪图片尺寸scale
:随机裁剪面积比例,默认(0.08, 1)
ratio
:随机长宽比,默认(3/4,4/3)
interpolation
:插值方法(裁剪出来的图片尺寸可能小于size
,所以需要进行插值处理,插值方法有三种)PIL.Image.NEAREST
PIL.Image.BILINEAR
(默认方法)PIL.Image.BICUBIC
- 示例:
transforms.RandomResizedCrop(size=224, scale=(0.08, 1))
所得图片比原始图片小得多,这个比例是在(0.08,1)
之间随机选取得到的,选取得到一个比例之后,再根据ratio
长宽比设定图像的长和宽,裁剪得到一个图片。裁剪得到图片之后,再resize
到设定的size
大小尺寸。如果想固定到某个比例,比如裁剪为原来图片的50%,则可将scale
设置为scale = (0.5, 0.,5)
(4)FiveCrop
- 功能:在图像的上下左右以及中心裁剪出尺寸为
size
的5张图片 - 参数:
size
:设置裁剪的大小- 示例:
transforms.FiveCrop(112)
(5)TenCrop
transforms.TenCrop(size, vertical_flip=False)
- 功能:在图像的上下左右以及中心裁剪出尺寸为
size
的5张图片,TenCrop
对这5张图片 进行水平或者垂直镜像获得10张图片 - 参数:
size
:所需裁剪图片尺寸vertical_flip
:是否垂直翻转- 示例:
transforms.TenCrop(112, vertical_flip=True)
4、翻转、旋转:transforms —— Flip and Rotation
(1)翻转:Flip
1)RandomHorizontalFlip
- 功能:依概率**水平(左右)**翻转图片
- 参数:
p
:翻转概率(即有多大的概率将图片进行翻转)
2)RandomVerticalFlip
- 功能:依概率**垂直(上下)**翻转图片
- 参数:
p
:翻转概率(即有多大的概率将图片进行翻转)
(2)旋转:Rotation
RandomRotation(degrees,
resample=False,
expand=False,
center=None)
- 功能:随机旋转图片
- 参数:
degrees
:旋转角度;- 当为 a a a时,在 ( − a , a ) (-a, a) (−a,a)之间选择旋转角度
- 当为 ( a , b ) (a,b) (a,b)时,在 ( a , b ) (a,b) (a,b)之间选择旋转角度
resample
:重采样方法expand
:是否扩大图片,以保持原图信息center
:旋转点设置,默认中心旋转
注意:当使用expand
扩大图片时,因为每张图片旋转的角度不同,最后得到的图片的大小是不一样的,最后拼接的时候可能出现报错的问题,所以在使用expand
的时候,需要注意对图片进行缩放,将所有照片缩放到统一的尺寸[red]
5、图像变换:transform —— Data Augmentation
(1)Pad
transforms.Pad(padding,
fill=0,
padding_mode='constant')
- 功能:对图片边缘进行填充
- 参数:
padding
:设置填充大小,与之前的RandomCrop
相似,共有三种模式:- 当为一个整数a时,上下左右均填充a个像素
- 当为一个元组(a,b)时,上下填充b个像素,左右填充a个像素
- 当为一个列表(a,b,c,d)时,左,上,右,下分别填充a,b,c,d(记忆对应关系:顺时针转动)
padding_mode
:填充模式,有4种模式:constant
:像素值由fill
设定edge
:像素值由图像边缘像素决定reflect
:镜像填充,最后一个像素不镜像,例如:[1,2,3,4] -> [3,2,1,2,3,4,3,2]
(由于最后一个像素不镜像,所以跳过1和4,分别从2和3开始进行镜像填充);symmetric
:镜像填充,最后一个像素镜像, 例如:[1,2,3,4] -> [2,1,1,2,3,4,4,3]
(最后一个像素镜像,所以不会跳过1和4,分别从1和4开始进行镜像填充)
fill
:设置填充的像素值,(R, G, B) or (Gray),只有当padding_mode = 'constant'
的时候才有效果- 示例:
transforms.Pad(padding=32, fill=(255, 0, 0), padding_mode='constant'),
transforms.Pad(padding=(8, 64), fill=(255, 0, 0), padding_mode='constant'),
transforms.Pad(padding=(8, 16, 32, 64), fill=(255, 0, 0), padding_mode='constant'),
transforms.Pad(padding=(8, 16, 32, 64), fill=(255, 0, 0), padding_mode='symmetric'),
(2)ColorJitter
transforms.ColorJitter(brightness=0,
contrast=0,
saturation=0,
hue=0)
- 功能:调整亮度、对比度、饱和度和色相
- 参数:
brightness
:亮度调整因子,共有两种模式:- 当为一个整数 a a a时,从 [ max { 0 , 1 − a } , 1 + a ] [\max\{0, 1-a\}, 1+a] [max{0,1−a},1+a]中随机选择
- 当为一个元组 ( a , b ) (a, b) (a,b)时,从 [ a , b ] [a, b] [a,b]中随机选择
contrast
:对比度参数,模式同brightness
saturation
:饱和度参数,模式同brightness
hue
:色相参数,共有两种模式:- 当为一个整数 a a a时,从 [ − a , a ] [-a, a] [−a,a]中选择参数(注意: 0 ≤ a ≤ 0.5 0\leq a \leq0.5 0≤a≤0.5)
- 示例:
transforms.ColorJitter(brightness=0.5),
transforms.ColorJitter(contrast=0.5),
transforms.ColorJitter(saturation=0.5),
transforms.ColorJitter(hue=0.3),
(3)Grayscale
Grayscale(num_output_channels)
- 功能:将图片转换为灰度图
- 参数:
num_ouput_channels
:输出通道数只能设1或3
Grayscale
相对于是p=1
的RandomGrayscale
[red]
(4)RandomGrayscale
RandomGrayscale(num_output_channels, p=0.1)
- 功能:依概率将图片转换为灰度图
- 参数:
num_ouput_channels
:输出通道数只能设1或3p
:概率值,图像被转换为灰度图的概率
#####(5)RandomAffine
RandomAffine(degrees,
translate=None,
scale=None,
shear=None,
resample=False,
fillcolor=0)
- 功能:对图像进行仿射变换,仿射变换是二维的线性变换,由五种基本原子变换构成,分别是:
- 旋转
- 平移
- 缩放
- 错切
- 翻转
- 参数:
degrees
:旋转角度设置translate
:平移区间设置,如(a, b)
表示a
设置宽(width),b
设置高(height) 图像在宽维度平移的区间为$ - \ width_{img} \times a < dx < width_{img} \times a $scale
:缩放比例(以面积为单位)fill_color
:填充颜色设置- 示例:
transforms.RandomAffine(degrees=30),
transforms.RandomAffine(degrees=0, translate=(0.2, 0.2), fillcolor=(255, 0, 0)),
transforms.RandomAffine(degrees=0, scale=(0.7, 0.7)),
transforms.RandomAffine(degrees=0, shear=(0, 0, 0, 45)),
transforms.RandomAffine(degrees=0, shear=90, fillcolor=(255, 0, 0)),
(6)RandomErasing
- 功能:对图像进行随机遮挡
- 参数:
p
:概率值,执行该操作的概率scale
:遮挡区域的面积ratio
:遮挡区域长宽比value
:设置遮挡区域的值- 示例
transforms.RandomErasing(p=1, scale=(0.02, 0.33), ratio=(0.3, 3.3), value=(254/255, 0, 0)),
transforms.RandomErasing(p=1, scale=(0.02, 0.33), ratio=(0.3, 3.3), value='1234'),
(7)transforms.Lambda
transforms.Lambda(lambd)
- 功能:用户自定义
lambda
方法 - 参数:
lambd
:lambda
匿名函数- 示例:
transforms.TenCrop(200, vertical_flip=True),
transforms.Lambda(lambda crops: torch.stack([transforms.Totensor()(crop) for crop in crops])),
6、Transforms的操作:Transforms Operation
(1)transforms.RandomChoice
- 功能:从一系列
transforms
方法中随机挑选一个 - 示例:
transforms.RandomChoice([transforms1, transforms2, transforms3])
(2)transforms.RandomApply
- 功能:依据概率执行一组
transforms
操作 - 示例:
transforms.RandomApply([transforms1, transforms2, transforms3], p=0.5)
(3)transforms.RandomOrder
- 功能:对一组
transforms
操作打乱顺序 - 示例:
transforms.RandomOrder([transforms1, transforms2, transforms3])
7、自定义Transforms:User-Defined Transforms
自定义Transforms
需要通过类实现:
class YourTransforms(object):
def __init__(self, ...):
pass
def __call__(self, img):
...
return img
实现的方法写如__call__
中,__init__
中传入参数
8、Transformation
方法小结
Pytorch
中提供的Transformation
方法共有22种,分为四大类:
- 裁剪
- transforms.CenterCrop
- transforms.RandomCrop
- transforms.RandomResizedCrop
- transforms.FiveCrop
- transforms.TenCrop
- 翻转和旋转
- transforms.RandomHorizontalFlip
- transforms.RandomVerticalFlip
- transforms.RandomRotation
- 图像变换
- transforms.Pad
- transforms.ColorJitter
- transforms.Grayscale
- transforms.RandomGrayscale
- transforms.RandomAffine
- transforms.LinearTransformation
- transforms.RandomErasing
- transforms.Lambda
- transforms.Resize
- transforms.Totensor
- transforms.Normalize
- transforms的操作
- transforms.RandomChoice
- transforms.RandomApply
- transforms.RandomOrder