【问题标题】:How to simulate a video in real time and be able to extract its frames?如何实时模拟视频并能够提取其帧?
【发布时间】:2021-04-13 17:35:09
【问题描述】:

我正在制作一个识别视频中人物的程序。使用 OpenCV,您可以提取视频的帧,如下所示(我正在使用 c++):

cv::VideoCapture vidCap(path/video.mp4);
cv::Mat frame;
while (!endVideo){
     successRead = vidCap.read(frame);
     if (!successRead){
         endVideo = true;
     }
/* work */
}

这对于视频来说很好,但将来我将使用相机。因此,我想用这个视频“path/video.mp4”来模拟它,就像它是一个相机一样,也就是说,我希望它实时运行,并且我的程序要捕捉实时运行的视频帧(即使它丢失了一些帧)。

伪代码是(我不关心库):

video.load(path/video.mp4) //load video
video.run()                //run video
while (!endVideo){
  video.getFrame(frame);  //get frame, even if it's the 10 frame
/* work */
}

【问题讨论】:

  • cv::VideoCapture 将尽快为您提供每一帧。如果您需要放慢速度,则需要使用一些延迟/睡眠功能(waitKey 可能)。如果您需要跳过帧,...就这样做。确定你现在想在哪一帧,然后根据需要阅读和忽略。由于没有人接受 Stack Overflow 上的答案并对答案进行投票,因此我不会费心将其变成“正确答案”。
  • 是的,这确实是最快的解决方案“如果您需要跳过帧,......就这样做”。但他想要一个更真实的解决方案。非常感谢您的帮助!

标签: python c++ opencv computer-vision video-capture


【解决方案1】:

执行此操作的一种方法可能是启动一个单独的线程,以正常速度读取视频文件并将每一帧填充到一个全局变量中。然后,主线程会在准备好时抓取该帧。

因此,如果我们使用仅显示时间和帧计数器的视频,我们可以在假相机更新帧时到处抓取帧:

#!/usr/bin/env python3

import cv2
import sys
import time
import logging
import numpy as np
import threading, queue

logging.basicConfig(level=logging.DEBUG, format='%(levelname)s %(message)s')

# This is shared between main and the FakeCamera
currentFrame = None

def FakeCamera(Q, filename):
    """Reads the video file at its natural rate, storing the frame in a global called 'currentFrame'"""
    logging.debug(f'[FakeCamera] Generating video stream from {filename}')

    # Open video
    video = cv2.VideoCapture(filename)
    if (video.isOpened()== False):
       logging.critical(f'[FakeCamera] Unable to open video {filename}')
       Q.put('ERROR')
       return

    # Get height, width and framerate so we know how often to read a frame
    h   = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
    w   = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
    fps = video.get(cv2.CAP_PROP_FPS)
    logging.debug(f'[FakeCamera] h={h}, w={w}, fps={fps}')

    # Initialise currentFrame
    global currentFrame
    currentFrame = np.zeros((h,w,3), dtype=np.uint8)

    # Signal main that we are ready
    Q.put('OK')

    while True:
        ret,frame = video.read()
        if ret == False:
            break
        # Store video frame where main can access it
        currentFrame[:] = frame[:]
        # Try and read at appropriate rate
        time.sleep(1.0/fps)

    logging.debug('[FakeCamera] Ending')
    Q.put('DONE')

if __name__ == '__main__':

    #  Create a queue for synchronising and communicating with our fake camera
    Q = queue.Queue()

    # Create a fake camera thread that reads the video in "real-time"
    fc = threading.Thread(target=FakeCamera, args=(Q,'video.mov'))
    fc.start()

    # Wait for fake camera to intialise
    logging.debug(f'[main] Waiting for camera to power up and initialise')
    msg = Q.get()
    if msg != 'OK':
        sys.exit()

    # Main processing loop should go here - we'll just grab a couple frames at different times
    cv2.imshow('Video',currentFrame)
    res = cv2.waitKey(2000)

    cv2.imshow('Video',currentFrame)
    res = cv2.waitKey(5000)

    cv2.imshow('Video',currentFrame)
    res = cv2.waitKey(2000)

    # Wait for buddy to finish
    fc.join()

样本输出

DEBUG [FakeCamera] Generating video stream from video.mov
DEBUG [main] Waiting for camera to power up and initialise
DEBUG [FakeCamera] h=240, w=320, fps=25.0
DEBUG [FakeCamera] Ending

关键词:Python、图像处理、OpenCV、多线程、多线程、多线程、多线程、视频、假相机。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-20
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 2016-12-21
    • 1970-01-01
    相关资源
    最近更新 更多