概述
OpenCV捕获摄像头并进行录像、截图等功能的实现
本文主要介绍一个小项目,此项目实现了对于摄像头画面的捕捉以及,对于画面的截取和一段画面的存储和处理的功能
我们将采用三个类来进行实现
1 CaptureManager类:
提取视频流
实现进入画面,退出画面(获取图像、估计帧速率、通过窗口管理器显示图像、暂停、写入图像)
2 WindowManager类:
抽象窗口和键盘
进行窗口的管理(初始化、 创建、展示、 释放)
3 Cameo 类:
进行初始化、运行(主循环捕获图像、显示图像 会调用到CaptureManager类中的方法)、触发事件(调用 Windows类中的方法)
import cv2
import numpy
import time
# fps frames per second 每秒传输的帧数
class CaptureManager(object):
# 进入画面
# 退出画面(绘制到窗口,写入文件, 释放帧)
# 写入图像
# 开始录像 (捕获摄像头的画面)
# 停止录像 存储录像
# args:
# capture:VideoCapture 对象, 用于读取视频文件或者 捕捉摄像头图像(capture = cv2.VideoCapture(0))
# preview_window_manager: 预处理窗口管理器 若设置了该参数则会在调用 enterFrame()
# 函数的时候将捕获的图像显示在指定的窗体上
# should_mirror_preview:是否在指定窗口上镜像显示(水平翻转)
def __init__(self, capture, previewWindowManager = None,
shouldMirrorPreview = False):
# mirrorPreview 进行镜面反转
self.previewWindowManager = previewWindowManager
self.shouldMirrorPreview = shouldMirrorPreview
#定义私有属性
# 属性加单下划线或者双下划线可以表示私有变量
self._capture = capture
self._channel = 0
self._enteredFrame = False
self._frame = None
self._imageFileName = None
self._videoFileName = None
self._videoEncoding = None
self._videoWriter = None
#摄像头调用 通道和帧的设置 图像文件 以及 视频文件
self._startTime = None
self._frameElapsed = int(0)
self._fpsEstimate = None
@property # 只读属性
#内置的@property装饰器Python负责将一种方法转换为属性调用。
def channel(self):
return self.channel
@channel.setter
def channel(self, value):
if self._channel !=value:
self._channel =value
self._frame = None
@property
def frame(self):
if self._enteredFrame and self._frame is None:
_, self._frame = self._capture.retrieve()
# retrieve 适用于多个摄像头进行同步
return self._frame
@property
def isWritingImage(self):
return self._imageFileName is not None
@property
def isWritingVideo(self):
return self._videoFileName is not None
def enterFrame(self):
# 检测之前是不是有其他的帧还未退出
assert not self._enteredFrame,
"previous enterFrame() had no matching exitFrame()"
if self._capture is not None:
#捕获帧
self._enteredFrame = self._capture.grab()
def exitFrame(self):
"""绘制到窗口 写入文件 释放帧"""
#检测是否还有其他的帧是可以获取的
# the getter 可以检索并取回帧
if self.frame is None:
self._enteredFrame = False
return
#更新帧速度估算值以及相关变量
if self._frameElapsed == 0:
self._startTime = time.time()
else:
timeElaspsed = time.time() - self._startTime
self._fpsEstimate = self._frameElapsed / timeElaspsed
self._frameElapsed += 1
# 如果指定了窗口管理器,则在窗口中显示图像
if self.previewWindowManager is not None:
if self.shouldMirrorPreview: # 想要返回镜像
mirroredFrame = numpy.fliplr(self._frame).copy()
# 使得矩阵x沿着垂直轴左右进行翻转
self.previewWindowManager.show(mirroredFrame)
else:
self.previewWindowManager.show(self.frame)
#是否指定图片路径,将图片写入到文件中
if self.isWritingImage:
cv2.imwrite(self._imageFileName, self._frame)
self._imageFileName = None
#将每一帧图像写到视频文件中
self._WriteVideoFrame() #_WriteVideoFrame
# 清空标志位 释放帧
self._frame = None
self._enteredFrame = False
# 指定录入的图像路径
def writeImage(self, filename):
"""指定每一帧图像的写入路径,
实际的写入操作会推迟到"下一次调用exitFrame 函数"""
self._imageFilename = filename
def startWritingVideo(self, filename,
encoding = cv2.VideoWriter_fourcc("I", "4", "2", "0")):
self._videoFileName = filename
self._videoEncoding = encoding
#结束录制
def stopWritingVideo(self):
self._videoEncoding = None
self._videoFilename = None
self._videoWriter = None
# 录制视频 非公有函数
def _WriteVideoFrame(self):
if not self.isWritingVideo:
return
if self._videoWriter is None:
fps = self._capture.get(cv2.CAP_PROP_FPS)
if fps == 0.0:
if self._framesElapsed < 20:
# 等待直到更多的帧经过 ,这样的话估算就比较容易和合适
return
else:
fps = self._fps_Estimate
size = (int(self._capture.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(self._capture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
self._videoWriter = cv2.VideoWriter(self._videoFileName, self._videoEncoding,
fps, size)
self._videoWriter.write(self._frame)
class WindowManager(object):
#创建窗体 绑定触发事件
def __init__(self, windowName, keypressCallback = None):
self.keypressCallback = keypressCallback
self._windowName = windowName
self._isWindowCreated = False
def show(self, frame):
cv2.imshow(self._windowName, frame)
@property
def isWindowCreated(self):
return self._isWindowCreated
def createWindow(self):
cv2.namedWindow(self._windowName)
self._isWindowCreated = True
def destroyWindow(self):
cv2.destroyWindow(self._windowName)
self._isWindowCreated = False
def processEvents(self):
keycode = cv2.waitKey(1)
if self.keypressCallback is not None and keycode != -1:
keycode &= 0xFF
self.keypressCallback(keycode)
import cv2
from managers import WindowManager, CaptureManager
import filters
class Cameo(object):
def __init__(self):
self._windowManager = WindowManager("Cameo", self.onKeypress)
self._CaptureManager = CaptureManager(
cv2.VideoCapture(0), self._windowManager, True)
#self._curveFilter = filters.BGRPortraCurveFilter()
def run(self):
" 进行主循环"
self._windowManager.createWindow()
while self._windowManager.isWindowCreated:
self._CaptureManager.enterFrame()
frame = self._CaptureManager.frame
# 过滤帧
filters.strokeEdges(frame, frame)
#self._curveFilter.apply(frame, frame)
self._CaptureManager.exitFrame()
self._windowManager.processEvents()
def onKeypress(self, keycode):
""" 对特殊的按键 进行相应"""
if keycode == 32: #空格
self._CaptureManager.writeImage("screenhot.png")
elif keycode == 9: # tab
if not self._CaptureManager.isWritingVideo:
self._CaptureManager.startWritingVideo("screencast.avi")
else:
self._CaptureManager.stopWritingVideo()
elif keycode == 27:
self._windowManager.destroyWindow()
if __name__ =="__main__":
c1 = Cameo()
c1.run()
最后
以上就是苹果宝马为你收集整理的OpenCV捕获摄像头并进行录像、截图等功能的实现的全部内容,希望文章能够帮你解决OpenCV捕获摄像头并进行录像、截图等功能的实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复