【Python】【OpenCV】Cameo项目(一)实时显示摄像头帧
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项目(一)实时显示摄像头帧的更多相关文章
- Javaweb项目页面实时显示后台处理结果
http://www.cnblogs.com/dong-xu/p/6701271.html 此博文甚好,项目参照博主代码可实现. 前端页面: <%@ page language="ja ...
- 使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)
前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo. 本文使用Markdown写成,为获得更好的 ...
- GUI开发:实时显示摄像头图像
import tkinter as tk from PIL import Image, ImageTk import cv2 import numpy as np import time g_exit ...
- python opencv3 窗口显示摄像头的帧
git:https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 """ 在窗口显示摄像 ...
- springboot1.5.9整合websocket实现实时显示的小demo
最近由于项目需要实时显示数据库更新的数据变化情况,一开始想过在前端使用ajax异步轮询方法实现,但后面考虑到性能和流量等要求,就放弃该方法而选择使用websocket(毕竟现在springboot整合 ...
- 在python3下使用OpenCV 抓取摄像头图像并实时显示3色直方图
以下代码为在Python3环境下利用OpenCV 抓取摄像头的实时图像, 通过OpenCV的 calHist函数计算直方图, 并显示在3个不同窗口中. import cv2 import numpy ...
- HSmartWindowControl 之 摄像头实时显示( 使用 WPF )
1.添加Halcon控件,创建WPF项目 在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见: HSmartWindowControl之安装篇 (Visual Studio ...
- python实现websocket服务器,可以在web实时显示远程服务器日志
一.开始的话 使用python简单的实现websocket服务器,可以在浏览器上实时显示远程服务器的日志信息. 之前做了一个web版的发布系统,但没实现在线看日志,每次发布版本后,都需要登录到服务器上 ...
- 使用vue 遇到的问题————— 解决手机实时显示项目
Vue项目文件组织架构: src文件夹存放源代码. Static文件夹存放第三方静态资源. git将项目上传github http://blog.csdn.net/laozitianxia/ ...
- Python+OpenCV图像处理(一)——读取显示一张图片
先在此处先声明,后面学习python+opencv图像处理时均参考这位博主的博文https://blog.csdn.net/u011321546/article/category/7495016/2? ...
随机推荐
- C#结合OpenCVSharp4图片相似度识别
OpenCVSharp4图片相似度识别 需求背景:需要计算两个图片的相似度,然后将相似的图片进行归纳 1. 图片相似度算法 由于我是CRUD后端仔,对图像处理没什么概念.因此网上调研了几种相似度算法分 ...
- WASI support in Go
原文在这里. 由 Johan Brandhorst-Satzkorn, Julien Fabre, Damian Gryski, Evan Phoenix, and Achille Roussel 发 ...
- Solution -「洛谷 P2044」「NOI 2012」随机数生成器
Description Link. 给你一个递推式,让你求某一项的值模上 \(g\). Solution 这道题正解是矩阵.我这里给出一种分治的做法. 题目中说 $\ \ \ \ \ \ \ $ $\ ...
- HashMap底层源码分析
HashMap底层原理实现 1.HashMap初始化 jdk1.8版本之后:数组+链表+红黑树实现,先去观看HashMap的构造方法: 构造方法: public HashMap() { this.lo ...
- 若依框架的startPage( )函数怎么自动关联查询SQL语句?
Question Description 使用JAVA语言的若依框架的时候,发现只要使用了startPage()函数, 并不需要前端传递分页的数据,也不需要注解,就能完成分页功能.预判他应该是使用类似 ...
- getchar()和putchar()
#include <stdio.h> #include <stdlib.h> int main() { char ch; /*.putchar() a. putchar函数的格 ...
- Top 5 Code Smells Newbies Developers Could Easily Identify & Avoid
Posted by Ajitesh Kumar / In Freshers, Software Quality / February 1, 2014 Following is one very pop ...
- element ui的多个表格复选框,展开列显示错误
今天在公司写页面的时候碰到一个bug,我们的那个页面上有多个表格. 用v-if来判断显示,然后再使用复选框和展开列的时候出了问题.先是复选框,第二个表格的复选框下一列不显示,我试了试,在下面的一列都会 ...
- 区间检测(range)
区间检测(range) 时间限制: 1 Sec 内存限制: 128 MB 题目描述 给定一个长度为n的序列,进行m次检测,每次检测某个区间中,是否有重复的数. 输入 第一行,两个整数n和m,表示序列 ...
- 【虹科干货】谈谈Redis Enterprise实时搜索的过人之处
我们都知道,用户在使用应用程序时候,对于速度有着越来越高的要求,真可谓是"一秒也等不及".而开发团队又该怎样来满足这种对于实时性的期望呢? 文章速览: Redis Enterpri ...