2 回答

TA贡献1911条经验 获得超7个赞
我将简要介绍该线程的主要要点:
最快的常用图像读取功能
imread
来自cv2
包。读取图像然后将它们添加到一个普通的 Python 列表中(正如您已经在做的那样)是读取大量图像的最快方法。
然而,鉴于您最终将图像列表转换为图像数组,构建图像数组的每种可能方法几乎与任何其他方法一样快
尽管有趣的是,如果您采用直接将图像分配给预分配数组的方法,实际上分配给哪个索引(即哪个维度)对于获得最佳性能很重要。
所以基本上,在纯单线程 Python 中工作时,您将无法获得更快的速度。您可能会从切换到cv2.imread
(代替PIL.Image.open
)获得提升。

TA贡献1780条经验 获得超1个赞
PNG 是一种非常慢的格式,因此如果您几乎可以使用其他任何格式,您将看到明显的加速。
例如,这是您的程序的 opencv 版本,它从命令行参数获取文件名:
#!/usr/bin/python3
import sys
import cv2
import numpy as np
video_array = []
for filename in sys.argv[1:]:
im = cv2.imread(filename)
video_array.append(np.asarray(im))
video_array = np.array(video_array)
print(video_array.shape)
我可以像这样运行它:
$ mkdir sample
$ for i in {1..100}; do cp ~/pics/k2.png sample/$i.png; done
$ time ./readframes.py sample/*.png
(100, 2048, 1450, 3)
real 0m6.063s
user 0m5.758s
sys 0m0.839s
所以 6s 读取 100 张 PNG 图像。如果我尝试使用 TIFF:
$ for i in {1..100}; do cp ~/pics/k2.tif sample/$i.tif; done
$ time ./readframes.py sample/*.tif
(100, 2048, 1450, 3)
real 0m1.532s
user 0m1.060s
sys 0m0.843s
1.5 秒,所以快了四倍。
您可能会通过pyvips获得小幅加速:
#!/usr/bin/python3
import sys
import pyvips
import numpy as np
# map vips formats to np dtypes
format_to_dtype = {
'uchar': np.uint8,
'char': np.int8,
'ushort': np.uint16,
'short': np.int16,
'uint': np.uint32,
'int': np.int32,
'float': np.float32,
'double': np.float64,
'complex': np.complex64,
'dpcomplex': np.complex128,
}
# vips image to numpy array
def vips2numpy(vi):
return np.ndarray(buffer=vi.write_to_memory(),
dtype=format_to_dtype[vi.format],
shape=[vi.height, vi.width, vi.bands])
video_array = []
for filename in sys.argv[1:]:
vi = pyvips.Image.new_from_file(filename, access='sequential')
video_array.append(vips2numpy(vi))
video_array = np.array(video_array)
print(video_array.shape)
我懂了:
$ time ./readframes.py sample/*.tif
(100, 2048, 1450, 3)
real 0m1.360s
user 0m1.629s
sys 0m2.153s
还有10%左右。
最后,正如其他海报所说,您可以并行加载帧。这不会对 TIFF 有多大帮助,但它肯定会提升 PNG。
添加回答
举报