python opencv 摄像头_OpenCV3-Python摄像头实时图像

Cameo项目,使每一步都设计成该应用的一个组件(component),以使应用具有扩展性和重用性。项目实现视频播放、内容截图、关闭调用等功能。

1. 设计方法

创建CaptureManager类和WindowManager类作为高级的I/O流接口。在应用程序代码中可以使用CaptureManager来读取新的帧,并能将帧分配到一个或多个输出中,这些输出包括静止的图像文件、视频文件以及窗口(可通过WindowManager类来实现),WindowManager类使应用程序代码能以面向对象的形式处理窗口和事件。

备注:

Python没有私有成员变量的概念,通常在变量前面添加单/双下划线(_)来表示私有变量。通常在Python中,以单下划线开始的成员变量称为保护变量(即只有类对象和子类对象能访问这些变量),而以双下划线开始的变量称为私有成员变量(即只有类对象自己能访问,子类对象不能访问这个变量)

2. 实现源码

(1) managers.py内容:#!/usr/bin/env python3

# -*- coding: utf-8 -*-

"""

Created on Sun Apr 1 10:18:20 2018

@author: lu

"""

import cv2

import numpy

import time

class CaptureManager(object):

def __init__(self, capture, previewWindowManager = None,

shouldMirrorPreview = False):

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._framesElapsed = numpy.long(0)

self._fpsEstimate = None

@property

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()

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):

""" capture the next frame """

assert not self._enteredFrame,'previous enterFrame() had no matching exitFrame()'

if self._capture is not None:

self._enteredFrame = self._capture.grab()

def exitFrame(self):

""" Draw to the window. Write to files. Release the frame"""

#check whether any grabbed frame is retrievable

if self.frame is None:

self._enteredFrame = False

return

#update the FPS estimate and related variables

if self._framesElapsed == 0:

self._startTime = time.time()

else:

timeElapsed = time.time() - self._startTime

self._fpsEstimate = self._framesElapsed / timeElapsed

self._framesElapsed += 1

#draw to the window, if any.

if self.previewWindowManager is not None:

if self.shouldMirrorPreview:

mirroredFrame = numpy.fliplr(self._frame).copy()

self.previewWindowManager.show(mirroredFrame)

else:

self.previewWindowManager.show(self._frame)

#write to the image file, if any

if self.isWritingImage:

cv2.imwrite(self._imageFilename,self._frame)

self._imageFilename = None

#write to the video file, if any

self._writeVideoFrame()

#release the frame

self._frame = None

self._enteredFrame = False;

def writeImage(self, filename):

"""write the next exited frame to an image file"""

self._imageFilename = filename

"""stop writing exited frame to a video file"""

def startWritingVideo(self, filename,

encoding = cv2.VideoWriter_fourcc('I','4','2','0')):

self._videoFilename = filename

self._videoEncoding = encoding

def stopWritingVideo(self):

"""stop writing exited frames to a video file """

self._videoFilename = None

self._videoEncoding = 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:

#the capture's FPS is unknow so use an estimate

if self._framesElapsed<20:

return

else:

fps = self._fpsEstimate

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

@property

def isWindowCreated(self):

return self._isWindowCreated

def createWindow(self):

cv2.namedWindow(self._windowName)

self._isWindowCreated = True

def show(self, frame):

cv2.imshow(self._windowName,frame)

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)

(2) main.py内容import numpy as np

import cv2

from managers import WindowManager, CaptureManager

class Cameo(object):

def __init__(self):

self._windowManager = WindowManager('Camo', self.onKeypress)

self._captureManager = CaptureManager(cv2.VideoCapture(0), self._windowManager, True)

def run(self):

self._windowManager.createWindow()

while self._windowManager.isWindowCreated:

self._captureManager.enterFrame()

frame = self._captureManager.frame

self._captureManager.exitFrame()

self._windowManager.processEvents()

def onKeypress(self, keycode):

"""

space -> Take a screenshot

tab -> start/stop recording a creencast

escape -> quit

"""

if keycode == 32: #space

self._captureManager.writeImage('screenshot.png')

elif keycode == 9: #tab

if not self._captureManager.isWritingVideo:

self._captureManager.startWritingVideo('screencast.avi')

else:

self._captureManager.stopWritingVideo()

elif keycode == 27: #escape

self._windowManager.destroyWindow()

if __name__=="__main__":

Cameo().run()

3. 实现效果图:

attachment.php?id=1140

注意:本站所有文章除特别说明外,均为原创,转载请务必以超链接方式并注明作者出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值