Python 读取视频并转换为帧的函数

Python function to read video and convert to frames

我想将我的输入视频转换为一组帧。我已阅读 post Python - Extracting and Saving Video Frames

但我想要一个功能,我可以插入视频作为参数,而不是视频文件的位置。

在下面的 VideoCapture 函数中,它获取视频文件的位置。

import cv2
def vidtoframes(videoFile):
 vidcap = cv2.VideoCapture(videoFile)
 success,image = vidcap.read()
 count = 0

 while success:
  cv2.imwrite("frame%d.jpg" % count, image) # save frame as JPEG file      
  success,image = vidcap.read()
  print('Read a new frame: ', success)
  count += 1

但是有没有一种函数或方法可以将视频传递给该方法并将其转换为帧数组而不将任何内容保存到磁盘上。

拍摄的视频必须保存到一个目录中,然后我们才能在其上执行功能。这也是应用程序的工作方式。

OO 方法:编写一种 "VideoWrapper" class 并导出 classes:

from abc import abstractmethod

class VideoWrapper:
    def __init__(self, path: str, chunk_size: int = 1):
        self.path = path
        self.chunk_size = chunk_size

    @abstractmethod
    def __iter__(self): ...

class VideoFileWrapper(VideoWrapper):
    def __iter__(self):
        chunk = []
        cap = cv2.VideoCapture(self.path)
        while cap.isOpened():
            ret, frame = cap.read()
            chunk.append(frame)
            if len(chunk) == self.chunk_size:
                yield chunk
                chunk = []


class VideoFolderWrapper(VideoWrapper):
    def __iter__(self):
        chunk = []
        for frame_path in glob(os.path.join(self.path, '*')):
            frame = cv2.imread(frame_path)
            chunk.append(frame)
            if len(chunk) == self.chunk_size:
               yield chunk
               chunk = []

在这种情况下,您可以在代码中传递一个 class 类型。 更好的 class 会实现 __enter____exit__ 方法,以便使用 with 语句、异常处理等。这可能太多了,一个更简单的 "Pythonic" 版本将是:

def video_wrapper(path):
    if os.path.isdir(path):
        frames = list(glob(os.path.join(path, '*.png')))
        frames.sort(key=file_name_order)
        for frame_path in frames:
            frame = cv2.cvtColor(cv2.imread(frame_path),cv2.COLOR_BGR2RGB)
            yield frame
    elif os.path.exists(path):
        cap = cv2.VideoCapture(path)
        while cap.isOpened():
        ret, frame = cap.read()
        yield frame

是的!有!但这需要一点设置。一切都在这里详细说明:

基础是您需要 linux 中的 tmpfs 分区,并利用 Python 的 tempfile 功能(它只是将 mkstemp 包装在linux 再一次)。

如果您的内存中已有视频文件,例如:

video_bytes = s3.download('file.avi')

而且只想在内存中处理(并继续使用OpenCV),然后查看我上面列出的其他post。