0


[九]深度学习Pytorch-transforms图像增强(剪裁、翻转、旋转)

0. 往期内容

[一]深度学习Pytorch-张量定义与张量创建

[二]深度学习Pytorch-张量的操作:拼接、切分、索引和变换

[三]深度学习Pytorch-张量数学运算

[四]深度学习Pytorch-线性回归

[五]深度学习Pytorch-计算图与动态图机制

[六]深度学习Pytorch-autograd与逻辑回归

[七]深度学习Pytorch-DataLoader与Dataset(含人民币二分类实战)

[八]深度学习Pytorch-图像预处理transforms

[九]深度学习Pytorch-transforms图像增强(剪裁、翻转、旋转)

[十]深度学习Pytorch-transforms图像操作及自定义方法

深度学习Pytorch-transforms图像增强

1. 数据增强

在这里插入图片描述
在这里插入图片描述

2. 剪裁

2.1 transforms.CenterCrop(size)

transforms.CenterCrop(size)

(1)功能:从图像中心裁剪尺寸为

size

的图片;
(2)参数

size:

若为

int

,则尺寸为

size*size

; 若为

(h,w)

,则尺寸为

h*w

.
(3)代码示例

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 1 CenterCrop
    transforms.CenterCrop(196),# 裁剪为196*196,如果是512的话,超出244的区域填充为黑色

    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std),])

2.2 transforms.RandomCrop(size, fill=0, padding_mode=‘constant’)

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

(1)功能:对图像随机裁剪出尺寸为

size

的图片;
(2)参数

size:

若为

int

,则尺寸为

size*size

; 若为

(h,w)

,则尺寸为

h*w

padding:

设置填充大小:
I. 当

padding

a

时,左右上下均填充

a

个像素;
II. 当

padding

(a,b)

时,左右填充

a

个像素,上下填充

b

个像素;
III. 当

padding

(a,b,c,d)

时,左、上、右、下分别填充

a、b、c、d

pad_if_need:

若设定的

size

大于原图像尺寸,则填充;

padding_mode:

填充模式,有

4

种模式:
I.

constant:

像素值由fill设定;
II.

edge:

像素值由图像边缘的像素值决定;
III.

reflect:

镜像填充,最后一个像素不镜像,

eg. [1,2,3,4] --> [3,2,1,2,3,4,3,2]

;
在这里插入图片描述

向左:由于1不会镜像,所以左边镜像2、3

向右:由于4不会镜像,所以右边镜像3、2

IV.

symmetric:

镜像填充,最后一个像素镜像,

eg. [1,2,3,4] --> [2,1,1,2,3,4,4,3]

;
在这里插入图片描述

向左:1、2镜像

向右:4、3镜像

fill:

padding_mode='constant'

时,用于设置填充的像素值;

(3)代码示例

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 2 RandomCrop
    transforms.RandomCrop(224, padding=16),
    transforms.RandomCrop(224, padding=(16,64)),
    transforms.RandomCrop(224, padding=16, fill=(255,0,0)),#fill=(255, 0, 0)RGB颜色#当size大于图片尺寸,即512大于244,pad_if_needed必须设置为True,否则会报错,其他区域会填充黑色(0,0,0)
    transforms.RandomCrop(512, pad_if_needed=True),# pad_if_needed=True
    transforms.RandomCrop(224, padding=64, padding_mode='edge'),#边缘
    transforms.RandomCrop(224, padding=64, padding_mode='reflect'),#镜像
    transforms.RandomCrop(1024, padding=1024, padding_mode='symmetric'),#镜像

    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std),])

2.3 transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(3/4, 4/3), interpolation)

transforms.RandomResizedCrop(size, scale=(0.08,1.0), ratio=(3/4,4/3), interpolation=<InterpolationMode.BILINEAR:'bilinear'>)

(1)功能:随机大小、随机长宽比裁剪图片;
(2)参数

size:

裁剪图片尺寸,若为

int

,则尺寸为

size*size

; 若为

(h,w)

,则尺寸为

h*w

