use*_*r42 3 python opencv video-processing python-imageio
我有一个视频,我想从视频中仅提取特定的帧。
目前我所做的是:
index = [1,2,3,4,5,6,7,8]
img_list = []
for i, frame in enumerate(iio.imiter("imageio:cockatoo.mp4")):
if i in index:
img_list.append(frame)
img_array = np.asarray(img_list)
Run Code Online (Sandbox Code Playgroud)
有没有办法只“寻找”我想要的帧,就像在 opencv 中完成的那样,如此处所示?
您可以使用indexkwarg of获取特定帧imread:
import imageio.v3 as iio
import numpy as np
index = [1,2,3,4,5,6,7,8]
img_list = []
for idx in index:
img_list.append(iio.imread("imageio:cockatoo.mp4", index=idx))
img_array = np.stack(img_list)
Run Code Online (Sandbox Code Playgroud)
如果您想要更高的性能,您可以使用pyav作为后端而不是默认的imageio-ffmpeg。
import imageio.v3 as iio
import numpy as np
index = [1,2,3,4,5,6,7,8]
img_list = []
for idx in index:
img_list.append(iio.imread("imageio:cockatoo.mp4", index=idx, plugin="pyav"))
img_array = np.stack(img_list)
Run Code Online (Sandbox Code Playgroud)
计时(每次重复 10 次):
>>> timeit.timeit('[iio.imread("imageio:cockatoo.mp4", index=idx) for idx in index]', setup="from __main__ import index, iio", number=10)
9.865169799999876
>>> timeit.timeit('[iio.imread("imageio:cockatoo.mp4", index=idx, plugin="pyav") for idx in index]', setup="from __main__ import index, iio", number=10)
2.250104900000224
Run Code Online (Sandbox Code Playgroud)
ofc 的缺点是每次都需要重新打开文件,您可以避免使用imopen:
import imageio.v3 as iio
import numpy as np
index = [1,2,3,4,5,6,7,8]
with iio.imopen("imageio:cockatoo.mp4", "r") as img_file:
img_list = [img_file.read(index=idx) for idx in index]
img_array = np.stack(img_list)
Run Code Online (Sandbox Code Playgroud)
不幸的是,imopen由于我在编写插件时错过了一个错误,该路线目前不适用于 pyav。但是,既然我现在意识到了这一点,我应该能够在未来几天内编写修复程序:)
编辑:该错误现已修复。您现在可以使用
import imageio.v3 as iio
import numpy as np
index = [1,2,3,4,5,6,7,8]
with iio.imopen("imageio:cockatoo.mp4", "r", plugin="pyav") as img_file:
img_list = [img_file.read(index=idx) for idx in index]
img_array = np.stack(img_list)
Run Code Online (Sandbox Code Playgroud)