如何加速枕头(python)中的图像加载? [英] How to speed up image loading in pillow (python)?

查看:126
本文介绍了如何加速枕头(python)中的图像加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 Pillow 进行一些简单的手写图像识别,而且它是实时的,所以我需要每秒调用 5-10 次我的函数.我正在加载图像并且只访问 20^2 像素中的 1 个,所以我真的不需要所有图像.我需要减少图片加载时间.

I want to use pillow for some simple handwritten image recognition, and it will be real-time so I will need to call my function 5-10 times a second. I'm loading the image and am only accessing 1 in 20^2 pixels so I really don't need all the image. I need to reduce the image loading time.

我从未使用过 python 图像库,希望得到所有建议.

I've never used a python image library and would appreciate all suggestions.

from PIL import Image
import time

start = time.time()

im = Image.open('ir/IMG-1949.JPG')
width, height = im.size
px = im.load()

print("loading: ", time.time() - start)

所需的加载时间:<50ms,实际加载时间:~150ms

desired loading time: <50ms, actual loading time: ~150ms

推荐答案

更新答案

自从我写下这个答案后,John Cupitt(pyvips 的作者)提出了一些改进和更正以及更公平的代码和时间安排,并善意地在这里分享.请查看他的改进版本,与我下面的代码一起甚至优先查看.

Since I wrote this answer, John Cupitt (author of pyvips) has come up with some improvements and corrections and fairer code and timings and has kindly shared them here. Please look at his improved version, alongside or even in preference to my code below.

原答案

JPEG 库具有加载时收缩" 功能,可以避免大量 I/O 和解压缩.您可以使用 Image.draft() 函数在 PIL/Pillow 中利用这一点,而不是像这样读取完整的 4032x3024 像素:

The JPEG library has a "shrink-on-load" feature which allows a lot of I/O and decompression to be avoided. You can take advantage of this with PIL/Pillow using the Image.draft() function, so instead of reading the full 4032x3024 pixels like this:

from PIL import Image

im = Image.open('image.jpg')
px = im.load() 

在我的 Mac 上需要 297 毫秒,您可以执行以下操作并读取 1008x756 像素,即宽度的 1/4 和高度的 1/4:

which takes 297ms on my Mac, you can do the following and read 1008x756 pixels, i.e. 1/4 the width and 1/4 the height:

im = Image.open('image.jpg') 
im.draft('RGB',(1008,756)) 
px = im.load()

这只需 75 毫秒,即快 4 倍.

and that takes only 75ms, i.e. it is 4x faster.

只是为了踢球,我尝试比较各种技术如下:

Just for kicks, I tried comparing various techniques as follows:

#!/usr/bin/env python3 

import numpy as np 
import pyvips 
import cv2 
from PIL import Image 

def usingPIL(f): 
    im = Image.open(f) 
    return np.asarray(im) 

def usingOpenCV(f): 
    arr = cv2.imread(f,cv2.IMREAD_UNCHANGED) 
    return arr 

def usingVIPS(f): 
    image = pyvips.Image.new_from_file(f, access="sequential") 
    mem_img = image.write_to_memory() 
    imgnp=np.frombuffer(mem_img, dtype=np.uint8).reshape(image.height, image.width, 3)  
    return imgnp 

def usingPILandShrink(f): 
    im = Image.open(f)  
    im.draft('RGB',(1008,756))  
    return np.asarray(im) 

def usingVIPSandShrink(f): 
    image = pyvips.Image.new_from_file(f, access="sequential", shrink=4) 
    mem_img = image.write_to_memory() 
    imgnp=np.frombuffer(mem_img, dtype=np.uint8).reshape(image.height, image.width, 3)  
    return imgnp 

并将其加载到 ipython 中并进行如下测试:

And loaded that into ipython and tested like this:

%timeit usingPIL('image.jpg')
315 ms ± 8.76 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit usingOpenCV('image.jpg')
102 ms ± 1.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit usingVIPS('image.jpg')
69.1 ms ± 31.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit usingPILandShrink('image.jpg')
77.2 ms ± 994 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit usingVIPSandShrink('image.jpg')                                                    
42.9 ms ± 332 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

看来 pyVIPS 显然是这里的赢家!

It seems like pyVIPS is the clear winner here!

关键字:Python、PIL、枕头、图像、图像处理、JPEG、加载时收缩、加载时收缩、草稿模式、读取性能、加速.

Keywords: Python, PIL, Pillow, image, image processing, JPEG, shrink-on-load, shrink on load, draft mode, read performance, speedup.

这篇关于如何加速枕头(python)中的图像加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