OpenCV 3 计算机视觉 Python语言实现 初步Cameo 项目

OpenCV 3 计算机视觉 Python语言实现 初步Cameo 项目

Cameo项目初步实现 此程序能显示摄像头帧、监听键盘输入以及记录截图或截屏。
本项目代码共有两个 .py 文件

  1. managers.py
  2. cameo.py

managers.py

首先是导入需要的包

import cv2
import numpy
import time

使用 managers.CaptureManager 提取视频流

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 = int(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, if any."""

        # But first, check that any previous frame was exited
        assert not self._enteredFrame, 'previous enterFame() 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.
        # The getter may retrieve and cache the frame.
        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._fpsEstimer = self._framesElapsed / timeElapsed

        self._framesElapsed += 1

    # Draw to the window, id 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 voide file, if any.
        self._WriteVedioFrame()

        # 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

    def startWritingVideo(self, filename, encoding = cv2.VideoWriter_fourcc('I', '4', '2', '0') ):
        """ Start writing exited farmes to a video file. """

        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 _WriteVedioFrame(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 unknown so use an estimate
                if self._framesElapsed < 20:
                    # Wait until more frames elapse so that the estimate is more stable.
                    return
                else:
                    fps = self._fpsEstimater

            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)

使用managers。WindowManager 抽象窗口和键盘

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 destoryWindow(self):
        cv2.destroyWindow(self._windowName)
        self._isWindowCreated = False

    def processEvent(self):
        keycode = cv2.waitKey(1)
        if self.keypressCallback is not None and keycode != 1:
            #Discard any non-ASCII info encoded by GTK
            keycode &= 0xFF
            self.keypressCallback(keycode)

cameo.Cameo()的强大实现
Cameo类提供两种方法启动应用程序: run0和onkeypress()。在初始化时,Camco类会把onkeypresso作为回调函数创建WindowManager类,而CaptureManager类会使用摄像头和WindowManager类。当调用run()函数时,应用程序会执行主循环处理帧和事件,应用程序会调用onkeypress()函数处理事件。按空格键可获取截图信息,按Tab键可启动1停止截屏(一个视频记录),按Esc键可退出应用程序。

cameo.py

import cv2

from Cameo_Project.managers import WindowManager, CaptureManager


class Cameo(object):

    def __init__(self):
        self._windowManager = WindowManager('Cameo', self.onKeypress)
        self._captureManager = CaptureManager(cv2.VideoCapture(0), self._windowManager, True)

    def run(self):
        """ Run the main loop. """
        self._windowManager.createWindow()
        while self._windowManager.isWindowCreated:
            self._captureManager.enterFrame()
            frame = self._captureManager.frame

            # TODO: Filter the frame (Chapter 3).

            self._captureManager.exitFrame()
            self._windowManager.processEvent()


    def onKeypress(self, keycode):
        """ Handle a keypress 
        
        space   ->  Take a screenshot.
        tab     ->  Start/stop recording a screencast.
        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.destoryWindow()



if __name__=="__main__":
    Cameo().run()

运行该程序,摄像头的图像会被镜像显示,而截图和截屏不会被镜像显示。
书中说是在初始化CaptureManager类时,将shouldMirrorPreview参数设置成了 “Ture”。

这段代码目前除了对帧做镜像处理之外不会有任何操作。在以后的更新中会跟着增加其他效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值