torchvision.transforms

图像预处理——transforms

如果本篇内容对您有帮助请点赞或关注,如若转载请注明出处,感谢!

1. transforms运行机制

1.1 torchvision:Pytorch计算机视觉工具包,包含三大模块

torchvision.transforms: 常用的图像预处理方法

• 数据中心化 \quad • 数据标准 \quad • 缩放 \quad • 裁剪
• 旋转 \quad • 翻转 \quad • 填充 \quad • 噪声添加
• 灰度变换 \quad • 线性变换 \quad • 仿射变换 \quad • 亮度、饱和度及对比度变换

torchvision.datasets: 常用数据集的dataset实现,MNIST,CIFAR-10,ImageNet等
torchvision.model : 常用的模型预训练,AlexNet,VGG, ResNet,GoogLeNet等

1.2 数据标准化—transforms.Normalize

transforms.Normalize(mean,std,inplace=False)

功能:逐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=stdinputmean

mean:各通道的均值
std:各通道的标准差
inplace:是否原地操作

2. 用transforms进行数据增强

深度学习是由数据驱动的,数据的数量以及分布对模型的优劣起到决定性作用,所以需要对数据进行一定的预处理以及数据增强,用来提升模型的泛化能力,说白了就是通过数据增强尽可能的产生和测试样本相似的图片,提高模型的预测能力

2.1 数据增强(Data Augmentation)

数据增强又称为数据增广数据扩增,它是对训练集进行变换(旋转、翻转、颜色变换),使训练集更丰富,从而让模型具有更好的泛化能力。

2.2 裁剪(Transforms——Crop)
  1. transforms.CenterCrop

    功能:从图像中心裁剪图片
    size:所需裁剪图片尺寸

    代码示例:
    train_transform = transforms.Compose([
        transforms.Resize((224, 224)),
        # 1 CenterCrop
        transforms.CenterCrop(196),  # 512
        ...
        ])
    

    ​ 第一行代码将原始图片限制在 224 × 224 224 × 224 224×224 的范围,第二行是将图片裁剪为 196 × 196 196 × 196 196×196,最后再尝试将图片裁剪为 512 × 512 512 × 512 512×512 ,得到下面从左到右的三张图片:

  2. transforms.RandomCrop

    transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant')

    功能:从图片中随机裁剪出尺寸为size的图片
    size:所需裁剪图片尺寸

    padding:设置填充大小
    \quad 1.当为 a a a时,上下左右均填充 a a a个像素
    \quad 2.当为 ( a , b ) (a, b) (a,b)时,上下填充 b b b个像素,左右填充 a a a个像素
    \quad 3.当为(a, b, c, d)时,左,上,右,下分别填充a, b, c, d
    pad_if_need:若图像小于设定size,则填充

    padding_mode:填充模式,有4种模式
    \quad 1.constant:像素值由fill设定
    \quad 2.edge:像素值由图像边缘像素决定
    \quad 3.reflect:镜像填充,由于最后一个像素不镜像,所以跳过1和4,分别从2和3开始进行镜像填充, eg:[1,2,3,4] → [3,2,1,2,3,4,3,2]
    4、symmetric:镜像填充,最后一个像素镜像,eg:[1,2,3,4] → [2,1,1,2,3,4,4,3]
    fill:constant时,设置填充的像素值

    代码示例:
    train_transform = transforms.Compose([
        transforms.Resize((224, 224)),
        # 2 RandomCrop
        transforms.RandomCrop(224, padding=16),
       #transforms.RandomCrop(224, padding=(16, 64)),
       #transforms.RandomCrop(224, padding=64, padding_mode='reflect'),
        ...
        ])
    

    ​ 第一步行代码将原始图片限制在 224 × 224 224 × 224 224×224 的范围,第二行是:

    • 上下左右均padding 16个像素后( 240 × 240 240× 240 240×240)随机裁剪出 224 × 224 224× 224 224×224的图像

    • 将图片上下padding 16个元素,左右padding 64个元素裁剪为 224 × 224 224 × 224 224×224

    • 上下左右均padding 16个像素后( 240 × 240 240× 240 240×240)随机裁剪出 224 × 224 224× 224 224×224的图像,填充方式为reflect:镜像填充

      得到下面从左到右的三张图片:

​ 3.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:插值方法’

代码示例:
train_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    # 3 RandomResizedCrop
    transforms.RandomResizedCrop(size=224, scale=(0.5, 0.5)),
    ...
    ])

所得图片比原始图片小得多,这个比例是在(0.08,1)之间随机选取得到的,选取得到一个比例之后,再根据ratio长宽比设定图像的长和宽,裁剪得到一个图片。裁剪得到图片之后,再resize到设定的size大小尺寸。如果想固定到某个比例,比如裁剪为原来图片的50%,则可将scale设置为scale = (0.5, 0.,5),得到图像如下:

  1. FiveCrop

    transforms.FiveCrop(size)

    功能:在图像的上下左右以及中心裁剪出尺寸为size的5张图片

    size:所需裁剪图片尺寸

    代码示例:
    train_transform = transforms.Compose([
        transforms.Resize((224, 224)),
        # 4 FiveCrop
        transforms.FiveCrop(112),#输出格式为tuple,无法直接可视化
        transforms.Lambda(lambda crops: torch.stack([(transforms.ToTensor()(crop)) for crop in crops])),#将第二行的输出转换为可接受格式tensor,不过是5维的张量
        ...
        ])
        ...
        bs, ncrops, c, h, w = inputs.shape
            for n in range(ncrops):
                img_tensor = inputs[0, n, ...]  # C H W
                img = transform_invert(img_tensor, train_transform)
                plt.imshow(img)
                plt.show()
                plt.pause(1)
    

    随机裁剪的5张图(左上角、右上角、左下角、右下角、中心)片如下:

  2. TenCrop

    transforms.TenCrop(size, vertical_flip=False)

    功能:在图像的上下左右以及中心裁剪出尺寸为size的5张图片,TenCrop对这5张图片进行水平或者垂直镜像获得10张图片
    size:所需裁剪图片尺寸
    vertical_flip:是否垂直翻转

2.3 翻转、旋转(transforms——Flip and Rotation)

1.RandomHorizontalFlip

RandomHorizontalFlip(p=0.5)

功能:依概率水平(左右)翻转图片
p:翻转概率

代码示例:
train_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.RandomHorizontalFlip(p=1),#Horizontal Flip
    ...
    ])

水平翻转,翻转概率为1:

2.RandomVerticalFlip

RandomVerticalFlip(p=0.5)

功能:依概率垂直(上下)翻转图片
p:翻转概率

代码示例:
train_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.RandomVerticalFlip(p=1),#Vertical Flip
    ...
    ])

垂直翻转,翻转概率为p=1(左图)和翻转概率为p=0.5(右图)

3.RandomRotation

RandomRotation(degrees, resample=False, expand=False, center=None)

功能:随机旋转图片
degrees:旋转角度当为a时,在(-a,a)之间选择旋转角度当为(a, b)时,在(a, b)之间选择旋转角度
resample:重采样方法
expand:是否扩大图片,以保持原图信息
center:旋转点设置,默认中心旋转

代码示例:
train_transform = transforms.Compose([
    transforms.Resize((224, 224)),                
    transforms.RandomRotation(90),   #RandomRotation,degree from(-90,90)
   # transforms.RandomRotation((90), expand=True),
   # transforms.RandomRotation(30, center=(0, 0)),
   # transforms.RandomRotation(30, center=(0, 0), expand=True),   # expand only for center rotation
    ...
    ])
2.4 图像变换

1.transforms.Pad

transforms.Pad(padding, fill=0, padding_mode='constant')

功能:对图片边缘进行填充
padding:设置填充大小当为a时,上下左右均填充a个像素当为(a, b)时,上下填充b个像素,左右填充a个像素当为(a, b, c, d)时,左,上,右,下分别填充a,b, c, d
padding_mode:填充模式,有4种模式,constant、edge、reflect和symmetric
fill:constant时,设置填充的像素值,(R, G, B) or (Gray)

代码示例:
train_transform = transforms.Compose([
    transforms.Resize((224, 224)), 
    #pad
    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='reflect'),
    # transforms.Pad(padding=(8, 16, 32, 64), fill=(255, 0, 0), padding_mode='symmetric'),
    ...
    ])

2.transforms.ColorJitter

transforms.ColorJitter(brightness=0, contrast=0, saturation=0, hue=0)

功能:调整亮度、对比度、饱和度和色相
brightness:亮度调整因子当为a时,从[max(0, 1-a), 1+a]中随机选择当为(a, b)时,从[a, b]中
contrast:对比度参数,同brightness
saturation:饱和度参数,同brightness
hue:色相参数,当为a时,从[-a, a]中选择参数,注: 0<= a <= 0.5,当为(a, b)时,从[a, b]中选择参数,注:-0.5 <= a <= b <= 0.5

