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

  1. 往期内容

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

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

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

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

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

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

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

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

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

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

深度学习Pytorch-transforms图像增强

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

; 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)),

    transforms.CenterCrop(196),

    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. 当 paddinga时,左右上下均填充 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];

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

IV. symmetric:镜像填充,最后一个像素镜像, eg. [1,2,3,4] --> [2,1,1,2,3,4,4,3];

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

fill:padding_mode='constant'时,用于设置填充的像素值;

(3) 代码示例

train_transform = transforms.Compose([
    transforms.Resize((224, 224)),

    transforms.RandomCrop(224, padding=16),
    transforms.RandomCrop(224, padding=(16, 64)),
    transforms.RandomCrop(224, padding=16, fill=(255, 0, 0)),

    transforms.RandomCrop(512, 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) 步骤
随机确定 scaleratio,然后对原始图片进行选取,再将选取的片段缩放到 size大小;
(4) 代码示例

train_transform = transforms.Compose([
    transforms.Resize((224, 224)),

    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) 功能:在图像的左上、右上、左下、右下、中心随机剪裁出尺寸为 size5张图片;
(2) 参数
size: 裁剪图片尺寸,若为 int,则尺寸为 size*size; 若为 (h,w),则尺寸为 h*w;
(3) 代码示例

train_transform = transforms.Compose([
    transforms.Resize((224, 224)),

    transforms.FiveCrop(112),

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

])

使用 FiveCrop时需要使用五维可视化,这是因为 inputs为五维( batch_size*ncrops*chanel*&#x56FE;&#x50CF;&#x5BBD;*&#x56FE;&#x50CF;&#x9AD8;),代码如下:

for epoch in range(MAX_EPOCH):
    for i, data in enumerate(train_loader):

        inputs, labels = data

        bs, ncrops, c, h, w = inputs.shape
        for n in range(ncrops):
            img_tensor = inputs[0, n, ...]
            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) 功能:在图像的左上、右上、左下、右下、中心随机剪裁出尺寸为 size5张图片,然后再对这 5张照片进行水平或者垂直镜像来获得总共 10张图片;
(2) 参数
size: 裁剪图片尺寸,若为 int,则尺寸为 size*size; 若为 (h,w),则尺寸为 h*w;
vertical_flip: 是否垂直翻转,默认为 False代表进行水平翻转;
(3) 代码示例

train_transform = transforms.Compose([
    transforms.Resize((224, 224)),

    transforms.TenCrop(112, vertical_flip=False),

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

])

使用 TenCrop时需要使用 &#x4E94;&#x7EF4;可视化,这是因为 inputs&#x4E94;&#x7EF4;batch_size*ncrops*chanel*&#x56FE;&#x50CF;&#x5BBD;*&#x56FE;&#x50CF;&#x9AD8;),代码如下:

for epoch in range(MAX_EPOCH):
    for i, data in enumerate(train_loader):

        inputs, labels = data

        bs, ncrops, c, h, w = inputs.shape
        for n in range(ncrops):
            img_tensor = inputs[0, n, ...]
            img = transform_invert(img_tensor, train_transform)
            plt.imshow(img)
            plt.show()
            plt.pause(1)
  1. 旋转

3.1 transforms.RandomHorizontalFlip(p=0.5)

transforms.RandomHorizontalFlip(p=0.5)

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

train_transform = transforms.Compose([
    transforms.Resize((224, 224)),

    transforms.RandomHorizontalFlip(p=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)),

    transforms.RandomVerticalFlip(p=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. 当 degreesa时,在区间 (-a,a)之间随机选择旋转角度;
II. 当 degrees(a,b)时,在区间 (a,b)之间随机选择旋转角度;
resample: 重采样方法;
expand: 是否扩大图片以保持原图信息,因为旋转后可能有些信息被遮挡了而丢失,如果扩大尺寸则可以显示完整图片信息;
center: 旋转点设置,默认沿着中心旋转;
(3) 代码示例

train_transform = transforms.Compose([
    transforms.Resize((224, 224)),

    transforms.RandomRotation(90),
    transforms.RandomRotation((90), expand=True),
    transforms.RandomRotation(30, center=(0, 0)),
    transforms.RandomRotation(30, center=(0, 0), expand=True),

    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std),
])
  1. 完整代码示例

"""
@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

def set_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}

def transform_invert(img_, transform_train):
"""
    将data 进行反transfrom操作
    :param img_: tensor
    :param transform_train: torchvision.transforms
    :return: PIL image
"""
    if 'Normalize' in str(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])

    img_ = img_.transpose(0, 2).transpose(0, 1)
    img_ = np.array(img_) * 255

    if img_.shape[2] == 3:
        img_ = Image.fromarray(img_.astype('uint8')).convert('RGB')
    elif 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_

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)),

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

valid_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(norm_mean, norm_std)
])

train_data = RMBDataset(data_dir=train_dir, transform=train_transform)
valid_data = RMBDataset(data_dir=valid_dir, transform=valid_transform)

train_loader = DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
valid_loader = DataLoader(dataset=valid_data, batch_size=BATCH_SIZE)

for epoch in range(MAX_EPOCH):
    for i, data in enumerate(train_loader):

        inputs, labels = data

        img_tensor = inputs[0, ...]
        img = transform_invert(img_tensor, train_transform)
        plt.imshow(img)
        plt.show()
        plt.pause(0.5)
        plt.close()

        bs, ncrops, c, h, w = inputs.shape

Original: https://blog.csdn.net/yanzhiwen2/article/details/123870111
Author: yanzhiwen2
Title: [九]深度学习Pytorch-transforms图像增强(剪裁、翻转、旋转)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/729059/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球