Pygame 官方文档 - Tutorials - camera模块介绍(Camera Module Introduction)

camera模块介绍(Camera Module Introduction)

Author: by Nirav Patel
Contact: nrp@eclecti.cc
        Pygame 1.9支持连接相机,允许您捕捉静止图像,观看直播流,并做一些简单的计算机视觉。 本教程将涵盖所有这些用例,提供可以基于您的应用或游戏的代码示例。 您可以参考完整API的参考文档。
        注意从Pygame 1.9开始,相机模块为在Linux上使用v4l2的相机提供原生支持。 通过Videocapture或OpenCV支持其他平台,但本指南将重点介绍本身的模块。 大多数代码对其他平台都有效,但控件之类的某些东西不起作用。 该模块也标记为实验性的(EXPERIMENTAL),这意味着API可能会在后续版本中更改。

导入和初始化(Import and Init)

import pygame
import pygame.camera
from pygame.locals import *

pygame.init()
pygame.camera.init()

由于camera模块是可选的,因此需要手动导入和初始化,如上所示。

捕捉单个图像(Capturing a Single Image)
        现在我们将介绍打开相机并将框架捕获帧作为表面【surface】。 在下面的示例中,我们假设计算机上有/ dev / video0处的摄像头,并将其初始化为640 x 480的大小。称为图像的表面是调用get_image()时摄像头看到的内容。

cam = pygame.camera.Camera("/dev/video0",(640,480))
cam.start()
image = cam.get_image()

列出已连接的相机(Listing Connected Cameras)
        您可能想知道,如果我们不知道相机的确切路径会怎么样?我们可以要求模块提供连接到计算机的摄像机列表,并初始化列表中的第一台摄像机。

camlist = pygame.camera.list_cameras()
if camlist:
cam = pygame.caemra.Camera(camlist[0],(640,480))

使用相机控件(Using Camera Controls)
        大多数相机都支持控制,如翻转图像和改变亮度。使用start()后,可以在任何时候使用set_controls()和get_controls()。

捕获流直播(Capturing a Live Stream)
        本教程的其余部分将基于捕获实时图像流。 为此,我们将使用下面的类。 如上所述,它只会将持续的相机帧流呈现在屏幕上,有效地显示实时视频。 它基本上是你所期望的,循环get_image(),blitting到显示表面,然后翻转它。 出于性能原因,我们将为相机提供相同的表面以便每次使用。

class Capture(object):
    def __init__(self):
        self.size = (640,480)
        # 创建一个显示surface。 标准的pygame东西
        self.display = pygame.display.set_mode(self.size, 0)

        # 这跟我们之前看到的一样
        self.clist = pygame.camera.list_cameras()
        if not self.clist:
            raise ValueError("Sorry, no cameras detected.")
        self.cam = pygame.camera.Camera(self.clist[0], self.size)
        self.cam.start()

		#创建要捕获的表面。 出于性能目的
		#位深度与显示表面的深度相同。
        self.snapshot = pygame.surface.Surface(self.size, 0, self.display)

    def get_and_flip(self):
		#如果你不想将帧率绑定到相机,你可以检查
        #如果相机准备好了图像。 请注意,虽然这适用于
        #大多数相机,但有些永远不会返回true。
        if self.cam.query_image():
            self.snapshot = self.cam.get_image(self.snapshot)

        # 把它blit到显示器表面。 简单!
        self.display.blit(self.snapshot, (0,0))
        pygame.display.flip()

    def main(self):
        going = True
        while going:
            events = pygame.event.get()
            for e in events:
                if e.type == QUIT or (e.type == KEYDOWN and e.key == K_ESCAPE):
                    #安全地关闭相机
                    self.cam.stop()
                    going = False

            self.get_and_flip()

        由于get_image()是一个阻塞调用,在慢速摄像机上可能需要相当长的时间,因此本例使用query_image()来查看摄像机是否准备就绪。 这允许您将游戏的帧率与相机的帧率分开。 如果您发现相机不能正确支持query_image()函数,也可以让相机在单独的线程中捕获图像,以获得大致相同的性能增益。

基本计算机视觉(Basic Computer Vision)
        通过使用camera,transform和mask模块,pygame可以做一些基本的计算机视觉。

