如何将numpy数组呈现到pygame表面?

Yot*_*tam 7 python pygame numpy pygame-surface

我正在编写一段代码,其中一部分是读取图像源并将其显示在屏幕上供用户进行交互.我还需要锐化的图像数据.我使用以下内容来读取数据并将其显示出来pyGame

def image_and_sharpen_array(file_name):
    #read the image data and return it, with the sharpened image
    image = misc.imread(file_name)

    blurred = ndimage.gaussian_filter(image,3)
    edge = ndimage.gaussian_filter(blurred,1)
    alpha = 20
    out = blurred + alpha*(blurred - edge)
    return image,out

#get image data
scan,sharpen = image_and_sharpen_array('foo.jpg')
w,h,c = scan.shape


#setting up pygame
pygame.init()
screen = pygame.display.set_mode((w,h))

pygame.surfarray.blit_array(screen,scan)
pygame.display.update()
Run Code Online (Sandbox Code Playgroud)

并且图像仅在旋转和反转的屏幕上显示.这是由于之间的差异misc.imreadpyGame?或者这是由于我的代码中出了什么问题?

还有其他办法吗?我读到的大部分解决方案都涉及保存数字然后用"pyGame"读取它.

tec*_*ico 5

我经常使用 numpyswapaxes()方法:在这种情况下,我们只需要在显示数组之前反转 x 和 y 轴(轴号 0 和 1):

return image.swapaxes(0,1),out
Run Code Online (Sandbox Code Playgroud)


Mik*_*l V 1

每个库都有自己的解释图像数组的方式。我想你所说的“旋转”是指转置。这就是 PyGame 显示 numpy 数组的方式。有很多方法可以让它看起来“正确”。实际上,甚至有很多方法可以显示数组,这使您可以完全控制通道表示等。在 pygame 版本 1.9.2 中,这是我能实现的最快的数组渲染。(请注意,对于早期版本,这不起作用!)。该函数将用数组填充表面:

def put_array(surface, myarr):          # put array into surface
    bv = surface.get_view("0")
    bv.write(myarr.tostring())
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,请使用它,应该可以在任何地方工作:

# put array data into a pygame surface
def put_arr(surface, myarr):
    bv = surface.get_buffer()
    bv.write(myarr.tostring(), 0)
Run Code Online (Sandbox Code Playgroud)

您可能仍然没有得到您想要的,因此它被转置或交换了颜色通道。这个想法是,以适合该表面缓冲区的形式管理数组。要找出正确的通道顺序和轴顺序,请使用openCV库 (cv2.imread(filename))。使用openCV,您可以按照标准以BGR顺序打开图像,并且它有很多转换功能。如果我没记错的话,当直接写入表面缓冲区时,BGR 是 24 位表面的正确顺序,BGRA 是 32 位表面的正确顺序。因此,您可以尝试将使用此函数从文件中获取的图像数组放入屏幕上。

还有其他方法来绘制数组,例如这里是整套辅助函数http://www.pygame.org/docs/ref/surfarray.html
但我不建议使用它,因为表面不用于直接像素操作,你可能会迷失在参考文献中。小提示:要进行“信号测试”,请使用图片,如下所示。所以你会立即看到是否有问题,只需加载为数组并尝试渲染。

在此输入图像描述