Python 从文件夹中的图像序列获取numpy数组
我有一个文件夹,比如说Python 从文件夹中的图像序列获取numpy数组,python,numpy,image-processing,keras,python-imaging-library,Python,Numpy,Image Processing,Keras,Python Imaging Library,我有一个文件夹,比如说video1,里面有一堆图像,顺序是frame\u 00.png,frame\u 01.png,… 我想要的是一个4D numpy数组,格式为(帧数,w,h,3) 这就是我所做的,但我认为这是相当缓慢的,有没有更快或更有效的方法来实现同样的事情 folder = "video1/" import os images = sorted(os.listdir(folder)) #["frame_00", "frame_01", "frame_02", ...] from P
video1
,里面有一堆图像,顺序是frame\u 00.png,frame\u 01.png,…
我想要的是一个4D numpy数组,格式为(帧数,w,h,3)
这就是我所做的,但我认为这是相当缓慢的,有没有更快或更有效的方法来实现同样的事情
folder = "video1/"
import os
images = sorted(os.listdir(folder)) #["frame_00", "frame_01", "frame_02", ...]
from PIL import Image
import numpy as np
video_array = []
for image in images:
im = Image.open(folder + image)
video_array.append(np.asarray(im)) #.transpose(1, 0, 2))
video_array = np.array(video_array)
print(video_array.shape)
#(75, 50, 100, 3)
关于这个话题,有一个非常详细(甚至有点太多)的例子。与其投票以dup结束这个问题,我将简要介绍一下该主题的主要要点:
- 最快的常用图像读取功能是
软件包中的cv2
imread
- 在中读取图像,然后将其添加到普通Python列表中(正如您已经在做的那样),是读取大量图像的最快方法
- 但是,考虑到最终要将图像列表转换为图像数组,构建图像数组的所有可能方法几乎都与其他方法一样快
- 尽管非常有趣的是,如果您采取将图像直接分配给预分配数组的方法,那么实际上分配给哪个索引(即哪个维度)对于获得最佳性能非常重要
cv2.imread
(代替PIL.Image.open
)可能会让您受益匪浅。在这个主题上有一个非常详细的说明(甚至可能有点太多)。与其投票以dup结束这个问题,我将简要介绍一下该主题的主要要点:
- 最快的常用图像读取功能是
软件包中的cv2
imread
- 在中读取图像,然后将其添加到普通Python列表中(正如您已经在做的那样),是读取大量图像的最快方法
- 但是,考虑到最终要将图像列表转换为图像数组,构建图像数组的所有可能方法几乎都与其他方法一样快
- 尽管非常有趣的是,如果您采取将图像直接分配给预分配数组的方法,那么实际上分配给哪个索引(即哪个维度)对于获得最佳性能非常重要
因此,基本上,在纯单线程Python中工作时,您将无法获得更快的速度。切换到
cv2.imread
(代替PIL.Image.open
)可能会给你带来好处。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
所以6秒可以读取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秒,因此速度提高了四倍
您可能会通过以下方式获得小的加速:
我明白了:
$ time ./readframes.py sample/*.tif
(100, 2048, 1450, 3)
real 0m1.360s
user 0m1.629s
sys 0m2.153s
还有10%左右
最后,正如其他海报所说,您可以并行加载框架。这对TIFF没有多大帮助,但肯定会提高PNG的速度。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
所以6秒可以读取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秒,因此速度提高了四倍
您可能会通过以下方式获得小的加速:
我明白了:
$ time ./readframes.py sample/*.tif
(100, 2048, 1450, 3)
real 0m1.360s
user 0m1.629s
sys 0m2.153s
还有10%左右
最后,正如其他海报所说,您可以并行加载框架。这对TIFF没有多大帮助,但肯定会提升PNG。您可以尝试
scipy.misc.imread
而不是使用PIL
。否则,我看不到任何明显的加速代码的方法。你也可以尝试并行读取帧。事实上,正如@trailing_whitespace所建议的那样,imread
比PIL快约15%。我使用scipy.misc.imread代替PIL,当我加载图像时,它的形状如下(50、100、3),并且方向正确。转置图像会给我(100,50,3),这是输入ML模型的正确形状,但图像显示时的方向不再正确。关于如何解决这个问题有什么想法吗?@trailing_空格scipy.misc.imread
和cv2.imread
之间有什么区别吗(比如,它们是否共享一个实现)?这表明cv2.imread
是可用的最快的图像读取功能。您可以尝试scipy.misc.imread
而不是使用PIL
。否则,我看不到任何明显的加速代码的方法。你也可以尝试并行读取帧。事实上,正如@trailing_whitespace所建议的那样,imread
比PIL快约15%。我使用scipy.misc.imread代替PIL,当我加载图像时,它的形状如下(50、100、3),并且方向正确。转置图像会给我(100,50,3),这是输入ML模型的正确形状,但图像显示时的方向不再正确。关于如何解决这个问题有什么想法吗?@trailing_空格scipy.misc.imread
和cv2.imread
之间有什么区别吗(比如,它们是否共享一个实现)?这表明cv2.imread
是可用的最快的图像读取功能。