python数据处理——图片读取速度测试及多核加速

机器学习深度学习的发展意味着大批量的读取数据变得越来越多,读取速度也强调越来越快,本着研究一下各框架的读取速度进行测试一下,然后分享出来。电脑环境是i7-8700 + 16G内存 + GTX1060配置。

1、各类python包读取图片接口测试

import cv2, glob
import time
from scipy.misc import imread as scipy_imread
from skimage import io
from PIL import Image
import numpy as np
from keras.preprocessing import image as keras_imread
import mxnet as mx  # mx.image

def ReadImage_SpeedTest():
    image_path = './Test_Image/image_1_1000_750.jpg'
    # image_path = './Test_Image/image_2_4608_3456.jpg'
    readTimes = 100
    img = cv2.imread(image_path)
    print("图像大小高*宽: {} * {}: ".format(img.shape[0], img.shape[1]))

    ## OpenCV 读取图片
    time1 = time.time()
    for i in range(readTimes):
        img_opencv = cv2.imread(image_path)
    print("OpenCV读取图片速度:", round(readTimes / (time.time() - time1), 2), "  张图片每秒(files/sec)")

    ## scipy 读取图片
    time1 = time.time()
    for i in range(readTimes):
        img_scipy = scipy_imread(image_path)
    print("scipy读取图片速度:", round(readTimes / (time.time() - time1), 2), "  张图片每秒(files/sec)")

    ## skimage 读取图片
    time1 = time.time()
    for i in range(readTimes):
        img_skimage = io.imread(image_path)
    print("skimage读取图片速度:", round(readTimes / (time.time() - time1), 2), "  张图片每秒(files/sec)")


    ## PIL 读取图片
    time1 = time.time()
    for i in range(readTimes):
        img = Image.open(image_path) ## img是Image内部的类文件,还需转换
        # img_PIL = np.array(img) ## numpy转换
    print("PIL 读取图片速度:", round(readTimes / (time.time() - time1), 2), "  张图片每秒(files/sec)")

    ## keras 读取图片
    time1 = time.time()
    for i in range(readTimes):
        img = keras_imread.load_img(image_path)
        img_keras = keras_imread.img_to_array(img)
    print("keras 读取图片速度:", round(readTimes / (time.time() - time1), 2), "  张图片每秒(files/sec)")

    ## mxnet 读取图片
    time1 = time.time()
    for i in range(readTimes):
        # img_mxnet = mx.image.imdecode(open(image_path,'rb').read())
        img_mxnet = mx.image.imread(image_path)
    mx.nd.waitall()
    print("mxnet 读取图片速度:", round(readTimes / (time.time() - time1), 2), "  张图片每秒(files/sec)")

测试结果:

输入图片是高*宽为750 * 1000时 :
OpenCV读取图片速度: 118.8 张图片每秒(files/sec)
scipy读取图片速度: 92.08 张图片每秒(files/sec)
skimage读取图片速度: 92.93 张图片每秒(files/sec)
PIL 读取图片速度: 93.36 张图片每秒(files/sec)
PIL 读取图片速度: 6265.02 张图片每秒(files/sec)(不转换numpy)
keras 读取图片速度: 73.4 张图片每秒(files/sec)
mxnet 读取图片速度: 95.83 张图片每秒(files/sec)

图像大小高*宽: 3456 * 4608 :
OpenCV读取图片速度: 6.67 张图片每秒(files/sec)
scipy读取图片速度: 4.47 张图片每秒(files/sec)
skimage读取图片速度: 4.52 张图片每秒(files/sec)
PIL 读取图片速度: 4.54 张图片每秒(files/sec)(转换numpy)
PIL 读取图片速度: 4262.03 张图片每秒(files/sec)(不转换numpy)
keras 读取图片速度: 3.49 张图片每秒(files/sec)
**mxnet 读取图片速度: 5.44 张图片每秒(files/sec)

可以看到,不管多大图片,在正常读取为numpy格式后,仍然是OpenCV快。但PIL若只读取图片,只执行:

 img = Image.open(image_path)

