【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 annotations2 import cv23 import numpy4 import time5 6 '''7 1、允许同一文件下不同类之间的类型提示,py3.7以上特性8 2、cv2——获取摄像头和展示9 3、numpy——对展示画面进行左右翻转(fliplr) 10 4、time——精确获取时间间隔,然后计算帧率估值 11 ''' 121314 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 2021 self._capture = capture 22 self._channel = 0 23 self._enteredFrame = False 24 self._frame = None 2526 self._imageFilename = None 27 self._videoFilename = None 28 self._videoEncoding = None 29 self._videoWriter = None 3031 self._startTime = None 32 self._framesElapsed = 0 33 self._fpsEstimate = None 3435 @property 36 def channel(self): 37 return self._channel 3839 @channel.setter 40 def channel(self, value): 41 if self._channel != value: 42 self._channel = value 43 self._frame = None# 对通道赋值时需要将当前帧置空,否则可能出现通道为未更改现象 4445 # 如果进入帧,且当前帧为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 5152 @property 53 def isWritingImage(self): 54 return self._imageFilename is not None 5556 @property 57 def isWritingVideo(self): 58 return self._videoFilename is not None 5960 def enterFrame(self): 61 # 检查上一帧是否被处理完,如未处理完,则会被下一帧覆盖,最终导致实时画面或者保存的视频不连续 62 assert not self._enteredFrame, 'previous enterFrame() had no matching exitFrame()' 6364 if self._capture is not None: 65 self._enteredFrame = self._capture.grab() 6667 def exitFrame(self): 68 # 如果当前帧为None,表示未成功捕获有效帧或视频流已处理完成,此时则直接结束此方法 69 if self.frame is None: 70 self._enteredFrame = False 71 return 7273 # 更新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 8081 # 是否水平反转画面并展示 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) 8889 # 将当前帧保存为图片 90 if self.isWritingImage: 91 cv2.imwrite(self._imageFilename, self._frame) 92 self._imageFilename = None 9394 # 将当前帧写入视频 95 self._writeVideoFrame() 9697 # 释放并退出当前帧 98 self._frame = None 99 self._enteredFrame = False100 101 def writeImage(self, filename):102 self._imageFilename = filename103 104 def startWritingVideo(self, filename, encoding=cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')):105 self._videoFilename = filename106 self._videoEncoding = encoding107 108 def stopWritingVideo(self):109 self._videoFilename = None110 self._videoEncoding = None111 self._videoWriter = None112 113 def _writeVideoFrame(self):114 if not self.isWritingVideo:115 return116 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
页:
[1]