跳转至

附录 A:与 Pygame 集成

本附录显示了如何在 OpenCV 应用中设置 Pygame 库以及如何使用 Pygame 进行窗口管理。 此外,附录还概述了 Pygame 的其他功能以及一些学习 Pygame 的资源。


注意

本章的所有完成代码都可以从我的网站下载


安装 Pygame

假设我们已经根据第 1 章,“设置 OpenCV”中描述的方法之一设置了 Python。 根据我们现有的设置,我们可以通过以下方式之一安装 Pygame:

  • 带有 32 位 Python 的 Windows:从以下位置下载并安装 Pygame 1.9.1。
  • 带有 64 位 Python 的 Windows:从以下位置下载并安装 Pygame 1.9.2 预览版。
  • 带有 Macports 的 Mac:打开“终端”并运行以下命令:

    ```py

    $ sudo port install py27-game

    ```

  • 带有 Homebrew 的 Mac:打开终端并运行以下命令来安装 Pygame 的依赖项,然后安装 Pygame 本身

    ```py

    $ brew install sdl sdl_image sdl_mixer sdl_ttf smpeg portmidi $ /usr/local/share/python/pip install \

    hg+http://bitbucket.org/pygame/pygame

    ```

  • Ubuntu 及其衍生版本:打开“终端”并运行以下命令:

    ```py

    $ sudo apt-get install python-pygame

    ```

  • 其他类似 Unix 的系统:Pygame 在许多系统的标准存储库中可用。 典型的包名称包括pygame, pygame27, py-game, py27-game, python-pygame,python27-pygame.。

现在,Pygame 应该可以使用了。

文档和教程

Pygame 的 API 文档和一些教程可以在以下网址在线找到。

Al Sweigart 的《使用 Python 和 Pygame 制作游戏》是一本烹饪手册,用于在 Pygame 1.9.1 \中重新创建几个经典游戏。 免费的电子版本可从以下网站在线获得。或在以下网站下载 PDF 文件。

派生Manager.WindowManager

如第 2 章,“处理照相机,文件和 GUI”中所述,我们的面向对象设计使我们可以轻松地将 OpenCV 的 HighGUI 窗口管理器切换为另一个窗口管理器,例如 Pygame。 为此,我们只需要继承我们的managers.WindowManager类的子类,并覆盖四个方法:createWindow()show()destroyWindow()processEvents()。 另外,我们需要导入一些新的依赖项。

要继续,我们需要第 2 章“处理照相机,文件和 GUI”中的managers.py文件,和第 4 章“用 Haar 级联跟踪人脸”中的utils.py文件。 在utils.py中,我们只需要一个函数isGray(),我们在第 4 章,“用 Haar 级联跟踪人脸”中实现。 让我们编辑managers.py以添加以下导入:

import pygame
import utils

同样在managers.py中,在执行WindowManager之后的某个位置,我们想添加名为PygameWindowManager的新子类:

class PygameWindowManager(WindowManager):
    def createWindow(self):
        pygame.display.init()
        pygame.display.set_caption(self._windowName)
        self._isWindowCreated = True
    def show(self, frame):
        # Find the frame's dimensions in (w, h) format.
        frameSize = frame.shape[1::-1]
        # Convert the frame to RGB, which Pygame requires.
        if utils.isGray(frame):
            conversionType = cv2.COLOR_GRAY2RGB
        else:
            conversionType = cv2.COLOR_BGR2RGB
        rgbFrame = cv2.cvtColor(frame, conversionType)
        # Convert the frame to Pygame's Surface type.
        pygameFrame = pygame.image.frombuffer(
            rgbFrame.tostring(), frameSize, 'RGB')
        # Resize the window to match the frame.
        displaySurface = pygame.display.set_mode(frameSize)
        # Blit and display the frame.
        displaySurface.blit(pygameFrame, (0, 0))
        pygame.display.flip()
    def destroyWindow(self):
        pygame.display.quit()
        self._isWindowCreated = False
    def processEvents(self):
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN and \
                    self.keypressCallback is not None:
                self.keypressCallback(event.key)
            elif event.type == pygame.QUIT:
                self.destroyWindow()
                return

注意,我们使用了两个 Pygame 模块:pygame.displaypygame.event

调用pygame.display.init()创建一个窗口,调用pygame.display.quit()销毁一个窗口。 重复调用display.init()无效,因为 Pygame 仅适用于单窗口应用。 Pygame 窗口的绘图表面类型为pygame.Surface。 为了获得对该Surface的引用,我们可以调用pygame.display.get_surface()pygame.display.set_mode()。 后一个函数在返回实体之前修改Surface实体的属性。 一个Surface实体具有一个blit()方法,该方法将另一个Surface和一个坐标对作为参数,其中后一个Surface应被“变白”(绘制)到第一个上。 完成当前帧的窗口Surface的更新后,我们应该通过调用pygame.display.flip()来显示它。

通过调用pygame.event.get()可以轮询诸如keypresses之类的事件,该函数将返回自上次调用以来发生的所有事件的列表。 每个事件的类型均为pygame.event.Event,并具有属性 type,它指示事件的类别,例如pygame.KEYDOWN表示按键,pygame.QUIT 表示窗口的关闭按钮被点击。 取决于type的值,Event实体可能具有其他属性,例如,KEYDOWN事件的key(ASCII 键代码)。

相对于使用 HighGUI 的基本WindowManager而言,PygameWindowManager通过在每帧 OpenCV 的图像格式和 Pygame 的Surface格式之间进行转换而产生一些间接费用。 但是,PygameWindowManager提供正常的窗口关闭行为,而基础WindowManager不提供。

修改应用

让我们将cameo.py文件修改为使用PygameWindowManager而不是WindowManager。 在cameo.py中找到以下行:

from managers import WindowManager, CaptureManager

将其替换为:

from managers import PygameWindowManager as WindowManager, \
                     CaptureManager

就这样! 现在,cameo.py使用一个 Pygame 窗口,当单击标准“关闭”按钮时,该窗口应该关闭。

Pygame 的进一步使用

我们仅使用了pygame.displaypygame.event模块的一些基本功能。 Pygame 提供了更多功能,包括:

  • 绘制 2D 几何
  • 绘制文字
  • 管理可绘制 AI 实体(精灵)的分组
  • 捕获与窗口,键盘,鼠标和操纵杆/游戏手柄相关的各种输入事件
  • 创建自定义事件
  • 播放和合成声音和音乐

例如,Pygame 可能是使用计算机视觉的游戏的合适后端,而 HighGUI 则不是。

总结

到现在为止,我们应该有一个应用,该应用使用 OpenCV 捕获(并可能操纵)图像,同时使用 Pygame 显示图像和捕获事件。 从这个基本的集成示例开始,您可能想扩展PygameWindowManager来包装其他 Pygame 功能,或者您想创建另一个WindowManager子类来包装另一个库。



回到顶部