如何实时模拟视频并能够提取其帧?
How to simulate a video in real time and be able to extract its frames?
我正在制作一个识别视频中人物的程序。使用 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 */
}
执行此操作的一种方法可能是启动一个单独的线程,以正常速度读取视频文件并将每一帧填充到一个全局变量中。然后主线程在准备就绪时抓取该帧。
所以,如果我们使用只显示时间和帧计数器的视频,我们可以在假摄像头更新帧时到处抓取帧:
#!/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,多线程,多线程,多线程,多线程,视频,假相机。
我正在制作一个识别视频中人物的程序。使用 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 */
}
执行此操作的一种方法可能是启动一个单独的线程,以正常速度读取视频文件并将每一帧填充到一个全局变量中。然后主线程在准备就绪时抓取该帧。
所以,如果我们使用只显示时间和帧计数器的视频,我们可以在假摄像头更新帧时到处抓取帧:
#!/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,多线程,多线程,多线程,多线程,视频,假相机。