如何用pyglet显示numpy数组?

4 投票
2 回答
3063 浏览
提问于 2025-04-16 00:43

我有一个标签矩阵,大小是100乘100,存储在一个numpy数组里,我想用pyglet来显示这个矩阵。

我最开始的想法是用这个矩阵通过函数pyglet.image.ImageData()来生成一个新的pyglet图像。这个函数需要一个图像数据的缓冲区作为输入,但我不知道怎么从numpy数组中得到一个格式正确的缓冲区。

有没有人知道该怎么做?

补充一下,我现在的解决方案:

3d_label = numpy.empty([100,100,3])
3d_label[:,:,0] = label * 255            # value range of label is [0,1]
3d_label[:,:,1] = label * 255
3d_label[:,:,2] = label * 255
image_data = ctypes.string_at(id(3d_label.tostring())+20, 100*100*3)
image = pyglet.image.ImageData(100, 100, 'RGB', image_data, -100*3)

有没有更好的方法用numpy从三个100乘100的矩阵构建一个[100*100*3]的矩阵?

2 个回答

1

你可以通过 3d_label.tostring() 来获取数组的内存表示。

tostring() 这个方法可以让你改变数组元素在内存中的排列顺序:

Parameters
----------
order : {'C', 'F', None}, optional
    Order of the data for multidimensional arrays:
    C, Fortran, or the same as for the original array.

另外,3d_label.data 这个方法用的内存更少,因为它不需要构建字符串。不过,它不能让你改变元素输出的顺序。

5

我觉得你想要的功能是 np.dstack(或者更一般来说,np.concatenate):

label255=label*255
label3=numpy.dstack((label255,label255,label255))

这个例子显示了 dstack 生成的数组(label3)和你自己构建的 label_3d 是一样的:

import numpy as np

label=np.random.random((100,100))
label255=label*255
label3=np.dstack((label255,label255,label255))

label_3d = np.empty([100,100,3])
label_3d[:,:,0] = label * 255            # value range of label is [0,1]
label_3d[:,:,1] = label * 255
label_3d[:,:,2] = label * 255
print(np.all(label3==label_3d))
# True

另外,我不太确定,但你有没有试过用 label3.data 来代替 ctypes.string_at(id(label3.tostring())+20, 100*100*3) 呢?

撰写回答