品易云推流 关闭
文章详情页
文章 > Python基础教程 > python使用OpenCV捕获事件

python使用OpenCV捕获事件

Python OpenCV

头像

小妮浅浅

2021-05-27 17:23:22669浏览 · 0收藏 · 0评论

1、步骤说明

定义关键事件;

将包含事件的视频片段写入到视频文件;

利用线程以确保在输入流和输出视频剪辑文件中执行I / O时,不会放慢主程序的速度;

利用内置的Python数据结构,如DEQUE队列以按顺序存放关键帧。

2、实例

# 导入必要的包
from collections import deque # 导入队列,FIFO(first in first out)先进先出原则
from threading import Thread
from queue import Queue
import time
import cv2
 
 
class KeyClipWriter:
    # bufSize 要在内存缓冲区中缓存的最大帧数
    # timeout 超时时间
    def __init__(self, bufSize=64, timeout=1.0):
        # 存储在内存中要保留的最大缓冲区大小 以及睡眠超时期间
        self.bufSize = bufSize
        self.timeout = timeout
 
        # 初始化帧的缓冲区(64帧)、Q:待写入的视频帧、视频写入类、 多线程(以避免I/O延迟)
        # recordering boolean类型指示录制是否已启动
        self.frames = deque(maxlen=bufSize)
        self.Q = None
        self.writer = None
        self.thread = None
        self.recording = False
 
    def update(self, frame):
        # 更新帧缓冲区
        self.frames.appendleft(frame)
        # 如果正在记录,将帧加入队列
        if self.recording:
            self.Q.put(frame)
 
    def start(self, outputPath, fourcc, fps):
        # 展示正在记录关键事件帧
        # 表明正在录制,启动视频写入类,初始化需要写入视频文件的帧队列
        self.recording = True
        self.writer = cv2.VideoWriter(outputPath, fourcc, fps,
                                      (600,600), True)
        self.Q = Queue()
 
        # 循环遍历所有帧,并加入队列
        for i in range(len(self.frames), 0, -1):
            self.Q.put(self.frames[i - 1])
 
        # 开启一个单独的线程写入帧到视频文件
        self.thread = Thread(target=self.write, args=())
        self.thread.daemon = True
        self.thread.start()
 
    def write(self):
        # 保持循环
        while True:
            # 如果停止了录制,退出线程
            if not self.recording:
                return
            # 判断队列是否已经没有关键事件帧了
            if not self.Q.empty():
                # 获取队列中的下一帧并写入视频文件
                frame = self.Q.get()
                self.writer.write(frame)
            # 如果队列已经空了,sleep超时时间以不浪费cpu周期
            # 使用队列时空闲一会儿尤其重要,队列数据结构是线程安全的,暗示必须在更新内部缓冲区之前获取锁/信号量。
            # 如果不sleep,当缓冲区为空时,然后写入和更新方法将不断为锁而战斗。相反,最好让视频写入类等待一会儿,直到需要写入文件的队列中存在积压的帧。
            else:
                time.sleep(self.timeout)
 
    def flush(self):
        # 通过刷新所有剩余帧来清空队列
        while not self.Q.empty():
            frame = self.Q.get()
            self.writer.write(frame)
 
    def finish(self):
        # 表明结束录制、加入线程
        # 刷新队列中的所有帧到视频文件
        # 释放视频写入指针
        self.recording = False
        self.thread.join()
        self.flush()
        self.writer.release()

以上就是python使用OpenCV捕获事件,希望对大家有所帮助。更多Python学习指路:python基础教程

关注

关注公众号,随时随地在线学习

本教程部分素材来源于网络,版权问题联系站长!

底部广告图