色彩空间(Colorspaces)
        初始化相机时,颜色空间是一个可选的参数,其中“RGB”、“YUV”和“HSV”是可能的选择。YUV和HSV都比RGB更适用于计算机视觉,允许您更容易按颜色阈值,我们将在本教程后面看到。

self.cam = pygame.camera.Camera(self.clist[0], self.size, "RGB")
self.cam = pygame.camera.Camera(self.clist[0], self.size, "YUV")
self.cam = pygame.camera.Camera(self.clist[0], self.size, "HSV")

阈值(Thresholding)
        使用transform模块中的threshold()函数,可以执行简单的绿色屏幕效果,或者在场景中隔离特定颜色的对象。 在下面的示例中,我们仅将绿树阈值化,并使图像的其余部分变黑。 有关阈值功能的详细信息,请查阅参考文档。

self.thresholded = pygame.surface.Surface(self.size, 0, self.display)
self.snapshot = self.cam.get_image(self.snapshot)
pygame.transform.threshold(self.thresholded,self.snapshot,(0,255,0),(90,170,170),(0,0,0),2)

        当然,只有在您已经知道要查找的对象的确切颜色时,这才有用。 为了解决这个问题并使阈值处理在现实世界中可用,我们需要添加一个校准阶段,我们可以识别对象的颜色并使用它来进行阈值处理。 我们将使用transform模块的average_color()函数来执行此操作。 下面是一个示例校准功能,您可以循环直到像按键这样的事件,以及它看起来像什么的图像。 框内的颜色将是用于阈值的颜色。 请注意,我们在下面的图像中使用HSV颜色空间。

def calibrate(self):
    # 捕捉图像
    self.snapshot = self.cam.get_image(self.snapshot)
    # 把它blit到显示surface上
    self.display.blit(self.snapshot, (0,0))
    # 在屏幕中间制作一个rect
    crect = pygame.draw.rect(self.display, (255,0,0), (145,105,30,30), 4)
    # 获取rect内部区域的平均颜色
    self.ccolor = pygame.transform.average_color(self.snapshot, crect)
    # 用这种颜色填充左上角
    self.display.fill(self.ccolor, (0,0,50,50))
pygame.display.flip()
pygame.transform.threshold(self.thresholded,self.snapshot,self.ccolor,(30,30,30),(0,0,0),2)

        你可以使用相同的想法做一个简单的绿色屏幕/蓝色屏幕,首先获得一个背景图像,然后对其进行阈值处理。下面的示例只是将相机指向HSV色彩空间中的空白墙。

def calibrate(self):
    # 捕获一堆背景图像
    bg = []
    for i in range(0,5):
      bg.append(self.cam.get_image(self.background))
    # 将它们平均降低到一个以消除一些噪音
    pygame.transform.average_surfaces(bg,self.background)
    # 把它搞定到显示器surface
    self.display.blit(self.background, (0,0))
pygame.display.flip()
pygame.transform.threshold(self.thresholded,self.snapshot,(0,255,0),(30,30,30),(0,0,0),1,self.background)

使用Mask模块(Using the Mask Module)
        如果你只想显示图像,上面的东西很棒,但是使用遮罩模块,你也可以使用相机作为游戏的输入设备。 例如,回到阈值化特定对象的示例,我们可以找到该对象的位置并使用它来控制屏幕上的对象。

def get_and_flip(self):
    self.snapshot = self.cam.get_image(self.snapshot)
    # 与我们之前得到的颜色相对应的阈值
    mask = pygame.mask.from_threshold(self.snapshot, self.ccolor, (30, 30, 30))
    self.display.blit(self.snapshot,(0,0))
    # 只保留那种颜色的最大斑点
    connected = mask.connected_component()
    # 确保斑点足够大,不仅仅是噪音
    if mask.count() > 100:
        # 找到斑点的中心
        coord = mask.centroid()
        # 在斑点的大小上绘制一个大小可变的圆
        pygame.draw.circle(self.display, (0,255,0), coord, max(min(50,mask.count()/400),5))
pygame.display.flip()

        这只是最基本的例子。 您可以跟踪多个不同颜色的斑点,查找对象的轮廓,在现实生活和游戏对象之间进行碰撞检测,获得对象的角度以实现更精细的控制等等。 玩得开心!
 

以上内容,自己翻译,可能有误,可参考:Tutorials - camera模块介绍(Camera Module Introduction))

点我回顶部

 
 
 
 
 
 
 
Fin.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值