Python 将视频加载到帧时出现内存问题

Python 将视频加载到帧时出现内存问题,python,opencv,memory,Python,Opencv,Memory,我有160个FLV视频文件夹,每个有120帧大小为152,360个RGB颜色3个通道,我想加载到numpy阵列帧。我使用以下代码执行此操作: import numpy as np import cv2 import os directory = "data/" # frames = [] frames = np.empty(shape=(160 * 120, 152, 360,3), dtype=np.float32) for file in os.listdir(directory):

我有160个FLV视频文件夹,每个有120帧大小为152,360个RGB颜色3个通道,我想加载到numpy阵列帧。我使用以下代码执行此操作:

import numpy as np
import cv2
import os

directory = "data/"
# frames = []
frames = np.empty(shape=(160 * 120, 152, 360,3), dtype=np.float32)

for file in os.listdir(directory):
    if file.endswith(".flv"):

        # Create a VideoCapture object and read from input file
        cap = cv2.VideoCapture(os.path.join(directory, file))

        # Read until video is completed
        while (cap.isOpened()):
            # Capture frame-by-frame
            ret, frame = cap.read()
            if ret == True:
                # frames.append(frame.astype('float32') / 255.)
                frames[nr_frame, :, :, :] = frame.astype('float32') / 255.
                nr_frame = nr_frame + 1
                nb_frames_in_file = nb_frames_in_file + 1
            else:
                break

        # When everything done, release the video capture object
        cap.release()

# frames = np.array(frames)
最初,我尝试使用一个列表框架来查看注释行,而不是预先分配的numpy数组,但这似乎占用了太多内存——不知道为什么


然而,这似乎没有多大帮助:尽管我的视频只有几KB大,但代码仍然非常占用大量GB的内存。我认为这是因为尽管我使用了cap.release,但是cv2.VideoCapture-objects的cap对象的资源可能不会被释放,对吗?我能做些什么来提高代码的内存效率?

您似乎严重低估了所需的内存量。压缩的视频文件可能很小,但您正在存储未压缩的原始数据

让我们回顾一下:

1000个视频 每个视频包含120帧 每帧包含300行和400列像素=120000像素 每个像素包含3个RGB值 每个值需要4个字节 因此,总内存=1000 x 120 x 300 x 400 x 3 x 4=1.728×10^11字节,约为161 GiB


如果您想减少内存需求,则需要重新设计算法,使其不必一次将所有内容都存储在内存中,即批处理。

您似乎严重低估了所需的内存量。压缩的视频文件可能很小,但您正在存储未压缩的原始数据

让我们回顾一下:

1000个视频 每个视频包含120帧 每帧包含300行和400列像素=120000像素 每个像素包含3个RGB值 每个值需要4个字节 因此,总内存=1000 x 120 x 300 x 400 x 3 x 4=1.728×10^11字节,约为161 GiB


如果您想减少内存需求,则需要重新设计算法,使其不必一次将所有内容都存储在内存中,即批处理。

我不确定为什么要使用float32,但帧数据类型应为uint8

frames = np.empty(shape=(1000 * 120,300, 400,3), dtype=np.uint8)

我不知道为什么要使用float32,但帧数据类型应该是uint8

frames = np.empty(shape=(1000 * 120,300, 400,3), dtype=np.uint8)
我建议使用。这是我最近一直在使用的一个非常好的PIL扩展。您可以将视频中的帧加载到对象中,该对象根据需要调用这些帧

例如,如果你有一个视频

import pims
V = pims.Video('filename.avi')
然后,您可以使用类似numpy的索引/切片来访问视频帧

im = V[100]
只有当您将它们转换为numpy数组时,它们才会保存在内存中

import numpy as np 
im = np.array(im)
您可以使用管道对整个视频进行预处理,而无需将其调用到内存中

@pims.pipeline
def grayscale(vid):
    return np.array(vid)[...,0].astype('float')/255 # float grayscale 

gray = grayscale(vid)
我建议使用。这是我最近一直在使用的一个非常好的PIL扩展。您可以将视频中的帧加载到对象中,该对象根据需要调用这些帧

例如,如果你有一个视频

import pims
V = pims.Video('filename.avi')
然后,您可以使用类似numpy的索引/切片来访问视频帧

im = V[100]
只有当您将它们转换为numpy数组时,它们才会保存在内存中

import numpy as np 
im = np.array(im)
您可以使用管道对整个视频进行预处理,而无需将其调用到内存中

@pims.pipeline
def grayscale(vid):
    return np.array(vid)[...,0].astype('float')/255 # float grayscale 

gray = grayscale(vid)

你想用1000个FLV同时存储在内存中做什么?@MarkSetchell:训练一个深度神经网络。我注意到我实际上只有160个视频,但问题仍然存在,以后还会更多-这只是一个测试数据集。你想用内存中的1000个FLV一次做什么?@MarkSetchell:训练一个深度神经网络。我注意到我实际上只有160个视频,但问题仍然存在,以后会更多-这只是一个测试数据集。我计划用框架和示例来训练一个深度神经网络,推荐使用float32。好,我计划用框架和示例来训练一个深度神经网络,推荐使用float32。我在文件数量上犯了一个错误,但问题仍然存在,我认为你的观点仍然有效。我计划训练一个深度神经网络,所以我考虑一次只加载一个视频并进行批量训练。我在文件数量上犯了一个错误,但问题仍然存在,我认为你的观点仍然有效。我计划训练一个深度神经网络,所以我考虑一次只加载一个视频并进行批量训练。你会遇到什么错误?PIMS.PIMS.video'filename.avi'不起作用。找不到pims.video模块。它应该是视频模块,可能不是视频。我手头没有pims可供测试,但是您可以通过键入pims。[TAB]或查阅文档来评估它是否应该是资本:您遇到了什么错误?PIMS.PIMS.video'filename.avi'不起作用。找不到pims.video模块。它应该是视频模块,可能不是视频。我手头没有pims可供测试,但是您可以通过键入pims。[TAB]或查阅文档来评估它是否应为资本: