美文网首页pythonpygame游戏编程
05 pygame编程入门之五:Camera Module In

05 pygame编程入门之五:Camera Module In

作者: 易景漫游杨晓宏 | 来源:发表于2019-07-16 15:02 被阅读0次

    pygame编程入门之五:Camera Module Introduction

    作者: Nirav Patel(nrp@eclecti.cc)

    翻译: 杨晓宏(561071777@qq.com)

    Pygame 1.9支持摄像头接口,允许你捕捉静态图像,观看实时流,并做一些简单的计算机视觉。本教程将介绍所有这些用例,提供您可以基于应用程序或游戏的代码示例。您可以参考完整的API的参考文档。
    注意,在Pygame 1.9中,相机模块为在Linux上使用v4l2的相机提供了本机支持。通过可视设备或OpenCV支持其他平台,但本指南将重点介绍本机模块。大多数代码对于其他平台都是有效的,但是某些诸如控件之类的东西是行不通的。该模块也被标记为实验性的,这意味着API在后续版本中可能会发生变化。

    #Import and Init
    import pygame
    import pygame.camera
    from pygame.locals import *
    
    pygame.init()
    pygame.camera.init()
    

    由于相机模块是可选的,所以需要像上面所示的那样手动导入和初始化。

    捕捉单个图像

    现在我们来看看最简单的例子,打开相机,捕捉一个框架作为一个表面。在下面的例子中,我们假设在计算机上有一个/dev/video0的摄像头,并将其初始化为640到480。被称为图像的表面是当getimage()被调用时所看到的任何东西。

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

    列出连接摄像头

    你可能会想,如果不知道相机的确切路径呢?我们可以要求模块提供一个安装在计算机上的相机列表,并初始化列表中的第一个摄像头。

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

    大多数相机都支持控制,比如翻转图像和改变亮度。 set_controls() and get_controls() 可以在 using start()之后的任何地方使用。

    cam.set_controls(hflip = True, vflip = False)
    print camera.get_controls()
    

    捕捉实时流

    本教程的其余部分将基于捕捉实时的图像流。为此,我们将使用下面的类。正如所描述的,它将简单地将一个持续的摄像头帧流到屏幕上,有效地显示实时视频。它基本上就是您所期望的,循环getimage(),到显示表面,然后翻转它。出于性能方面的原因,我们将每次使用为相机提供相同的表面。

    class Capture(object):
        def __init__(self):
            self.size = (640,480)
            # create a display surface. standard pygame stuff
            self.display = pygame.display.set_mode(self.size, 0)
    
            # this is the same as what we saw before
            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()
    
            # create a surface to capture to.  for performance purposes
            # bit depth is the same as that of the display surface.
            self.snapshot = pygame.surface.Surface(self.size, 0, self.display)
    
        def get_and_flip(self):
            # if you don't want to tie the framerate to the camera, you can check
            # if the camera has an image ready.  note that while this works
            # on most cameras, some will never return true.
            if self.cam.query_image():
                self.snapshot = self.cam.get_image(self.snapshot)
    
            # blit it to the display surface.  simple!
            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):
                        # close the camera safely
                        self.cam.stop()
                        going = False
    
                self.get_and_flip()
    

    由于 get_image()是一个阻塞调用,它可能在慢的摄像头上花费相当多的时间,这个例子使用 query_image() 来查看相机是否已经准备好了。这可以让你把游戏的framerate和你的相机分开。如果您发现您的相机不支持queryimage()函数,那么也可以让相机在单独的线程中捕获图像,从而获得大致相同的性能收益。

    基本的计算机视觉

    通过使用相机、转换和掩码模块,pygame可以做一些基本的计算机视觉。

    颜色空间

    在初始化相机时,colorspace是一个可选参数,它有“RGB”、“YUV”和“HSV”作为可能的选择。YUV和HSV通常对计算机视觉比RGB更有用,并且允许你更容易通过颜色来调整阈值,我们将在后面的教程中看到。

    self.cam = pygame.camera.Camera(self.clist[0], self.size, "RGB")
    ../_images/camera_rgb.jpg
    self.cam = pygame.camera.Camera(self.clist[0], self.size, "YUV")
    ../_images/camera_yuv.jpg
    self.cam = pygame.camera.Camera(self.clist[0], self.size, "HSV")
    ../_images/camera_hsv.jpg
    

    Thresholding

    从转换模块中使用 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)
    
    ../_images/camera_thresholded.jpg

    当然,只有当您已经知道您要寻找的对象的确切颜色时,这才有用。
    为了解决这个问题,让阈值在现实世界中可用,需要添加一个校准阶段,在这个阶段识别对象的颜色并使用它来进行阈值设置。
    使用transform模块的 average_color() 函数来完成这项工作。
    下面是一个校准函数例子,你可以循环,直到像按键一样的事件,以及类似。盒子里的颜色将会是这个threshold颜色。
    请注意,在下面的图像中使用HSV彩色空间。

    def calibrate(self):
        # capture the image
        self.snapshot = self.cam.get_image(self.snapshot)
        # blit it to the display surface
        self.display.blit(self.snapshot, (0,0))
        # make a rect in the middle of the screen
        crect = pygame.draw.rect(self.display, (255,0,0), (145,105,30,30), 4)
        # get the average color of the area inside the rect
        self.ccolor = pygame.transform.average_color(self.snapshot, crect)
        # fill the upper left corner with that color
        self.display.fill(self.ccolor, (0,0,50,50))
        pygame.display.flip()
        
    
    ../_images/camera_average.jpg
    pygame.transform.threshold(self.thresholded,self.snapshot,self.ccolor,(30,30,30),(0,0,0),2)
    
    ../_images/camera_thresh.jpg

    你可以用同样的方法做一个简单的绿色屏幕/蓝色屏幕,首先得到一个背景图像,然后对它进行阈值处理。
    下面的例子只是把相机对准了HSV彩色空间的空白白色墙壁。

    def calibrate(self):
        # capture a bunch of background images
        bg = []
        for i in range(0,5):
          bg.append(self.cam.get_image(self.background))
        # average them down to one to get rid of some noise
        pygame.transform.average_surfaces(bg,self.background)
        # blit it to the display surface
        self.display.blit(self.background, (0,0))
        pygame.display.flip()
        
    
    ../_images/camera_background.jpg
    pygame.transform.threshold(self.thresholded,self.snapshot,(0,255,0),(30,30,30),(0,0,0),1,self.background)
    
    ../_images/camera_green.jpg

    使用掩模模块

    如果你只是想要显示图像,上面的东西是很棒的,但是使用蒙版模块,你也可以使用摄像头作为游戏的输入设备。例如,回到阈值的例子中,我们可以找到那个对象的位置,并使用它来控制屏幕上的对象。

    def get_and_flip(self):
        self.snapshot = self.cam.get_image(self.snapshot)
        # threshold against the color we got before
        mask = pygame.mask.from_threshold(self.snapshot, self.ccolor, (30, 30, 30))
        self.display.blit(self.snapshot,(0,0))
        # keep only the largest blob of that color
        connected = mask.connected_component()
        # make sure the blob is big enough that it isn't just noise
        if mask.count() > 100:
            # find the center of the blob
            coord = mask.centroid()
            # draw a circle with size variable on the size of the blob
            pygame.draw.circle(self.display, (0,255,0), coord, max(min(50,mask.count()/400),5))
        pygame.display.flip()
    
    ../_images/camera_mask.jpg

    这是最基本的例子。
    你可以追踪多个不同颜色的斑点,找到物体的轮廓,在现实生活中和在游戏对象之间进行碰撞检测,获得一个物体的角度,以获得更好的控制,等等。玩得开心!

    相关文章

      网友评论

        本文标题:05 pygame编程入门之五:Camera Module In

        本文链接:https://www.haomeiwen.com/subject/hqhtlctx.html