Numpy (OpenCV) 图像数组到 OpenGL 纹理 (pi3d)

Numpy (OpenCV) image array to OpenGL texture (pi3d)

我正在使用 pi3d 在屏幕上显示一个 ImageSprite,其纹理来自我正在加载的图像。

displayTexture = pi3d.Texture("display/display.jpg", blend=True, mipmap=True) 
displaySlide = pi3d.ImageSprite(texture=displayTexture, shader=shader, w=800, h=600)

这个纹理图像实际上是我在程序中创建的。这是一个 openCV2 图像,因此只是一个 numpy 数组。目前我保存它只是为了将它作为纹理再次加载,但是有没有办法用不断变化的 numpy 数组值不断更新精灵的纹理?

我查看了 openCV OpenGL 支持,但据我所知,它现阶段仅支持 Windows,因此不适合此用途。

编辑:应该提到我也很高兴有一个较低级别的解决方案。我目前正在尝试在图像数组上使用 .toString() 并将生成的字节列表与 glTexImage2D 一起使用来生成纹理,但到目前为止还没有骰子。

是的,你 可以 将 PIL.Image 传递给 pi3d.Texture,它将使用它创建一个新的纹理。那里涉及一些工作,所以如果它是一个大纹理,它会影响帧速率。您还需要更新保存纹理数组的缓冲区中的指针,以便使用新纹理。

有一种方法可以将 numpy 数组加载到 PIL.Image (Image.fromarray()),因此这是一条简单的路线。然而,它有点令人费解,因为 pi3d 已经将 PIL.Image 转换为一个 numpy 数组,请参阅 https://github.com/tipam/pi3d/blob/master/pi3d/Texture.py#L163

下面的代码可以作为 pi3d.Texture 工作的捷径,但调用 'private' 函数 _load_opengl 有点麻烦。我可能会考虑制作一种更强大的方法来执行此操作(即将视频映射到 3D 对象等)

#!/usr/bin/python
from __future__ import absolute_import, division, print_function, unicode_literals

import demo
import pi3d
import random
import numpy as np
from PIL import Image, ImageDraw
DISPLAY = pi3d.Display.create(x=150, y=150)
shader = pi3d.Shader("uv_flat")
im = Image.open("textures/PATRN.PNG")
#draw = ImageDraw.Draw(im) # there are various PIL libraries you could use
nparr = np.array(im)
tex = pi3d.Texture(im) # can pass PIL.Image rather than path as string
sprite = pi3d.ImageSprite(tex, shader, w=10.0, h=10.0)
mykeys = pi3d.Keyboard()
while DISPLAY.loop_running():
  #draw.line((random.randint(0,im.size[0]),
  #           random.randint(0,im.size[1]),
  #           random.randint(0,im.size[0]),
  #           random.randint(0,im.size[1])), fill=128) # draw random lines
  #nparr = np.array(im)
  nparr += np.random.randint(-2, 2, nparr.shape) # random noise
  tex.image = nparr
  tex._load_opengl()
  sprite.draw()
  if mykeys.read() == 27:
    mykeys.close()
    DISPLAY.destroy()
    break

PS 我不记得切换到 numpy 纹理的 pi3d 版本是什么,但它是最近的,所以你可能需要升级

编辑:

从 Texture.image 字节对象到 numpy 数组的转换是 v1.14 发布于 18Mar15

阐明使用 numpy 数组初始化和刷新不断变化的图像的步骤:

...
im = Image.fromarray(cv2im)       # cv2im is a numpy array
tex = pi3d.Texture(im)            # create Texture from PIL image
sprite = pi3d.ImageSprite(tex, shader, w=10.0, h=10.0)
...
  tex.image = cv2im               # set Texture.image to modified numpy array
  tex._load_opengl()              # re-run OpenGLESv2 routines