,

size

是最后图片的尺寸;

scale:

随机裁剪面积比例,默认区间

(0.08,1)

,

scale

默认是随机选取

0.08-1

之间的一个数

ratio:

随机长宽比,默认区间

(3/4,4/3)

,

ratio

默认是随机选取

3/4-4/3

之间的一个数

interpolation:

插值方法,

eg. PIL. Image. NEAREST, PIL. Image. BILINEAR, PIL. Image. BICUBIC

;
(3)步骤
随机确定

scale

ratio

,然后对原始图片进行选取,再将选取的片段缩放到

size

大小;
(4)代码示例

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 3 RandomResizedCrop
    transforms.RandomResizedCrop(size=224, scale=(0.5,0.5)),

    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std),])

2.4 transforms.FiveCrop(size)

transforms.FiveCrop(size)

(1)功能:在图像的左上、右上、左下、右下、中心随机剪裁出尺寸为

size

5

张图片;
(2)参数

size:

裁剪图片尺寸,若为

int

,则尺寸为

size*size

; 若为

(h,w)

,则尺寸为

h*w

;
(3)代码示例

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 4 FiveCrop
    transforms.FiveCrop(112),#单独使用错误,直接使用transforms.FiveCrop(112)会报错,需要跟下一行一起使用#lamda的冒号之前是函数的输入(crops),冒号之后是函数的返回值
    transforms.Lambda(lambda crops: torch.stack([(transforms.ToTensor()(crop))for crop in crops])),#这里进行了ToTensor(),后面不需要执行Totensor()和Normalize,第114-115行])

使用

FiveCrop

时需要使用五维可视化,这是因为

inputs

为五维(

batch_size*ncrops*chanel*图像宽*图像高

),代码如下:

for epoch inrange(MAX_EPOCH):for i, data inenumerate(train_loader):

        inputs, labels = data   

        #五维可视化#使用FiveCrop时inputs为五维:batch_size*ncrops*chanel*图像宽*图像高,此时ncrops=5
        bs, ncrops, c, h, w = inputs.shape
        for n inrange(ncrops):
            img_tensor = inputs[0, n,...]# C H W
            img = transform_invert(img_tensor, train_transform)
            plt.imshow(img)
            plt.show()
            plt.pause(1)

2.5 transforms.TenCrop(size, vertical_flip=False)

transforms.TenCrop(size, vertical_flip=False)

(1)功能:在图像的左上、右上、左下、右下、中心随机剪裁出尺寸为

size

5

张图片,然后再对这

5

张照片进行水平或者垂直镜像来获得总共

10

张图片;
(2)参数

size:

裁剪图片尺寸,若为

int

,则尺寸为

size*size

; 若为

(h,w)

,则尺寸为

h*w

;

vertical_flip:

是否垂直翻转,默认为

False

代表进行水平翻转;
(3)代码示例

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 5 TenCrop
    transforms.TenCrop(112, vertical_flip=False),#lamda的冒号之前是函数的输入(crops),冒号之后是函数的返回值
    transforms.Lambda(lambda crops: torch.stack([(transforms.ToTensor()(crop))for crop in crops])),])

使用

TenCrop

时需要使用

五维

可视化,这是因为

inputs

五维

batch_size*ncrops*chanel*图像宽*图像高

),代码如下:

for epoch inrange(MAX_EPOCH):for i, data inenumerate(train_loader):

        inputs, labels = data   

        #五维可视化#使用FiveCrop时inputs为五维:batch_size*ncrops*chanel*图像宽*图像高,此时ncrops=5
        bs, ncrops, c, h, w = inputs.shape
        for n inrange(ncrops):
            img_tensor = inputs[0, n,...]# C H W
            img = transform_invert(img_tensor, train_transform)
            plt.imshow(img)
            plt.show()
            plt.pause(1)

3. 旋转

3.1 transforms.RandomHorizontalFlip(p=0.5)

transforms.RandomHorizontalFlip(p=0.5)

