【问题标题】:Capture Webcam image using CV2 and Pyglet in Python在 Python 中使用 CV2 和 Pyglet 捕获网络摄像头图像
【发布时间】:2015-09-10 20:36:48
【问题描述】:

我正在使用 Python 的 CV2 (OpenCV) 和 Pyglet Python 库来创建一个小型应用程序,该应用程序将显示来自网络摄像头的实时视频并覆盖一些文本或静态图像。我已经使用 CV2 制作了一个应用程序,它只在一个框架中显示网络摄像头图像,但现在我想将该框架放在一个 pyglet 窗口中。

到目前为止,这是我拼凑起来的:

import pyglet
from pyglet.window import key
import cv2
import numpy


window = pyglet.window.Window()

camera=cv2.VideoCapture(0)

def getCamFrame(color,camera):
    retval,frame=camera.read()
    if not color:
        frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
    frame=numpy.rot90(frame)
    return frame


frame=getCamFrame(True,camera)
video = pyglet.resource.media(frame, streaming=True)

@window.event
def on_key_press(symbol, modifiers):
    if symbol == key.ESCAPE:
        print 'Application Exited with Key Press'
        window.close()

@window.event
def on_draw():
    window.clear()
    video.blit(10,10)

pyglet.app.run()

运行时出现以下错误:

Traceback, line 20 in <module>
  video = pyglet.resource.media(frame, streaming=True)
TypeError: unhashable type: 'numpy.ndarray'

我也愿意接受其他选项,让我在直播视频上显示文本。我最初使用 pygame,但最后我需要多显示器支持,所以我使用了 pyglet。

【问题讨论】:

    标签: python opencv video numpy pyglet


    【解决方案1】:
    import pyglet
    import cv2
    window = pyglet.window.Window()
    
    video = cv2.VideoCapture(0)
    def takepicture(dt):
        num = 0
    
        ret,frame = video.read()
        cv2.imwrite(str(num)+'.jpg',frame)
        print("Image_Captured")
    
    @window.event
    def on_draw():
        window.clear()
        image = pyglet.image.load('0.jpg')
        image.blit(0,0)
    
    pyglet.clock.schedule_interval(takepicture, 0.001)
    
    
    pyglet.app.run()
    

    【讨论】:

    • 你能解释一下这段代码是如何解决问题的吗?
    【解决方案2】:

    您可以使用ImageData constructor 将每个opencv 图像转换为pyglet 图像。思路是将opencv图像转换成PIL数组,然后再转换成字节串,然后作为原始数据传递给构造函数。

    from PIL import Image
    def cv2glet(img):
        '''Assumes image is in BGR color space. Returns a pyimg object'''
        rows, cols, channels = img.shape
        raw_img = Image.fromarray(img).tobytes()
    
        top_to_bottom_flag = -1
        bytes_per_row = channels*cols
        pyimg = pyglet.image.ImageData(width=cols, 
                                       height=rows, 
                                       format='BGR', 
                                       data=raw_img, 
                                       pitch=top_to_bottom_flag*bytes_per_row)
        return pyimg
    

    【讨论】:

      【解决方案3】:

      虽然这可行,但我发现当图像为高分辨率时,从 numpy 数组加载图像非常慢。 pygarrrayimage,github上的一个python模块,可以直接将numpy数组加载到显卡中,无需复制:

      https://github.com/motmot/pygarrayimage

      这使我从高分辨率视频中加载图像的 python 应用程序不会出现延迟。查看示例文件夹,了解如何将图像快速传送到屏幕上。

      【讨论】:

        【解决方案4】:

        您的方法存在许多问题,但最棘手的是将 numpy 数组转换为纹理。我使用下面的方法,这是我在 SO 其他地方的某个时候发现的。简而言之,您必须利用 pyglet.gl 公开的 ctypes 类型和结构来生成 GLubytes 数组,然后将图像的内容(一个 numpy 数组)放入其中。然后,因为你有一个一维数组的值,你必须通过指定像素格式和间距来指定 Pyglet 应该如何制作图像,pImage 这里。

        如果您让下面的示例正常工作,您应该能够让pImg 在每次调用on_draw 时更新,您应该完成了。

        import pyglet
        from pyglet.gl import *
        from pyglet.window import key
        import cv2
        import numpy
        import sys
        
        window = pyglet.window.Window()
        
        camera=cv2.VideoCapture(0)
        
        retval,img = camera.read()
        sy,sx,number_of_channels = img.shape
        number_of_bytes = sy*sx*number_of_channels
        
        img = img.ravel()
        
        image_texture = (GLubyte * number_of_bytes)( *img.astype('uint8') )
        # my webcam happens to produce BGR; you may need 'RGB', 'RGBA', etc. instead
        pImg = pyglet.image.ImageData(sx,sy,'BGR',
               image_texture,pitch=sx*number_of_channels)
        
        @window.event
        def on_key_press(symbol, modifiers):
            if symbol == key.ESCAPE:
                print 'Application Exited with Key Press'
                window.close()
        
        @window.event
        def on_draw():
            window.clear()
            pImg.blit(0,0)
        
        pyglet.app.run()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-09
          • 1970-01-01
          相关资源
          最近更新 更多