我有一个文件夹,说video1
,其中包含frame_00.png, frame_01.png, ...
顺序的一堆图像
我想要的是格式为(number of frames, 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)
答案 0 :(得分:1)
关于这个主题,有一个older SO thread涉及了很多细节(也许有些过多)。与其投票否决以重复的方式结束这个问题,不如让我快速总结一下该线程的主要要点:
Async
软件包中的imread
。因此,基本上,使用纯单线程Python时,您将无法获得更快的速度。从切换到cv2
(代替cv2.imread
)可能会有所帮助。
答案 1 :(得分:1)
PNG是一种非常慢的格式,因此,如果您几乎可以使用其他任何格式,都会看到很大的加速。
例如,这是您的程序的opencv版本,该版本从命令行args获取文件名:
#!/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秒,因此快了四倍。
使用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。
答案 2 :(得分:-1)
否,没有直接方法可以从文件夹中拍摄图像。您需要像遍历一样遍历每个文件并将其转换为numpy数组。