VPI - 视觉编程接口

3.2 版本

PyTorch/CUDA 互操作性

概述

此示例展示了 VPI 和 PyTorch 之间在 Python 中的互操作性如何工作。它展示了一组简单的图像处理操作,应用于 PyTorch 和 VPI 中的示例输入图像,而无需在互操作期间进行任何内存复制。

此示例使用 PyTorch 作为示例,但是,这种互操作性可以与任何支持 cuda 数组接口的库一起使用。

诸如以下的库

该示例从您提供的图像开始,将其转换为灰度图像,然后对其执行以下操作序列

  1. 使用 PyTorch 降低图像强度
  2. 执行 PyTorch -> VPI 互操作性,无需内存复制
    vpi_image = vpi.asimage(torch_image)
  3. 使用 VPI 应用盒状滤波器
  4. 执行 VPI -> PyTorch 互操作性,无需内存复制
    with vpi_image.rlock_cuda() as cuda_buffer
    torch_image = torch.as_tensor(cuda_buffer)
    或者,使用额外的深度内存复制
    torch_image = torch.as_tensor(vpi_image.cuda())
  5. 使用 PyTorch 增加图像强度

然后将结果保存到磁盘。

说明

用法是

python3 main.py <输入图像>

其中

  • 输入图像:输入图像文件名;它接受 png、jpeg 以及可能的其他格式。

这是一个示例

  • Python
    python3 main.py ../assets/kodim08.png

该示例将生成 vpi_pytorch.png 作为输出文件。

结果

输入图像输出图像

源代码

为了方便起见,以下代码也安装在示例目录中。

27 import vpi
28 import torch
29 import numpy as np
30 
31 from PIL import Image, ImageOps
32 from argparse import ArgumentParser
33 
34 # Parse command line arguments
35 parser = ArgumentParser()
36 parser.add_argument('input', help='Image to be used as input')
37 
38 args = parser.parse_args()
39 
40 # Make sure CUDA is available for this example
41 assert torch.cuda.is_available()
42 cuda_device = torch.device('cuda')
43 
44 # Read the input image and convert it to grayscale
45 try
46  pil_image = ImageOps.grayscale(Image.open(args.input))
47 except IOError
48  sys.exit("Input file not found")
49 except
50  sys.exit("Error with input file")
51 
52 # Pillow -> NumPy --------------------------------------
53 np_image = np.asarray(pil_image)
54 
55 # NumPy -> PyTorch/CUDA --------------------------------
56 torch_image = torch.asarray(np_image).cuda()
57 
58 # Perform an operation using PyTorch
59 torch_image = torch_image/255 * 0.5
60 
61 # PyTorch/CUDA -> VPI, no copies involved --------------
62 vpi_image = vpi.asimage(torch_image)
63 
64 # Peform operations using VPI's CUDA backend
65 with vpi.Backend.CUDA
66  # Blur the input image with box filter
67  vpi_image = vpi_image.box_filter(3)
68 
69 # VPI -> PyTorch/CUDA, no copies involved --------------
70 with vpi_image.rlock_cuda() as cuda_buffer
71  # Perform another operation using PyTorch
72  torch_tensor = torch.as_tensor(cuda_buffer, device=cuda_device)
73  torch_image = torch_tensor*255 + 128
74 
75 # PyTorch -> NumPy -------------------------------------
76 np_image = np.asarray(torch_image.cpu())
77 
78 # NumPy -> Pillow --------------------------------------
79 pil_image = Image.fromarray(np_image)
80 
81 # Save the output to disk
82 pil_image.convert('L').save('vpi_pytorch.png')