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

图片读取速度测试及加速

  • 1、各类python包读取图片接口测试
  • 2、通过多核进行加速读取
  • 3、参考

机器学习深度学习的发展意味着大批量的读取数据变得越来越多,读取速度也强调越来越快,本着研究一下各框架的读取速度进行测试一下,然后分享出来。电脑环境是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图像处理)