专栏首页AI黑科技工具箱0.伏笔:图像读取方式以及效率对比
原创

0.伏笔:图像读取方式以及效率对比

入职了之后挺忙,已经好久没有做一些科普性的更新了。近期已做了些学术要求不高的工作,所以刚好有时间写写总结。

接下来的一段时间会向着深度学习工具使用的方向,去做一些纯工程性质的分享,重点会介绍MXNet+Gluon的使用,包括一些内幕黑科技,与大家共同进步。

今天来讲一下Python中几种主流读取图像方法,并对他们的读取方式的效率进行对比。

我搜集了几类大家用的比较多的读取图像方法:opencv、scikit-image、scipy、pillow、matplotlib,这些方法的好处就是我们直接调包就好。

在早期,pillow算是Python默认库中比较流行的图像工具,后来pillow原始开发人员逐渐做了废弃的选择(现在维护的是另一班人),然后各类图像处理库,包括原来在c艹称霸的opencv也选择了支持Python,然后就是numpy+scipy+scikit-learn+scikit-image这一逆天的科学计算大礼包的出现。这些基础数据处理的科学计算库的出现,对整个机器学习界乃至现如今0门槛入门深度学习起了不可磨灭的促进作用。

当然了,毕竟是工具,用的顺手才是重要的。好活不一定用好工具,但是好工具一定出好活。

  1. 我们首先来看一下opencv的读取效率:
# 加载时间函数用于计算效率
import time
# opencv
import cv2
N = 1000
tic = time.time()
for i in range(N):
    img = cv2.imread('../data/train/cat.123.jpg')
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
print(N/(time.time()-tic), 'images decoded per second with opencv')
imshow(img)

734.9363854754574 images decoded per second with opencv

opencv读取成numpy.array的速度为每秒734张。

2. 我们来看一下scipy的读取方式和它的效率:

# scipy
from scipy.misc import imread
N = 1000
tic = time.time()
for i in range(N):
    img = imread('../data/train/cat.123.jpg')
print(N/(time.time()-tic), 'images decoded per second with scipy.misc')

623.7528820826661 images decoded per second with scipy.misc

采用scipy中的misc函数进行读取效率略微比opencv低一点,速度为每秒623张

3. 如果采用scipy的亲儿子skimage进行读取呢?

# skimage
from skimage import io
N = 1000
tic = time.time()
for i in range(N):
    img = io.imread('../data/train/cat.123.jpg')
print(N/(time.time()-tic), 'images decoded per second with skimage')

613.2599892065876 images decoded per second with skimage 可以看出它的读取速度和scipy基本相当,甚至慢一点,可以确定的一点的是skimage是scipy的亲儿子。速度:每秒613张

4. 和大家重点说一下pillow这个老大,我们还是先做实验:

# pillow
from PIL import Image
N = 1000
tic = time.time()
for i in range(N):
    img = Image.open('../data/train/cat.123.jpg')
    img = np.array(img)
print(N/(time.time()-tic), 'images decoded per second with pillow')

606.2237641859305 images decoded per second with pillow

pillow看起来速度比上面还要慢一点,差别也不大,基本是每秒606张。但实际上,pillow在之星open语句的时候,实际上是通过读取二进制编码的方式进行读取图像,原则上应该是要比上面快很多,那么为什么速度会这么慢呢?我们再做个试验。

# pillow
N = 1000
tic = time.time()
for i in range(N):
    img = Image.open('../data/train/cat.123.jpg')
    #img = np.array(img)
print(N/(time.time()-tic), 'images decoded per second with pillow')

10118.899305672832 images decoded per second with pillow 可以明显发现,读取速度直接提升两个数量级,但是此时的img是Image内部的类文件,需要做相应的转换才是可以的,所以在执行np.array()的时候出现速度下降。

5. 既然已经考虑到了关于读取方式和解码问题的效率问题时,那么我们是不是有更好的图像读取方式呢?于是DMLC(创造MXNet的组织)调用了第一项中opencv中读取编码、解析编码的部分代码,并加入了自动多线程并行读取。

# mx.image
import mxnet as mx
N = 1000
tic = time.time()
for i in range(N):
    img = mx.image.imdecode(open('../data/train/cat.123.jpg','rb').read())
mx.nd.waitall()
print(N/(time.time()-tic), 'images decoded per second with mx.image')
imshow(img.asnumpy())

3104.49234140315 images decoded per second with mx.image

直接爆炸!

这个读出来可是实打实的numpy.array()格式,性能直接提升五倍。在之前做了解释,MXNet是对读取的二进制文件做了opencv的解码,同时加入了自动多线程功能,所以速度真的飞起,真材实料的黑科技啊!

说点远的

实际上可以发现,各深度学习框架都有自己独特的数据读取方式,比如TensorFlow也同样加入了queue读取文件,也通过解码的方式提高效率;再比如各框架为了提高效率都开始采用一定的数据结构格式文件:keras的h5、TensorFlow的tfrecord、MXNet的rec,甚至早起caffe的IMDB格式等。

