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. Laf 云开发平台及其实现原理

    Laf 产品介绍 自我介绍 大家好,我是来自 Laf 团队的王子俊,很高兴今天能在这里给大家分享我们 Laf 云开发平台及其实现原理.本来想说一点什么天气之类的话作为开头,但主持人都说完啦,我就不多说 ...

  2. MFAN论文阅读笔记(待复现)

    论文标题:MFAN: Multi-modal Feature-enhanced Attention Networks for Rumor Detection 论文作者:Jiaqi Zheng, Xi ...

  3. Solution -「YunoOI 2017」由乃的 OJ

    Description Link. 起床困难综合症 上树. Solution 线段树维护,树剖上树. 具体题解有空再写,我要去睡觉了. #include<bits/stdc++.h> ty ...

  4. Github 组合搜索开源项目 (超详细)

    例如搜索 Spring Boot 相关项目  spring boot (最简单最常用) in:name spring boot (匹配项目名字)  in:name spring boot stars: ...

  5. Oracle查询--增加--删除--修改主键

    对Oracle表主键的操作,有四类:查询,增加,修改,删除 1.查询主键 /*查询某个表中存在的约束*/ select * from user_constraints where table_name ...

  6. C中code关键字

    单片机C语言code是什么作用? code的作用是告诉单片机,我定义的数据要存储在ROM(程序存储区)里面,写入后就不能再更改,其实是相当与汇编里面的寻址MOVC(好像是),因为C语言中没办法详细描述 ...

  7. Django框架项目之支付功能——支付宝支付

    文章目录 支付宝支付 入门 支付流程 aliapy二次封装包 GitHub开源框架 依赖 结构 alipay_public_key.pem app_private_key.pem setting.py ...

  8. Android Tools Project Site

    Android Tools Project Site Search this site   Projects Overview Screenshots Release Status Roadmap D ...

  9. PortAudio详解(2015年12月1日更新)

    PortAudio详解 整理者:赤子玄心 QQ:280604597 Email:280604597@qq.com 大家有什么不明白的地方,或者想要详细了解的地方可以联系我,我会认真回复的 1   简介 ...

  10. STM32 + ESP32(AT固件 MQTT协议) + MQTTX(桌面终端) + (EMQX消息服务器)

    翻出老物件,搭建一个简单的 IOT 开发环境,也算是废物利用了 ,接下来加传感器.1. STM32  采集数据:     RTOS.     资源相对比较丰富,可以根据项目需求定制.2. ESP32  ...