torchvision 之 transforms 简单使用

torchvision.transforms是一个图像转换工具包,不同的图像转换组件可以通过Compose来连接从而形成一个流水线(类似于torch.nn.Sequential),以实现更复杂的图像转换功能。

Image\Tensor\ndarray 之间的相互转换

绝大多数转换都同时支持 PIL 的Image对象和张量图像。当然也可以使用ToTensor()ToPILImage()等工具实现 PIL 对象和张量图像之间的相互转换。

还支持批量地转换张量图像。一般batch图像是一个具有(B, C, H, W)尺寸地张量,其中 B 代表每个 batch 中地图像个数。

ToTensor()

ToTensor()可以将一个PIL Image或一个具有(H, W, C)尺寸且数值范围在[0, 255]之间的ndarray转换成一个形状为(C, H, W)且数值范围在[0, 1]之间的浮点型张量。

转换的前提条件:对于 PIL Image,图像模式必须为(L, LA, P, I, F. RGB, YCbCr, RGBA, CMYL, 1)中的一种,对于ndarray,它的数据类型必须为np.uint8

事实上,ToTensor 中的归一化操作均是通过除以数组中的最大元进行实现的。PIL Image 和 ndarray 转化成 Tensor 后内容的顺序不一致。PIL Image 转化成 Tensor 后,排列格式为 [R, G, B],即 img[0] 代表 R 通道;而 opencv ndarray 转化成 Tensor 后,排列格式为 [B, G, R]。

import cv2
import torchvision
from PIL import Image

imgcv = cv2.imread('/path/to/fig') # shape: H W C uint8 [0-255] B G R
image = Image.open('/path/to/fig')

totenor = torchvision.transform.ToTensor()

imgcv_tensor = totensor(imgcv) # shape: C H W torch.float32 [0-1] B G R
image_tensor = totensor(image) # shape: C H W torch.float32 [0-1] R G B

PILToTensor()

不进行归于化的 Image to Tensor

import torchvision
from PIL import Image

img = Image.open('/path/to/img')

totensor = torchvision.transform.PILToTensor()

tensor = totensor(img) # shape: C H W torch.uint8 [0-255]

ToPILImage()

将 Tensor 或 ndarray 转为 Image.
其中 Tensor 要求形状为 (C, H, W),ndarray 要求形状为 (H, W, C)

import torchvision
import cv2
from PIL import Image

imgcv = cv2.imread('/path/to/img') # B G R
imgcv = imgcv[:, :, -1::-1]

totensor = torchvision.transform.ToTensor()

tensor = totensor(imgcv.copy())

topilimage = torchvision.transforms.ToPILImage()

image1 = topilimage(imgcv)

image2 = topilimage(tensor)

Compose

很多时候,我们需要对大量的图片完成一系列的图像转换操作,这时候我们就能用 Compose() 将这些操作组合成一道流水线,以简化我们的代码。

trans_pipeline = transforms.Compose([
    transforms.RandomHorizontalFlip(1.0),
    transforms.Resize((300, 300)),
    transforms.ToTensor(),
])

img = Image.open('./pics/1.jpg')
img = trans_pipeline(img)

# 按需自定义Compose, 当然Compose_imglabel里的transforms也需做出自己的定义
class Compose_imglabel(object):
    def __init__(self, transforms):
        self.transforms = transforms

    def __call__(self, img, label):
        for t in self.transforms:
            img, label = t(img, label)
        return img, label
### 自定义 Torchvision Transforms 为了实现特定的数据预处理需求,在 PyTorch 中可以通过继承 `torchvision.transforms` 的基类来创建自定义转换器。这允许灵活地添加新的图像变换逻辑,从而更好地适应不同的应用场景。 #### 创建自定义 Transform 类 通过继承 `torch.nn.Module` 或者直接从 `object` 继承并遵循一定的接口约定可以构建一个新的 transform 对象。通常情况下推荐继承 `nn.Module` 以便于管理参数和其他模块化特性[^1]。 下面是一个简单的例子展示如何编写一个名为 `CustomTransform` 的新变换: ```python from torchvision import transforms as T import torch.nn as nn import numpy as np class CustomTransform(nn.Module): """Apply custom transformation to input PIL image or tensor.""" def __init__(self, param=0.5): super().__init__() self.param = param def forward(self, img): """ Args: img (PIL Image or Tensor): Input image. Returns: PIL Image or Tensor: Transformed image. """ # Example operation - apply random brightness adjustment if isinstance(img, torch.Tensor): img_np = img.numpy() else: img_np = np.array(img) adjusted_img = ... # Implement your own logic here using self.param and img_np # For instance, adjust the brightness of the image based on some criteria if isinstance(img, torch.Tensor): return torch.from_numpy(adjusted_img) else: return Image.fromarray(np.uint8(adjusted_img)) ``` 在这个例子中,`forward()` 方法接收输入图片(既可以是 PIL 图像也可以是张量),执行某些操作后再返回相同类型的对象。这里假设实现了亮度调整的功能作为示范。 #### 将自定义 Transform 集成到现有 Pipeline 中 一旦有了自己的变换类之后就可以很容易地将其集成到标准的 pipeline 当中去: ```python # Define a list of transformations including our custom one transform_pipeline = T.Compose([ T.Resize((256, 256)), # Resize images to fixed size CustomTransform(param=0.7), # Apply custom transformation with specified parameter value T.ToTensor(), # Convert final result into tensors suitable for neural networks ]) dataset = ImageFolder(root='path/to/images', transform=transform_pipeline)[^2] ``` 上述代码片段展示了如何组合多个变换并将它们应用于来自文件系统的图像数据集上。注意这里的 `ImageFolder` 是用来加载分类好的图像目录结构的一个便捷方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值