Cameo项目介绍:

1、实时捕获并显示摄像头帧。

2、具备截图、保存视频和退出三个功能键。

要求存在文件:manager.py 和 cameo.py

一、manager.py

两个类:CaptureManager、WindowManager

  CaptureManager负责摄像头帧的捕获,编解码得到实际帧,当前帧保存为图片、一段时间内的帧保存为视频这四个核心功能。

  CaptureManager负责窗口的创建、窗口展示当前画面、三个功能键的交互、关闭窗口释放资源这四个个功能

二、cameo.py

程序入口,关联调用CaptureManager和CaptureManager,并定义三个功能键

详细方法实现参照下述代码和注释

manager.py

  1 from __future__ import annotations
2 import cv2
3 import numpy
4 import time
5
6 '''
7 1、允许同一文件下不同类之间的类型提示,py3.7以上特性
8 2、cv2——获取摄像头和展示
9 3、numpy——对展示画面进行左右翻转(fliplr)
10 4、time——精确获取时间间隔,然后计算帧率估值
11 '''
12
13
14 class CaptureManager:
15 def __init__(self, capture: cv2.VideoCapture,
16 previewWindowManager: WindowManager = None,
17 shouldMirrorPreview: bool = False):
18 self.previewWindowManager = previewWindowManager
19 self.shouldMirrorPreview = shouldMirrorPreview
20
21 self._capture = capture
22 self._channel = 0
23 self._enteredFrame = False
24 self._frame = None
25
26 self._imageFilename = None
27 self._videoFilename = None
28 self._videoEncoding = None
29 self._videoWriter = None
30
31 self._startTime = None
32 self._framesElapsed = 0
33 self._fpsEstimate = None
34
35 @property
36 def channel(self):
37 return self._channel
38
39 @channel.setter
40 def channel(self, value):
41 if self._channel != value:
42 self._channel = value
43 self._frame = None # 对通道赋值时需要将当前帧置空,否则可能出现通道为未更改现象
44
45 # 如果进入帧,且当前帧为None则对已捕获的帧进行解码和获取实际图像帧
46 @property
47 def frame(self):
48 if self._enteredFrame and self._frame is None:
49 _, self._frame = self._capture.retrieve(self._frame, self.channel)
50 return self._frame
51
52 @property
53 def isWritingImage(self):
54 return self._imageFilename is not None
55
56 @property
57 def isWritingVideo(self):
58 return self._videoFilename is not None
59
60 def enterFrame(self):
61 # 检查上一帧是否被处理完,如未处理完,则会被下一帧覆盖,最终导致实时画面或者保存的视频不连续
62 assert not self._enteredFrame, 'previous enterFrame() had no matching exitFrame()'
63
64 if self._capture is not None:
65 self._enteredFrame = self._capture.grab()
66
67 def exitFrame(self):
68 # 如果当前帧为None,表示未成功捕获有效帧或视频流已处理完成,此时则直接结束此方法
69 if self.frame is None:
70 self._enteredFrame = False
71 return
72
73 # 更新FPS估值
74 if self._framesElapsed == 0:
75 self._startTime = time.perf_counter()
76 else:
77 timeElapsed = time.perf_counter() - self._startTime
78 self._fpsEstimate = self._framesElapsed / timeElapsed
79 self._framesElapsed += 1
80
81 # 是否水平反转画面并展示
82 if self.previewWindowManager is not None:
83 if self.shouldMirrorPreview:
84 mirroredFrame = numpy.fliplr(self._frame)
85 self.previewWindowManager.show(mirroredFrame)
86 else:
87 self.previewWindowManager.show(self._frame)
88
89 # 将当前帧保存为图片
90 if self.isWritingImage:
91 cv2.imwrite(self._imageFilename, self._frame)
92 self._imageFilename = None
93
94 # 将当前帧写入视频
95 self._writeVideoFrame()
96
97 # 释放并退出当前帧
98 self._frame = None
99 self._enteredFrame = False
100
101 def writeImage(self, filename):
102 self._imageFilename = filename
103
104 def startWritingVideo(self, filename, encoding=cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')):
105 self._videoFilename = filename
106 self._videoEncoding = encoding
107
108 def stopWritingVideo(self):
109 self._videoFilename = None
110 self._videoEncoding = None
111 self._videoWriter = None
112
113 def _writeVideoFrame(self):
114 if not self.isWritingVideo:
115 return
116
117 # 检查是否创建了VideoWriter对象
118 if self._videoWriter is None:
119 # 获取摄像头帧率
120 fps = self._capture.get(cv2.CAP_PROP_FPS)
121 # 如果帧率获取失败则使用估计值
122 if numpy.isnan(fps) or fps <= 0.0:
123 # 获取更多的以处理帧数,以求得更稳定的帧率
124 if self._framesElapsed < 20:
125 return
126 else:
127 fps = self._fpsEstimate
128 size = (int(self._capture.get(
129 cv2.CAP_PROP_FRAME_WIDTH)),
130 int(self._capture.get(
131 cv2.CAP_PROP_FRAME_HEIGHT)))
132 self._videoWriter = cv2.VideoWriter(
133 self._videoFilename, self._videoEncoding,
134 fps, size)
135
136 self._videoWriter.write(self._frame)
137
138
139 class WindowManager(object):
140
141 def __init__(self, windowName: str
142 , keypressCallback=None):
143 self.keypressCallback = keypressCallback
144
145 self._windowName = windowName
146 self._isWindowCreated = False
147
148 @property
149 def isWindowCreated(self):
150 return self._isWindowCreated
151
152 def createWindow(self):
153 cv2.namedWindow(self._windowName)
154 self._isWindowCreated = True
155
156 def show(self, frame):
157 cv2.imshow(self._windowName, frame)
158
159 def destroyWindow(self):
160 cv2.destroyWindow(self._windowName)
161 self._isWindowCreated = False
162
163 def processEvents(self):
164 keycode = cv2.waitKey(1)
165 if self.keypressCallback is not None and keycode != -1:
166 self.keypressCallback(keycode)

cameo.py

 1 import cv2
2 from managers import WindowManager, CaptureManager
3
4
5 class Cameo:
6 def __init__(self):
7 self._windowManager = WindowManager('Cameo',
8 self.onKeypress)
9 self._captureManager = CaptureManager(
10 cv2.VideoCapture(0), self._windowManager, True)
11
12 def run(self):
13 # 创建窗口
14 self._windowManager.createWindow()
15 while self._windowManager.isWindowCreated:
16 # 开始捕获摄像头帧
17 self._captureManager.enterFrame()
18 # 解码并获取实际帧
19 frame = self._captureManager.frame
20 # 预留后续新功能
21 if frame is not None:
22 pass
23 # 写入图片文件或者视频文件并释放帧资源
24 self._captureManager.exitFrame()
25 # 检查并返回键盘状态
26 self._windowManager.processEvents()
27
28 def onKeypress(self, keycode):
29 if keycode == 32: # space
30 self._captureManager.writeImage(r'screenshot.png')
31 elif keycode == 9: # tab
32 if not self._captureManager.isWritingVideo:
33 self._captureManager.startWritingVideo('screencast.avi')
34 else:
35 self._captureManager.stopWritingVideo()
36 elif keycode == 27: # escape
37 self._windowManager.destroyWindow()
38
39
40 if __name__ == "__main__":
41 Cameo().run()

【Python】【OpenCV】Cameo项目(一)实时显示摄像头帧的更多相关文章

  1. Javaweb项目页面实时显示后台处理结果

    http://www.cnblogs.com/dong-xu/p/6701271.html 此博文甚好,项目参照博主代码可实现. 前端页面: <%@ page language="ja ...

  2. 使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo. 本文使用Markdown写成,为获得更好的 ...

  3. GUI开发:实时显示摄像头图像

    import tkinter as tk from PIL import Image, ImageTk import cv2 import numpy as np import time g_exit ...

  4. python opencv3 窗口显示摄像头的帧

    git:https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 """ 在窗口显示摄像 ...

  5. springboot1.5.9整合websocket实现实时显示的小demo

    最近由于项目需要实时显示数据库更新的数据变化情况,一开始想过在前端使用ajax异步轮询方法实现,但后面考虑到性能和流量等要求,就放弃该方法而选择使用websocket(毕竟现在springboot整合 ...

  6. 在python3下使用OpenCV 抓取摄像头图像并实时显示3色直方图

    以下代码为在Python3环境下利用OpenCV 抓取摄像头的实时图像, 通过OpenCV的 calHist函数计算直方图, 并显示在3个不同窗口中. import cv2 import numpy ...

  7. HSmartWindowControl 之 摄像头实时显示( 使用 WPF )

    1.添加Halcon控件,创建WPF项目 在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见: HSmartWindowControl之安装篇 (Visual Studio ...

  8. python实现websocket服务器,可以在web实时显示远程服务器日志

    一.开始的话 使用python简单的实现websocket服务器,可以在浏览器上实时显示远程服务器的日志信息. 之前做了一个web版的发布系统,但没实现在线看日志,每次发布版本后,都需要登录到服务器上 ...

  9. 使用vue 遇到的问题————— 解决手机实时显示项目

    Vue项目文件组织架构: src文件夹存放源代码. Static文件夹存放第三方静态资源.     git将项目上传github  http://blog.csdn.net/laozitianxia/ ...

  10. Python+OpenCV图像处理(一)——读取显示一张图片

    先在此处先声明,后面学习python+opencv图像处理时均参考这位博主的博文https://blog.csdn.net/u011321546/article/category/7495016/2? ...

随机推荐

  1. 动态规划二 & 贪心算法 实验三

    一.贪心算法和动态规划法解决背包问题. 有一个背包其容积 C = 13.现有表格内的物品可以购买. 商品 价格 P 体积 V 啤酒 24 10 汽水 2 3 饼干 9 4 面包 10 5 牛奶 9 4 ...

  2. rnacos实现raft和类distro协议,支持集群部署

    1. rnacos 简介 rnacos是一个用rust实现的nacos服务. rnacos是一个轻量. 快速.稳定.高性能的服务:包含注册中心.配置中心.web管理控制台功能,支持单机.集群部署. r ...

  3. 探秘移动端BI:发展历程与应用前景解析

    什么是移动端BI 维基百科 上对于 移动端商业智能的定义是这样的 > Mobile BI is a system that presents historical and real-time i ...

  4. Hadoop - WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform...

    Hadoop - WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... 配置完ha ...

  5. 解决CentOS 7出现docker-compose: command not found

    解决CentOS 7出现docker-compose: command not found 1. 安装docker-compose 既然使用了docker-compose那自然得安装了 在GitHub ...

  6. js合并对象常用方法

    const person = { name: 'David Walsh', gender: 'Male' }; const tools = { computer: 'Mac', editor: 'At ...

  7. AT 下分记录

    7.30 AGC063 \(+30=1620\) B 做法假 WA 了三次,为啥总是吃了罚时才能发现问题啊 心态还是需要解决的问题.过完 B 啥都想不出来又自闭了

  8. 基于 P-Tuning v2 进行 ChatGLM2-6B 微调实践

    微调类型简介 1. SFT监督微调:适用于在源任务中具有较高性能的模型进行微调,学习率较小.常见任务包括中文实体识别.语言模型训练.UIE模型微调.优点是可以快速适应目标任务,但缺点是可能需要较长的训 ...

  9. 网络基础-OSI七层vsTCP/UDP四层 五层 数据封装

    1.0 网络基础 1.1 网络是什么? 网络是信息传输.接收.共享的虚拟平台,通过它把各个点.面.体的信息联系到一起,从而实现这些资源的共享 网络分类:局域网 ,城域网,广域网 1.2 数据通信方式 ...

  10. K8s - 安装部署Kafka、Zookeeper集群教程(支持从K8s外部访问)

    本文演示如何在K8s集群下部署Kafka集群,并且搭建后除了可以K8s内部访问Kafka服务,也支持从K8s集群外部访问Kafka服务.服务的集群部署通常有两种方式:一种是 StatefulSet,另 ...