繁体   English   中英

Pygame,从二维 numpy 数组创建灰度

[英]Pygame, create grayscale from 2d numpy array

Python 3.4,pygame==1.9.2b8

我想绘制灰度框架。 现在,下面的代码生成蓝色,但我想在 (0,255) 范围内生成颜色,其中 0 - 黑色。 255 - 白色。 怎么可能?!

import pygame 
import numpy as np
s = 300
screen = pygame.display.set_mode((s, s))
screenarray = np.zeros((s,s))
screenarray.fill(200)
pygame.surfarray.blit_array(screen, screenarray)
pygame.display.flip()
input()
  • 事实上,我有更复杂的screenarray ,其中每个元素位于 (0,65535) 期间。 所以我想将它转换为灰度。

非常感谢。

pygame 可以通过两种方式将整数识别为颜色:

  1. RGB 的 3 元素序列,其中每个元素的范围在 0-255 之间。
  2. 映射的整数值。

如果您希望能够拥有一个数组,其中 0-255 之间的每个整数代表一个灰色阴影,您可以使用此信息创建自己的灰度数组。 您可以通过定义一个类来创建自己的数组。


第一种方法是创建一个 numpy 数组,每个元素都是一个 3 元素序列。

class GreyArray(object):

    def __init__(self, size, value=0):
        self.array = np.zeros((size[0], size[1], 3), dtype=np.uint8)
        self.array.fill(value)

    def fill(self, value):
        if 0 <= value <= 255:
            self.array.fill(value)

    def render(self, surface):
        pygame.surfarray.blit_array(surface, self.array)

基于映射的整数值创建一个类可能有点抽象。 我不知道这些值是如何映射的,但是通过快速测试,很容易确定每个灰色阴影都以16843008的值16843008 ,从黑色开始0

class GreyArray(object):

    def __init__(self, size, value=0):
        self.array = np.zeros(size, dtype=np.uint32)
        self.array.fill(value)

    def fill(self, value):
        if 0 <= value <= 255:
            self.array.fill(value * 16843008)  # 16843008 is the step between every shade of gray.

    def render(self, surface):
        pygame.surfarray.blit_array(surface, self.array)

简短的演示。 按 1-6 更改灰色阴影。

import pygame
import numpy as np
pygame.init()

s = 300
screen = pygame.display.set_mode((s, s))

# Put one of the class definitions here!

screen_array = GreyArray(size=(s, s))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_1:
                screen_array.fill(0)
            elif event.key == pygame.K_2:
                screen_array.fill(51)
            elif event.key == pygame.K_3:
                screen_array.fill(102)
            elif event.key == pygame.K_4:
                screen_array.fill(153)
            elif event.key == pygame.K_5:
                screen_array.fill(204)
            elif event.key == pygame.K_6:
                screen_array.fill(255)

    screen_array.render(screen)
    pygame.display.update()

PyGame 使用 24 位颜色作为三个字节 (R,G,B) 所以白色是 (0,0,0) 黑色是 (255,255,255)

import pygame 
import numpy as np

SIZE = 256

pygame.init()
screen = pygame.display.set_mode((SIZE, SIZE))

screenarray = np.zeros((SIZE, SIZE, 3))

for x in range(SIZE):
    screenarray[x].fill(x)

pygame.surfarray.blit_array(screen, screenarray)

pygame.display.flip()

input()

pygame.quit()

在此处输入图片说明

从 python 3.6 开始,我得到了以下结果:

display = pygame.display.set_mode((width, height))
frame = np.array(framebuf.getData(), copy=False, dtype=np.uint8).reshape((height, width, 1))
screenarray = np.repeat(frame, 3, axis = 2).swapaxes(0, 1)
pygame.surfarray.blit_array(display, screenarray)
pygame.display.flip()

在这个片段中, frame 是一个 numpy 数组,用来自framebuf.getData()的列表初始化。 因此,它可以是任何灰度位图,而不仅仅是此处其他示例中的常量或渐变。 我们将数组重塑为目标显示尺寸。 现在我们部署numpy.repeat将每个灰度字节复制到另外两个通道中。 最后,我们必须将swapaxes作为反转宽度和高度的最简单方法。 与 numpy 正交,pygame 期望具有宽度尺寸的 screenarray 首先出现,这使它看起来有点列(嗯,什么)?

总体而言,这在 640x480 下提供了约 80fps,这非常糟糕,但仍然比任何显式 Python 代码好得多。 我想最好的办法是在本机代码端准备 RGB 帧......

在灰度级图像的情况下,在阵列的形状必须进行转换numpy.reshape和灰度信道必须被扩展到使用红-绿和蓝色彩通道numpy.repeat

cv2Image = np.repeat(cv2Image.reshape(size[1], size[0], 1), 3, axis = 2)

pygame.Surface可以通过生成对象pygame.image.frombuffer

surface = pygame.image.frombuffer(cv2Image.flatten(), size, 'RGB')

下面的函数转换numpy.array具有形状(Y,X),以一个pygame.Surface对象:

import numpy as np
def numpyGrayscaleToSurface(numpyArray):
    size = numpyArray.shape[1::-1]
    numpyArray= np.repeat(numpyArray.reshape(size[1], size[0], 1), 3, axis = 2)
    surface = pygame.image.frombuffer(numpyArray.flatten(), size, 'RGB')
    return surface.convert()

另请参阅如何将 OpenCV (cv2) 图像(BGR 和 BGRA)转换为 pygame.Surface 对象

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM