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

时间:2018-07-06 17:59:04

标签: python python-3.x opencv video video-processing

我想将输入的视频转换为一组帧。我已阅读以下文章 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

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

OO方法:编写一种“ VideoWrapper”类和派生类:

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 = []

在这种情况下,您可以在代码中传递单个类类型。 更好的类将实现__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