(1)功能:根据概率对图片进行水平(左右)翻转,每次根据概率来决定是否执行翻转;
(2)参数

p:

反转概率;
(3)代码示例

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 1 Horizontal Flip
    transforms.RandomHorizontalFlip(p=1),#执行水平翻转的概率为1

    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std),])

3.2 transforms.RandomVerticalFlip(p=0.5)

transforms.RandomVerticalFlip(p=0.5)

(1)功能:根据概率对图片进行垂直(上下)翻转,每次根据概率来决定是否执行翻转;
(2)参数

p:

反转概率;
(3)代码示例

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 2 Vertical Flip
    transforms.RandomVerticalFlip(p=0.5),#执行垂直翻转的概率为0.5

    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std),])

3.3 transforms.RandomRotation(degrees, expand=False, center=None, fill=0, resample=None)

transforms.RandomRotation(degrees, expand=False, center=None, fill=0, resample=None)

(1)功能:对图片旋转随机的角度;
(2)参数

degrees:

旋转角度;
I. 当

degrees

a

时,在区间

(-a,a)

之间随机选择旋转角度;
II. 当

degrees

(a,b)

时,在区间

(a,b)

之间随机选择旋转角度;

resample:

重采样方法;

expand:

是否扩大图片以保持原图信息,因为旋转后可能有些信息被遮挡了而丢失,如果扩大尺寸则可以显示完整图片信息;

center:

旋转点设置,默认沿着中心旋转;
(3)代码示例

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 3 RandomRotation
    transforms.RandomRotation(90),
    transforms.RandomRotation((90), expand=True),#当batch_size不为1时,expand使用时,张量在第0个维度尺寸需要匹配,需要对图片缩放到统一的size
    transforms.RandomRotation(30, center=(0,0)),#左上角旋转
    transforms.RandomRotation(30, center=(0,0), expand=True),#expand只可以针对中心旋转来扩展,无法用于左上角旋转来找回丢失的信息

    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std),])

4. 完整代码示例

