我正在使用 pi3d 在屏幕上显示一个 ImageSprite,其纹理来 self 正在加载的图像。
displayTexture = pi3d.Texture("display/display.jpg", blend=True, mipmap=True)
displaySlide = pi3d.ImageSprite(texture=displayTexture, shader=shader, w=800, h=600)
这个纹理图像实际上是我在程序中创建的。这是一个 openCV2 图像,因此只是一个 numpy 数组。目前我保存它只是为了将它作为纹理再次加载,但是有没有办法用不断变化的 numpy 数组值不断更新 Sprite 的纹理?
我查看了 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
关于python - Numpy (OpenCV) 图像数组到 OpenGL 纹理 (pi3d),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30066324/