代码示例:
train_transform = transforms.Compose([
    transforms.Resize((224, 224)), 
    # ColorJitter
    transforms.ColorJitter(brightness=0.5),
    # transforms.ColorJitter(contrast=0.5),
    # transforms.ColorJitter(saturation=0.2),
    # transforms.ColorJitter(hue=0.3),
    ...
    ])

3.Grayscale

Grayscale(num_output_channels)

功能:将图片转换为灰度图
num_ouput_channels:输出通道数只能设1或3

代码示例:
train_transform = transforms.Compose([
    transforms.Resize((224, 224)), 
    #Grayscale
    transforms.Grayscale(num_output_channels=3),
    ...
    ])

输出通道设置为3:

4.RandomGrayscale

RandomGrayscale(num_output_channels,p=0.1)

功能:依概率将图片转换为灰度图
num_ouput_channels:输出通道数只能设1或3
p:概率值,图像被转换为灰度图的概率

5.RandomAffine

RandomAffine(degrees, translate=None, scale=None, shear=None, resample=False, fillcolor=0)

功能:对图像进行仿射变换,仿射变换是二维的线性变换,由五种基本原子变换构成,分别是旋转、平移、缩放、错切和翻转
degrees:旋转角度设置
translate:平移区间设置,如(a, b), a设置宽(width),b设置高(height),图像在宽维度平移的区间为 -img_width * a < dx < img_width * a
scale:缩放比例(以面积为单位)
fill_color:填充颜色设置

代码示例:
train_transform = transforms.Compose([
    transforms.Resize((224, 224)), 
    #Affine
    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

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) or (Gray)

7.transforms.Lambda
transforms.Lambda(lambd)

功能:用户自定义lambda方法
lambd:lambda匿名函数

lambda [arg1 [,arg2, … , argn]] : expression

transforms.Lambda(lambda crops: torch.stack([transforms.Totensor()(crop) for crop in crops]))

3. transforms的操作(Transforms Operation)

3.1 transforms.RandomChoice

transforms.RandomChoice([transforms1, transforms2, transforms3])

功能:从一系列transforms方法中随机挑选一个

3.2 transforms.RandomApply

transforms.RandomApply([transforms1, transforms2, transforms3], p=0.5)

功能:依据概率执行一组transforms操作

3.3 transforms.RandomOrder

transforms.RandomOrder([transforms1, transforms2, transforms3])

功能:对一组transforms操作打乱顺序

4. 自定义transforms(User-Defined Transforms)

自定义transforms要素:

  1. 仅接收一个参数,返回一个参数

    class Compose(object):
        def __call__(self, img):
            for t in self.transforms:
               img = t(img)
            return img
    
  2. 注意上下游的输出与输入通过类实现多参数传入:

class YourTransforms(object):
     def __init__(self, ...):
         ...
     def __call__(self, img):
         ...
        return img

椒盐噪声: 椒盐噪声又称为脉冲噪声,是一种随机出现的白点或者黑点, 白点称为盐噪声,黑色为椒噪声。
信噪比(Signal-Noise Rate, SNR):是衡量噪声的比例,图像中为图像像素的占比。

>
class AddPepperNoise(object):
     def __init__(self, snr, p):
        self.snr = snr
        self.p = p
     def __call__(self, img):  
       '''
       添加椒盐噪声具体实现过程
       '''
        return img

5. transforms方法总结

1.裁剪
• 1. transforms.CenterCrop
• 2. transforms.RandomCrop
• 3. transforms.RandomResizedCrop
• 4. transforms.FiveCrop
• 5. transforms.TenCrop
2.翻转和旋转
• 1. transforms.RandomHorizontalFlip
• 2. transforms.RandomVerticalFlip
• 3. transforms.RandomRotation
3.图像变换
• 1. transforms.Pad
• 2. transforms.ColorJitter
• 3. transforms.Grayscale
• 4. transforms.RandomGrayscale
• 5. transforms.RandomAffine
• 6. transforms.LinearTransformation
• 7. transforms.RandomErasing
• 8. transforms.Lambda
• 9. transforms.Resize
• 10. transforms.Totensor
• 11. transforms.Normalize
4.transforms的操作
• 1. transforms.RandomChoice
• 2. transforms.RandomApply
• 3. transforms.RandomOrder

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bobodareng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值