简直飞快,此时的img是Image内部的类文件,需要做相应的np.array()转换才可以进行图像操作。但这样有一个好处就是,在进行批量图像生成或增强的时候,可以查看自己得到的图片是否完全正确,仅仅通过open就可以验证了,而不需要每一张图片都读取出来。

2、通过多核进行加速读取

说完以上的读取速度,我们尝试着再快一些。首先,Python 程序是使用单 CPU 核心单个进程执行,但当前大部分设备cpu都是多核,比如i7-8700就是六核,我们可以考虑多核加速。即通过使用 Python 的 concurrent.futures 模块。

常规的读取批量数据都是以for循环开始,然后对每个文件进行处理至结束。如下代码:

image_path = 'H:\\DataSet'
#单独for循环 依次读取
start_time = time.time()
for image_filename in glob.glob(image_path + '\\*.jpg'):
    img = cv2.imread(image_filename)
    # img = cv2.resize(img, (600, 600))
print('for 循环 time:', round(time.time() - start_time, 2), " 秒")

得到的运行时间:
接下来利用concurrent.futures 模块多核处理,在我们图像列表中,可以让 Python 做类似的工作:

  • 将 jpg 文件列表分成 6 个小组;
  • 运行 Python 解释器中的 6 个独立实例;
  • 让 Python 的每个实例处理 6 个数据小组中的一个;
  • 结合四个处理过程得到的结果得出最终结果列表。

代码改写如下:

import concurrent.futures
def load_and_resize(image_filename):
    img = cv2.imread(image_filename)
    # img = cv2.resize(img, (600, 600))

start_time1 = time.time()
with concurrent.futures.ProcessPoolExecutor() as executor: ## 默认为1
	image_files = glob.glob(image_path + '\\*.jpg')
	'''
	executor.map() 将你想要运行的函数和列表作为输入,列表中的每个元素
	都是我们函数的单个输入,由于我们有6个核,我们将同时处理该列表中的6个项目
	'''
	executor.map(load_and_resize, image_files)
print('多核并行加速后运行 time:', round(time.time() - start_time1, 2), " 秒")

测试结果:

700 张图片 : (分辨率从400×800到3578×2596不等)

for 循环 time: 			23.57  秒
多核并行加速后运行 time: 	5.55  秒

6888 张图片 : (分辨率从120×240到4541×2277不等)

for 循环 time: 				258.27  秒
多核并行加速后运行 time: 		41.49  秒

六核心CPU, 数据量越大基本就是加速到6倍,极大的加速了数据的读取过程。

3、参考

[1]:https://blog.csdn.net/twt520ly/article/details/79760379
[2]:https://zhuanlan.zhihu.com/p/30383580
[3]:https://blog.csdn.net/u012193416/article/details/87531272
[4]:https://blog.csdn.net/e01528/article/details/83148892

Python 中,我们可以使用内置的 `open()` 函数来打开一个文件,然后使用文件对象进行读写操作。下面是一个简单的例子: ## 写入文件 ```python # 打开文件(如果文件不存在则创建) file = open("example.txt", "w") # 写入内容 file.write("Hello, World!\n") file.write("This is an example file.\n") # 关闭文件 file.close() ``` 在上面的代码中,我们使用 `open()` 函数打开一个名为 `example.txt` 的文件,并指定模式为 `"w"`,表示写入模式。如果文件不存在,则会创建一个新的文件。然后,我们使用 `write()` 方法写入两行文本内容,并在每行的末尾添加了一个换行符。最后,我们使用 `close()` 方法关闭文件。 ## 读取文件 ```python # 打开文件 file = open("example.txt", "r") # 读取内容 content = file.read() # 关闭文件 file.close() # 输出内容 print(content) ``` 在上面的代码中,我们再次使用 `open()` 函数打开 `example.txt` 文件,并指定模式为 `"r"`,表示读取模式。然后,我们使用 `read()` 方法读取文件的所有内容,并将结果保存到 `content` 变量中。最后,我们使用 `print()` 函数输出 `content` 变量的值。 需要注意的是,在读取文件时,我们需要确保文件已经存在,否则会抛出 `FileNotFoundError` 异常。此外,在读取大文件时,我们可以使用 `readline()` 或 `readlines()` 方法逐行读取文件的内容,而不是一次性读取整个文件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值