【问题标题】:Python function to read video and convert to framesPython函数读取视频并转换为帧
【发布时间】:2018-12-15 08:54:55
【问题描述】:

我想将我的输入视频转换为一组帧。我已经阅读了关于 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

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

【问题讨论】:

  • 你的意思是视频网址吗?
  • 我想制作一个可以将视频转换为一组帧的Web应用程序,所以我想让代码通用。我想将上传到网站的视频转换为一组帧并返回它们,而不将任何内容保存到文件中。
  • 我不确定你的意思。如果视频已上传,则将其保存在某处,您可以提供 OpenCV 的路径,但如果视频可以像 Youtube 一样流式传输,则可以使用 youtube-dl
  • 我对 Web 开发非常陌生。所以我想知道,视频会保存在哪里?
  • 或者我如何找到它的位置?

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


【解决方案1】:

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

【讨论】:

  • 感谢 Hidrana 抽出时间帮助其他人解决堆栈溢出问题。为了提高您的回答质量,请考虑展示一个示例解决方案,并解释为什么需要修复。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    Streaming video in memory with OpenCV VideoWriter and Python BytesIO

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

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

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

    并且只想在内存中处理它(并继续使用 OpenCV),然后查看我上面列出的另一篇文章。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-20
      • 2021-07-19
      • 2020-12-19
      • 1970-01-01
      • 1970-01-01
      • 2020-06-02
      • 2022-11-24
      • 2021-08-15
      相关资源
      最近更新 更多