# -*- coding: utf-8 -*-"""
# @file name  : transforms_methods_1.py
# @author     : tingsongyu
# @date       : 2019-09-11 10:08:00
# @brief      : transforms方法(一)
"""import os
import numpy as np
import torch
import random
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
from tools.my_dataset import RMBDataset
from PIL import Image
from matplotlib import pyplot as plt

defset_seed(seed=1):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)

set_seed(1)# 设置随机种子# 参数设置
MAX_EPOCH =10
BATCH_SIZE =1
LR =0.01
log_interval =10
val_interval =1
rmb_label ={"1":0,"100":1}deftransform_invert(img_, transform_train):"""
    将data 进行反transfrom操作
    :param img_: tensor
    :param transform_train: torchvision.transforms
    :return: PIL image
    """if'Normalize'instr(transform_train):
        norm_transform =list(filter(lambda x:isinstance(x, transforms.Normalize), transform_train.transforms))
        mean = torch.tensor(norm_transform[0].mean, dtype=img_.dtype, device=img_.device)
        std = torch.tensor(norm_transform[0].std, dtype=img_.dtype, device=img_.device)
        img_.mul_(std[:,None,None]).add_(mean[:,None,None])#normalize是减去均值除以标准差,反操作就是乘以标准差加上均值

    img_ = img_.transpose(0,2).transpose(0,1)# C*H*W --> H*W*C  通道变换
    img_ = np.array(img_)*255#将0-1转换为0-255#针对chanel是三通道还是一通道分别转换if img_.shape[2]==3:#RGB图像
        img_ = Image.fromarray(img_.astype('uint8')).convert('RGB')#将ndarray数据转换为imageelif img_.shape[2]==1:#灰度图像
        img_ = Image.fromarray(img_.astype('uint8').squeeze())else:raise Exception("Invalid img shape, expected 1 or 3 in axis 2, but got {}!".format(img_.shape[2]))return img_

# ============================ step 1/5 数据 ============================
split_dir = os.path.join("..","..","data","rmb_split")
train_dir = os.path.join(split_dir,"train")
valid_dir = os.path.join(split_dir,"valid")

norm_mean =[0.485,0.456,0.406]
norm_std =[0.229,0.224,0.225]

train_transform = transforms.Compose([
    transforms.Resize((224,224)),#图片统一缩放到244*244# 1 CenterCrop# transforms.CenterCrop(196),     # 裁剪为196*196,如果是512的话,超出244的区域填充为黑色# 2 RandomCrop# transforms.RandomCrop(224, padding=16),# transforms.RandomCrop(224, padding=(16, 64)),# transforms.RandomCrop(224, padding=16, fill=(255, 0, 0)), #fill=(255, 0, 0)RGB颜色#当size大于图片尺寸,即512大于244,pad_if_needed必须设置为True,否则会报错,其他区域会填充黑色(0,0,0)# transforms.RandomCrop(512, pad_if_needed=True),   # pad_if_needed=True# transforms.RandomCrop(224, padding=64, padding_mode='edge'), #边缘# transforms.RandomCrop(224, padding=64, padding_mode='reflect'), #镜像# transforms.RandomCrop(1024, padding=1024, padding_mode='symmetric'), #镜像# 3 RandomResizedCrop# transforms.RandomResizedCrop(size=224, scale=(0.5, 0.5)),# 4 FiveCrop# transforms.FiveCrop(112), #单独使用错误,直接使用transforms.FiveCrop(112)会报错,需要跟下一行一起使用#lamda的冒号之前是函数的输入(crops),冒号之后是函数的返回值# transforms.Lambda(lambda crops: torch.stack([(transforms.ToTensor()(crop)) for crop in crops])), #这里进行了ToTensor(),后面不需要执行Totensor()和Normalize,第114-115行# 5 TenCrop# transforms.TenCrop(112, vertical_flip=False),# transforms.Lambda(lambda crops: torch.stack([(transforms.ToTensor()(crop)) for crop in crops])),# 1 Horizontal Flip# transforms.RandomHorizontalFlip(p=1), #执行水平翻转的概率为1# 2 Vertical Flip# transforms.RandomVerticalFlip(p=0.5), #执行垂直翻转的概率为0.5# 3 RandomRotation# transforms.RandomRotation(90),# transforms.RandomRotation((90), expand=True), #当batch_size不为1时,expand使用时,张量在第0个维度尺寸需要匹配,需要对图片缩放到统一的size# transforms.RandomRotation(30, center=(0, 0)), #左上角旋转# transforms.RandomRotation(30, center=(0, 0), expand=True),   #expand只可以针对中心旋转来扩展,无法用于左上角旋转来找回丢失的信息#若使用FiveCrop或TenCrop,以下两行需要注释掉
    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std),])

valid_transform = transforms.Compose([
    transforms.Resize((224,224)),
    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std)])# 构建MyDataset实例
train_data = RMBDataset(data_dir=train_dir, transform=train_transform)
valid_data = RMBDataset(data_dir=valid_dir, transform=valid_transform)# 构建DataLoder
train_loader = DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
valid_loader = DataLoader(dataset=valid_data, batch_size=BATCH_SIZE)# ============================ step 5/5 训练 ============================for epoch inrange(MAX_EPOCH):for i, data inenumerate(train_loader):

        inputs, labels = data   
       
        #四维可视化#input的大小为四维:batch_size*chanel*图像宽*图像高 # B C H W
        img_tensor = inputs[0,...]# C H W
        img = transform_invert(img_tensor, train_transform)#对transform进行逆变换,可视化图片
        plt.imshow(img)
        plt.show()
        plt.pause(0.5)
        plt.close()#五维可视化#使用FiveCrop时inputs为五维:batch_size*ncrops*chanel*图像宽*图像高,此时ncrops=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)

本文转载自: https://blog.csdn.net/yanzhiwen2/article/details/123870111
版权归原作者 yanzhiwen2 所有, 如有侵权,请联系我们删除。

“[九]深度学习Pytorch-transforms图像增强(剪裁、翻转、旋转)”的评论:

还没有评论