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

时间:2015-06-13 11:53:56

标签: python numpy pygame 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()

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

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

4 个答案:

答案 0 :(得分:2)

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

return image.swapaxes(0,1),out

答案 1 :(得分:1)

我的建议是使用pygame.transform模块。有fliprotate方法,您可以使用这些方法进行转换。查看有关此文档的文档。

我的建议是将输出图像保存到新的Surface,然后应用转换,然后将blit应用到显示器。

temp_surf = pygame.Surface((w,h))
pygame.surfarray.blit(temp_surf, scan)

'''transform temp_surf'''

screen.blit(temp_surf, (0,0))

我不知道为什么会这样。这可能与轴从2d数组转移到pygame Surface的顺序有关。

答案 2 :(得分:1)

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

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

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

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

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

还有其他方法来绘制数组,例如这里是整套辅助函数http://www.pygame.org/docs/ref/surfarray.html
但我不建议使用它,因为表面不是用于直接像素操作,你可能会迷失在引用中。 小提示:做'信号测试'使用图片,就像这样。因此,您将立即看到是否有错误,只需加载为数组并尝试渲染。

enter image description here

答案 3 :(得分:1)

我认为technico提供了一个很好的解决方案 - 只需要一点点信息。假设get_arr()是一个返回像素数组的函数:

pixl_arr = get_arr()
pixl_arr = numpy.swapaxes(pixl_arr, 0, 1)
new_surf = pygame.pixelcopy.make_surface(pixl_arr)
screen.blit(new_surf, (dest_x, dest_y))

或者,如果您知道图像将始终具有相同的尺寸(如在迭代视频或gif文件的帧中),则重用相同的表面会更有效:

pixl_arr = get_arr()
pixl_arr = numpy.swapaxes(pixl_arr, 0, 1)
pygame.pixelcopy.array_to_surface(old_surf, pixl_arr)
screen.blit(old_surf, (dest_x, dest_y))

YMMV,但到目前为止这对我来说效果很好。