Python图像读写方法对比

  训练视觉相关的神经网络模型时,总是要用到图像的读写。方法有很多,比如matplotlib、cv2、PIL等。下面比较几种读写方式,旨在选出一个最快的方式,提升训练速度。

实验标准

  因为训练使用的框架是Pytorch,因此读取的实验标准如下:

  1、读取分辨率都为1920x1080的5张图片(png格式一张,jpg格式四张)并保存到数组。

  2、将读取的数组转换为维度顺序为CxHxW的Pytorch张量,并保存到显存中(我使用GPU训练),其中三个通道的顺序为RGB。

  3、记录各个方法在以上操作中所耗费的时间。因为png格式的图片大小差不多是质量有微小差异的jpg格式的10倍,所以数据集通常不会用png来保存,就不比较这两种格式的读取时间差异了。

  写入的实验标准如下:

  1、将5张1920x1080的5张图像对应的Pytorch张量转换为对应方法可使用的数据类型数组。

  2、以jpg格式保存五张图片。

  3、记录各个方法保存图片所耗费的时间。

实验情况

cv2

  因为有GPU,所以cv2读取图片有两种方式:

  1、先把图片都读取为一个numpy数组,再转换成保存在GPU中的pytorch张量。

  2、初始化一个保存在GPU中的pytorch张量,然后将每张图直接复制进这个张量中。

  第一种方式实验代码如下:

1import os, torch 2import cv2 as cv 3import numpy as np 4from time import time 5 6read_path = 'D:test' 7write_path = 'D:test\\write\\' 8 9# cv2读取 1 10start_t = time() 11imgs = np.zeros([5, 1080, 1920, 3]) 12for img, i in zip(os.listdir(read_path), range(5)): 13 img = cv.imread(filename=os.path.join(read_path, img)) 14 imgs[i] = img 15imgs = torch.tensor(imgs).to('cuda')[...,[2,1,0]].permute([0,3,1,2])/255 16print('cv2 读取时间1:', time() - start_t) 17# cv2保存 18start_t = time() 19imgs = (imgs.permute([0,2,3,1])[...,[2,1,0]]*255).cpu().numpy() 20for i in range(imgs.shape[0]): 21 cv.imwrite(write_path + str(i) + '.jpg', imgs[i]) 22print('cv2 保存时间:', time() - start_t)

  实验结果:

1cv2 读取时间10.39693760871887207 2cv2 保存时间: 0.3560612201690674

  第二种方式实验代码如下:

1import os, torch 2import cv2 as cv 3import numpy as np 4from time import time 5 6read_path = 'D:test' 7write_path = 'D:test\\write\\' 8 9 10# cv2读取 2 11start_t = time() 12imgs = torch.zeros([5, 1080, 1920, 3], device='cuda') 13for img, i in zip(os.listdir(read_path), range(5)): 14 img = torch.tensor(cv.imread(filename=os.path.join(read_path, img)), device='cuda') 15 imgs[i] = img 16imgs = imgs[...,[2,1,0]].permute([0,3,1,2])/255 17print('cv2 读取时间2:', time() - start_t) 18# cv2保存 19start_t = time() 20imgs = (imgs.permute([0,2,3,1])[...,[2,1,0]]*255).cpu().numpy() 21for i in range(imgs.shape[0]): 22 cv.imwrite(write_path + str(i) + '.jpg', imgs[i]) 23print('cv2 保存时间:', time() - start_t)

  实验结果:

1cv2 读取时间20.23636841773986816 2cv2 保存时间: 0.3066873550415039

matplotlib

  同样两种读取方式,第一种代码如下:

1import os, torch 2import numpy as np 3import matplotlib.pyplot as plt 4from time import time 5 6read_path = 'D:test' 7write_path = 'D:test\\write\\' 8 9# matplotlib 读取 1 10start_t = time() 11imgs = np.zeros([5, 1080, 1920, 3]) 12for img, i in zip(os.listdir(read_path), range(5)): 13 img = plt.imread(os.path.join(read_path, img)) 14 imgs[i] = img 15imgs = torch.tensor(imgs).to('cuda').permute([0,3,1,2])/255 16print('matplotlib 读取时间1:', time() - start_t) 17# matplotlib 保存 18start_t = time() 19imgs = (imgs.permute([0,2,3,1])).cpu().numpy() 20for i in range(imgs.shape[0]): 21 plt.imsave(write_path + str(i) + '.jpg', imgs[i]) 22print('matplotlib 保存时间:', time() - start_t)

  实验结果:

1matplotlib 读取时间10.45380306243896484 2matplotlib 保存时间: 0.768944263458252

  第二种方式实验代码:

1import os, torch 2import numpy as np 3import matplotlib.pyplot as plt 4from time import time 5 6read_path = 'D:test' 7write_path = 'D:test\\write\\' 8 9# matplotlib 读取 2 10start_t = time() 11imgs = torch.zeros([5, 1080, 1920, 3], device='cuda') 12for img, i in zip(os.listdir(read_path), range(5)): 13 img = torch.tensor(plt.imread(os.path.join(read_path, img)), device='cuda') 14 imgs[i] = img 15imgs = imgs.permute([0,3,1,2])/255 16print('matplotlib 读取时间2:', time() - start_t) 17# matplotlib 保存 18start_t = time() 19imgs = (imgs.permute([0,2,3,1])).cpu().numpy() 20for i in range(imgs.shape[0]): 21 plt.imsave(write_path + str(i) + '.jpg', imgs[i]) 22print('matplotlib 保存时间:', time() - start_t)

  实验结果:

1matplotlib 读取时间20.2044532299041748 2matplotlib 保存时间: 0.4737534523010254

  需要注意的是,matplotlib读取png格式图片获取的数组的数值是在$[0, 1]$范围内的浮点数,而jpg格式图片却是在$[0, 255]$范围内的整数。所以如果数据集内图片格式不一致,要注意先转换为一致再读取,否则数据集的预处理就麻烦了。

PIL

  PIL的读取与写入并不能直接使用pytorch张量或numpy数组,要先转换为Image类型,所以很麻烦,时间复杂度上肯定也是占下风的,就不实验了。

torchvision

  torchvision提供了直接从pytorch张量保存图片的功能,和上面读取最快的matplotlib的方法结合,代码如下:

1import os, torch 2import matplotlib.pyplot as plt 3from time import time 4from torchvision import utils 5 6read_path = 'D:test' 7write_path = 'D:test\\write\\' 8 9# matplotlib 读取 2 10start_t = time() 11imgs = torch.zeros([5, 1080, 1920, 3], device='cuda') 12for img, i in zip(os.listdir(read_path), range(5)): 13 img = torch.tensor(plt.imread(os.path.join(read_path, img)), device='cuda') 14 imgs[i] = img 15imgs = imgs.permute([0,3,1,2])/255 16print('matplotlib 读取时间2:', time() - start_t) 17# torchvision 保存 18start_t = time() 19for i in range(imgs.shape[0]): 20 utils.save_image(imgs[i], write_path + str(i) + '.jpg') 21print('torchvision 保存时间:', time() - start_t)

  实验结果:

1matplotlib 读取时间20.15358829498291016 2torchvision 保存时间: 0.14760661125183105

  可以看出这两个是最快的读写方法。另外,要让图片的读写尽量不影响训练进程,我们还可以让这两个过程与训练并行。另外,utils.save_image可以将多张图片拼接成一张来保存,具体使用方法如下:

1utils.save_image(tensor = imgs, # 要保存的多张图片张量 shape = [n, C, H, W] 2 fp = 'test.jpg', # 保存路径 3 nrow = 5, # 多图拼接时,每行所占的图片数 4 padding = 1, # 多图拼接时,每张图之间的间距 5 normalize = True, # 是否进行规范化,通常输出图像用tanh,所以要用规范化 6 range = (-1,1)) # 规范化的范围
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Python图像读写方法对比 - HelloWorld