在我用了多种框架后,我果断选择了MXNet。早起被人吐槽MXNet已经一去不复返,同时DMLC为了降低新手入门难度,更是推出了Gluon的前端。

下回如果有时间,我会聊聊我为什么放弃TensorFlow,以及各大框架使用的优劣感受~会接地气的~

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

登录 后参与评论
0 条评论

相关文章

  • 1.试水:可定制的数据预处理与如此简单的数据增强(上)

    说实话,在我仔细研究了MXNet和Gluon是如何进行数据加载与数据增强的,不得不佩服DMLC真的很良心,提供了如此简单的接口和又方便又多样的数据处理工具库。

    SCP-173
  • 1.试水:可定制的数据预处理与如此简单的数据增强(下)

    上一部分我们讲了MXNet中NDArray模块实际上有很多可以继续玩的地方,不限于卷积,包括循环神经网络RNN、线性上采样、池化操作等,都可以直接用NDArra...

    SCP-173
  • ​零基础入门深度学习(九):目标检测之常用数据预处理与增广方法

    本课程是百度官方开设的零基础入门深度学习课程,主要面向没有深度学习技术基础或者基础薄弱的同学,帮助大家在深度学习领域实现从0到1+的跨越。从本课程中,你将学习到...

    用户1386409
  • 登上更高峰!颜水成、程明明团队开源ViP,引入三维信息编码机制,无需卷积与注意力

    本文从位置信息编码出发,引入了高-宽-通道三维信息编码机制。为进一步校正不同分支的作用,提出了加权融合方式。ViP在ImageNet上取得了83.2%的top1...

    AIWalker
  • visdom可视化pytorch训练过程

      在深度学习模型训练的过程中,常常需要实时监听并可视化一些数据,如损失值loss,正确率acc等。在Tensorflow中,最常使用的工具非Tensorboa...

    py3study
  • 图像处理之gamma校正

      在电视和图形监视器中,显像管发生的电子束及其生成的图像亮度并不是随显像管的输入电压线性变化,电子流与输入电压相比是按照指数曲线变化的,输入电压的指数要大于电...

    全栈程序员站长
  • CV学习笔记(二):OpenCV基本操作

    今天这一篇文章主要记录一下OpenCV中一些基本的操作,包括读取图片,视频以及反转图像的几种操作:

    云时之间
  • 动手学深度学习(二) Softmax与分类模型

    softmax运算符(softmax operator)解决了以上两个问题。它通过下式将输出值变换成值为正且和为1的概率分布:

    致Great
  • 详解PyTorch可视化工具visdom(一)

    在深度学习领域,模型训练是一个必须的过程,因此常常需要实时监听并可视化一些数据,如损失值loss,正确率acc等。在Tensorflow中,最常使用的工具非Te...

    全栈程序员站长
  • Gamma校正

    Gamma源于CRT(显示器/电视机)的响应曲线,即其亮度与输入电压的非线性关系。

    zy010101
  • 视觉目标检测和识别之过去,现在及可能

    作者:李习华 知乎专栏:碧空的cv之旅 量子位 已获授权编辑发布 计算机视觉中目标检测、跟踪、识别是最基本的几个task,尤其又以检测最为重要和基础。同时基本上...

    量子位
  • Android OpenGL 渲染图像读取哪家强?

    glReadPixels 是 OpenGL ES 的 API ,OpenGL ES 2.0 和 3.0 均支持。使用非常方便,下面一行代码即可搞定,但是效率很低...

    字节流动
  • Keras中 ImageDataGenerator函数的参数用法

    featurewise_center:布尔值,使输入数据集去中心化(均值为0), 按feature执行。

    砸漏
  • 基于阈值的车道标记

    在这篇文章中,我将介绍如何从视频中查找并标记车道。被标记的车道会显示到视频上,并得到当前路面的曲率以及车辆在该车道内的位置。首先我们需要对图像进行相机失真校正,...

    小白学视觉
  • 5 | PyTorch加载真实数据:图像、表格、文本,one-hot

    在实际的工作中,常见的机器学习处理的数据大概分成三种,一种是图像数据,图像数据通常是RGB三通道的彩色数据,图像上的每个像素由一个数值表示,这个其实比较容易处理...

    机器学习之禅
  • CUDA优化的冷知识17|纹理存储优势(3)

    https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html 来阅读原文。

    GPUS Lady
  • 基于阈值的车道标记

    在这篇文章中,我将介绍如何从视频中查找并标记车道。被标记的车道会显示到视频上,并得到当前路面的曲率以及车辆在该车道内的位置。首先我们需要对图像进行相机失真校正,...

    AI算法与图像处理
  • CV学习笔记(二):OpenCV基本操作

    今天这一篇文章主要记录一下OpenCV中一些基本的操作,包括读取图片,视频以及反转图像的几种操作:

    云时之间

扫码关注腾讯云开发者

领取腾讯云代金券