Pygame,从二维 numpy 数组创建灰度
Pygame, create grayscale from 2d numpy array
Python3.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 使用 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()
有两种方法pygame可以将整数识别为颜色:
- RGB 的 3 元素序列,其中每个元素的范围在 0-255 之间。
- 映射的整数值。
如果您希望能够有一个数组,其中 0-255 之间的每个整数代表一种灰色阴影,您可以使用此信息创建自己的灰度数组。您可以通过定义 class.
来创建自己的数组
第一种方法是创建一个 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)
根据映射的整数值创建 class 可能有点抽象。我不知道这些值是如何映射的,但是通过快速测试很容易确定每个灰色阴影都用 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()
从 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 期望屏幕数组首先出现宽度维度,这使得它看起来有点按列(嗯,什么)?
总的来说,这在 640x480 下给出了大约 80fps,这非常糟糕,但仍然比任何显式 Python 代码要好得多。我想最好的办法是在本机代码端准备 RGB 帧...
对于灰度图像,必须使用 numpy.reshape
and the gray channel must be expanded to a red-green and blue color channel using 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
with shape (y, x) to a 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()
另见 。
Python3.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 使用 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()
有两种方法pygame可以将整数识别为颜色:
- RGB 的 3 元素序列,其中每个元素的范围在 0-255 之间。
- 映射的整数值。
如果您希望能够有一个数组,其中 0-255 之间的每个整数代表一种灰色阴影,您可以使用此信息创建自己的灰度数组。您可以通过定义 class.
来创建自己的数组第一种方法是创建一个 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)
根据映射的整数值创建 class 可能有点抽象。我不知道这些值是如何映射的,但是通过快速测试很容易确定每个灰色阴影都用 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()
从 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 期望屏幕数组首先出现宽度维度,这使得它看起来有点按列(嗯,什么)?
总的来说,这在 640x480 下给出了大约 80fps,这非常糟糕,但仍然比任何显式 Python 代码要好得多。我想最好的办法是在本机代码端准备 RGB 帧...
对于灰度图像,必须使用 numpy.reshape
and the gray channel must be expanded to a red-green and blue color channel using 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
with shape (y, x) to a 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()
另见