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张量,然后将每张图直接复制进这个张量中。
第一种方式实验代码如下:
import os, torch
import cv2 as cv
import numpy as np
from time import time read_path = 'D:test'
write_path = 'D:test\\write\\' # cv2读取 1
start_t = time()
imgs = np.zeros([5, 1080, 1920, 3])
for img, i in zip(os.listdir(read_path), range(5)):
img = cv.imread(filename=os.path.join(read_path, img))
imgs[i] = img
imgs = torch.tensor(imgs).to('cuda')[...,[2,1,0]].permute([0,3,1,2])/255
print('cv2 读取时间1:', time() - start_t)
# cv2保存
start_t = time()
imgs = (imgs.permute([0,2,3,1])[...,[2,1,0]]*255).cpu().numpy()
for i in range(imgs.shape[0]):
cv.imwrite(write_path + str(i) + '.jpg', imgs[i])
print('cv2 保存时间:', time() - start_t)
实验结果:
cv2 读取时间1: 0.39693760871887207
cv2 保存时间: 0.3560612201690674
第二种方式实验代码如下:
import os, torch
import cv2 as cv
import numpy as np
from time import time read_path = 'D:test'
write_path = 'D:test\\write\\' # cv2读取 2
start_t = time()
imgs = torch.zeros([5, 1080, 1920, 3], device='cuda')
for img, i in zip(os.listdir(read_path), range(5)):
img = torch.tensor(cv.imread(filename=os.path.join(read_path, img)), device='cuda')
imgs[i] = img
imgs = imgs[...,[2,1,0]].permute([0,3,1,2])/255
print('cv2 读取时间2:', time() - start_t)
# cv2保存
start_t = time()
imgs = (imgs.permute([0,2,3,1])[...,[2,1,0]]*255).cpu().numpy()
for i in range(imgs.shape[0]):
cv.imwrite(write_path + str(i) + '.jpg', imgs[i])
print('cv2 保存时间:', time() - start_t)
实验结果:
cv2 读取时间2: 0.23636841773986816
cv2 保存时间: 0.3066873550415039
matplotlib
同样两种读取方式,第一种代码如下:
import os, torch
import numpy as np
import matplotlib.pyplot as plt
from time import time read_path = 'D:test'
write_path = 'D:test\\write\\' # matplotlib 读取 1
start_t = time()
imgs = np.zeros([5, 1080, 1920, 3])
for img, i in zip(os.listdir(read_path), range(5)):
img = plt.imread(os.path.join(read_path, img))
imgs[i] = img
imgs = torch.tensor(imgs).to('cuda').permute([0,3,1,2])/255
print('matplotlib 读取时间1:', time() - start_t)
# matplotlib 保存
start_t = time()
imgs = (imgs.permute([0,2,3,1])).cpu().numpy()
for i in range(imgs.shape[0]):
plt.imsave(write_path + str(i) + '.jpg', imgs[i])
print('matplotlib 保存时间:', time() - start_t)
实验结果:
matplotlib 读取时间1: 0.45380306243896484
matplotlib 保存时间: 0.768944263458252
第二种方式实验代码:
import os, torch
import numpy as np
import matplotlib.pyplot as plt
from time import time read_path = 'D:test'
write_path = 'D:test\\write\\' # matplotlib 读取 2
start_t = time()
imgs = torch.zeros([5, 1080, 1920, 3], device='cuda')
for img, i in zip(os.listdir(read_path), range(5)):
img = torch.tensor(plt.imread(os.path.join(read_path, img)), device='cuda')
imgs[i] = img
imgs = imgs.permute([0,3,1,2])/255
print('matplotlib 读取时间2:', time() - start_t)
# matplotlib 保存
start_t = time()
imgs = (imgs.permute([0,2,3,1])).cpu().numpy()
for i in range(imgs.shape[0]):
plt.imsave(write_path + str(i) + '.jpg', imgs[i])
print('matplotlib 保存时间:', time() - start_t)
实验结果:
matplotlib 读取时间2: 0.2044532299041748
matplotlib 保存时间: 0.4737534523010254
需要注意的是,matplotlib读取png格式图片获取的数组的数值是在$[0, 1]$范围内的浮点数,而jpg格式图片却是在$[0, 255]$范围内的整数。所以如果数据集内图片格式不一致,要注意先转换为一致再读取,否则数据集的预处理就麻烦了。
PIL
PIL的读取与写入并不能直接使用pytorch张量或numpy数组,要先转换为Image类型,所以很麻烦,时间复杂度上肯定也是占下风的,就不实验了。
torchvision
torchvision提供了直接从pytorch张量保存图片的功能,和上面读取最快的matplotlib的方法结合,代码如下:
import os, torch
import matplotlib.pyplot as plt
from time import time
from torchvision import utils read_path = 'D:test'
write_path = 'D:test\\write\\' # matplotlib 读取 2
start_t = time()
imgs = torch.zeros([5, 1080, 1920, 3], device='cuda')
for img, i in zip(os.listdir(read_path), range(5)):
img = torch.tensor(plt.imread(os.path.join(read_path, img)), device='cuda')
imgs[i] = img
imgs = imgs.permute([0,3,1,2])/255
print('matplotlib 读取时间2:', time() - start_t)
# torchvision 保存
start_t = time()
for i in range(imgs.shape[0]):
utils.save_image(imgs[i], write_path + str(i) + '.jpg')
print('torchvision 保存时间:', time() - start_t)
实验结果:
matplotlib 读取时间2: 0.15358829498291016
torchvision 保存时间: 0.14760661125183105
可以看出这两个是最快的读写方法。另外,要让图片的读写尽量不影响训练进程,我们还可以让这两个过程与训练并行。
Python图像读写方法对比的更多相关文章
- Object-c:两种文件读写的对比
一.读写方法对比:(主要针对本地读取本地文件) 方式\操作 读 写 非URL方式 stringWithContentsOfFile writeToFile URL方式 stringWithConten ...
- Python 3 读写文件的简单方法!
Python 3 读写文件的简单方法! a = open('test.txt','w') 这行代码创建了一个名为test的文本文档,模式是写入(模式分为三种,w代表写入,r代表阅读,a代表在尾行添加) ...
- Python OpenCV 图像相识度对比
强大的openCV能做什么我就不啰嗦,你能想到的一切图像+视频处理. 这里,我们说说openCV的图像相似度对比, 嗯,说好听一点那叫图像识别,但严格讲, 图像识别是在一个图片中进行类聚处理,比如图片 ...
- python——几种截图对比方式!
本次记录的几种截图对比方式,主要是为了在进行手机自动化测试时,通过截图对比来判断测试的正确性,方式如下: # -*- coding: utf- -*- ''' 用途:利用python实现多种方法来实现 ...
- 15.python文件(file)方法详解
文件的基本操作 文件读写: 文件的读写满足以下3个步骤: 1).打开文件 2).操作数据(读.写) 3).关闭文件 --> 不要忘记 1).打开文件: python的open() 方法用于打开一 ...
- python类及其方法
python类及其方法 一.介绍 在 Python 中,面向对象编程主要有两个主题,就是类和类实例类与实例:类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中 ...
- NIO与普通IO文件读写性能对比
最近在熟悉java的nio功能.nio采用了缓冲区的方式进行文件的读写,这一点更接近于OS执行I/O的方式.写了个新旧I/O复制文件的代码,练练手,顺便验证一下两者读写性能的对比,nio是否真的比普通 ...
- iPhone开发 数据持久化总结(终结篇)—5种数据持久化方法对比
iPhone开发 数据持久化总结(终结篇)—5种数据持久化方法对比 iphoneiPhoneIPhoneIPHONEIphone数据持久化 对比总结 本篇对IOS中常用的5种数据持久化方法进行简单 ...
- python内置方法
1. 简介 本指南归纳于我的几个月的博客,主题是 魔法方法 . 什么是魔法方法呢?它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加"魔法"的特殊方法. 它们经常是 ...
随机推荐
- 创建好maven项目以后发现无法创建scala文件
今天创建了一个maven项目 然后准备创建scala文件的时候发现没有Scala 然后只好上网上找方法了 下面是一种解决方法 1.点击file,选择settings 进去之后,选择build 进去 ...
- ls: 显示目下的内容及相关属性信息
ls: 显示目下的内容及相关属性信息 [功能说明] ls 命令可以理解为英文单词 "list" 的缩写,其功能是列出目录的内容及其内容属性信息(list directory con ...
- 异步编程新方式async/await
一.前言 实际上对async/await并不是很陌生,早在阮大大的ES6教程里面就接触到了,但是一直处于理解并不熟练使用的状态,于是决定重新学习并且总结一下,写了这篇博文.如果文中有错误的地方还请各位 ...
- 超好用的UnixLinux 命令技巧 大神为你详细解读
1.删除一个大文件 我在生产服务器上有一个很大的200GB的日志文件需要删除.我的rm和ls命令已经崩溃,我担心这是由于巨大的磁盘IO造成的,要删除这个大文件,输入: > /path/to/fi ...
- mqtt网关
MQTT网关 MQTT网关是可以是将普通的串口数据.Modbus RTU数据等转化为MQTT协议的从而方便与平台的对接,通过连接服务器.订阅和发布主题来实现传统设备和MQTT云端的联系.例如,笔记本和 ...
- 很多人都搞不清楚C语言和C++的关系!今天我们来一探究竟为大家解惑~
最近,身边有许多小伙伴已经开始学习编程了,但是呢,学习又会碰到许多的问题,其中作为新手小白提到最多的问题就是编程语言的选择. 每次遇到这种问题,看起来很简单,但是又有很多小伙伴搞不清编程语言之间的关系 ...
- Docker Stack 笔记
Docker Compose (Docker Stack) image: Specify the image to start the container from. Can either be a ...
- trade可撤销贪心正确性证明
鉴于tarde这道题正解过于好写,导致我对这个诡异的贪心的正确性产生了疑问,所以花了2h的时间与同机房神犇M-Blanca,Midoria7,goote~进行讨论,最后与goote~犇犇各得出了一个正 ...
- wine实用经验教程
本篇讲类unix系统下的用以模拟运行Windows程序的wine.会从普通使用者的比较实用的角度去讲.有专为国内用户准备的内容. 本篇面向有Linux经验但对wine不熟悉的人. wine可靠吗?该不 ...
- spring boot:用rocketmq消息订阅实现删除购物车商品功能(spring boot 2.3.3)
一,为什么要使用消息队列实现删除购物车商品功能? 消息队列主要用来处理不需要立刻返回结果的业务, 常见的例子: 用户在下单后,要清除原购物车中的商品, 这个处理过程不需要马上实现也不需要返回结果给用户 ...