哑哑 发表于 2023-11-27 22:20:43

【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]
查看完整版本: 【Python】【OpenCV】Cameo项目(一)实时显示摄像头帧