python读图命令与效率汇总

文章目录

  • python读图命令汇总
  • 各个函数读图效率对比
    • 结果
    • 代码

python读图命令汇总

python可以用来读图的命令有:

库(版本) 函数
opencv-python (4.2.0) cv2.imread
imageio(2.8.0) imageio.imread
skimage.io (0.16.2) skimage.io.imread
matplotlib.pyplot (3.1.3) matplotlib.pyplot.imread
matplotlib.image (3.1.3) matplotlib.image.imread
PIL.Image (7.1.2) PIL.Image.open & np.array
tensorflow (2.1) tf.io.read_file & tf.io.decode_image

各个函数读进来的图片数据有些不同,主要有(以下测试不包含tensorflow):

  • cv2读入的图片通道顺序是BGR,其他均为RGB
  • cv2读进来的jpg图片即使调整通道顺序后与其他的函数读入的也不同(仅jpg不同),存在一点点误差(其他函数的读取结果均相同,但不见得是cv2解码效果比其他的差,很有可能是cv2解码效果优于其他所有)
  • matplotlib读取的png图像的数值范围是[0, 1]的float型,转为[0, 255]的uint8型后结果与其他一样

各个函数读图效率对比

先摆结果,测试代码放后面,有兴趣的话可以在自己电脑上测测。我的CPU是G4560,比较烂。

结果

表中数字表示读取一张1920 x 1080的图片的平均耗时,单位是ms。测试方法是反复读取同一张图片1000次,然后计算平均耗时。

综合来说,除了tensorflow在读jpg图像时效率明显有优势外,其他均是cv2表现最佳。
如果有需要无损保存图片,从后期再使用时的读图效率来看,bmp大大优于png。png占的空间稍小一点,假如不缺那点磁盘空间的话,建议用bmp。

bmp格式是无损不压缩,png格式是无损压缩。为了做到无损,png的压缩比一般不是非常高,具体要看图像内容,如果是自然拍摄的图像或者内容非常丰富的图像,那么压缩比一般不高,如果是内容简单,色彩也非常简单(如纯色图)的图像,那么压缩比还是非常可观的。

函数 jpg png bmp
cv2.imread 31.87 50.99 9.10
imageio.imread 44.02 59.82 17.07
skimage.io.imread 43.37 65.91 19.10
matplotlib.pyplot.imread 44.18 72.30 12.91
matplotlib.image.imread 38.90 67.61 12.72
PIL.Image.open & np.array 45.67 60.84 17.44
tf.io.read_file & tf.io.decode_image 17.74 53.15 19.58

代码

# -*- coding: utf-8 -*-
import time
import cv2
import imageio
import skimage.io
import matplotlib.pyplot
import matplotlib.image

NUM = 1000


def read_time_test(image_file, read_num, func, func_name):
    jpg_file = image_file + '.jpg'
    png_file = image_file + '.png'
    bmp_file = image_file + '.bmp'
    t0 = time.time()
    for i in range(read_num):
        image = func(jpg_file)
    t_cost = time.time() - t0
    print('%s, jpg read time: %.2f' % (func_name, t_cost / read_num * 1000))

    t0 = time.time()
    for i in range(read_num):
        image = func(png_file)
    t_cost = time.time() - t0
    print('%s, png read time: %.2f' % (func_name, t_cost / read_num * 1000))

    t0 = time.time()
    for i in range(read_num):
        image = func(bmp_file)
    t_cost = time.time() - t0
    print('%s, bmp read time: %.2f' % (func_name, t_cost / read_num * 1000))


# '1' is image file name without extension
read_time_test('1', NUM, cv2.imread, 'cv2.imread')
read_time_test('1', NUM, imageio.imread, 'imageio.imread')
read_time_test('1', NUM, skimage.io.imread, 'skimage.io.imread')
read_time_test('1', NUM, matplotlib.pyplot.imread, 'matplotlib.pyplot.imread')
read_time_test('1', NUM, matplotlib.image.imread, 'matplotlib.image.imread')

PIL.Image.open()本身的读取效率极快,但是读入的数据类型并不能直接被使用(类型是PIL.JpegImagePlugin.JpegImageFile,PIL.PngImagePlugin.PngImageFile,PIL.BmpImagePlugin.BmpImageFile等之类),需要使用np.array()转换为ndarray后才能正常使用(转换耗费了99%以上的时间)。如果把图片读为ndarray作为最终目的,那么PIL的效率并没有什么优势。另提醒一声,PIL库安装时候的名字叫pillow:pip install pillow

# -*- coding: utf-8 -*-
import time
from PIL import Image
import numpy as np

NUM = 1000

t0 = time.time()
for i in range(NUM):
    image = Image.open('1.jpg')
    image = np.array(image)
t_cost = time.time() - t0
print('PIL.Image.open, jpg read time: %.2f' % (t_cost / NUM * 1000))

t0 = time.time()
for i in range(NUM):
    image = Image.open('1.png')
    image = np.array(image)
t_cost = time.time() - t0
print('PIL.Image.open, png read time: %.2f' % (t_cost / NUM * 1000))

t0 = time.time()
for i in range(NUM):
    image = Image.open('1.bmp')
    image = np.array(image)
t_cost = time.time() - t0
print('PIL.Image.open, bmp read time: %.2f' % (t_cost / NUM * 1000))

tensorflow类似PIL,也需要两条命令配合才能真正读取图片,tensorflow读取jpeg图片的效率相对较高,读取png和bmp相比较其他读图函数没有什么优势。

# -*- coding: utf-8 -*-
import time
import tensorflow as tf

NUM = 1000

t0 = time.time()
for i in range(NUM):
    image_file = tf.io.read_file('1.jpg')
    image = tf.io.decode_image(image_file)
t_cost = time.time() - t0
print('PIL.Image.open, jpg read time: %.2f' % (t_cost / NUM * 1000))
print(image.shape, type(image))

t0 = time.time()
for i in range(NUM):
    image_file = tf.io.read_file('1.png')
    image = tf.io.decode_image(image_file)
t_cost = time.time() - t0
print('PIL.Image.open, png read time: %.2f' % (t_cost / NUM * 1000))
print(image.shape, type(image))

t0 = time.time()
for i in range(NUM):
    image_file = tf.io.read_file('1.bmp')
    image = tf.io.decode_image(image_file)
t_cost = time.time() - t0
print('PIL.Image.open, bmp read time: %.2f' % (t_cost / NUM * 1000))
print(image.shape, type(image))

你可能感兴趣的:(python)