Pygame,从2d numpy数组创建灰度

时间:2016-11-23 04:22:54

标签: python python-3.x numpy pygame

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)期间。所以我想把它转换成灰度。

非常感谢。

4 个答案:

答案 0 :(得分:1)

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()

enter image description here

答案 1 :(得分:0)

pygame有两种方法可以将整数识别为颜色:

  1. RGB的3元素序列,其中每个元素的范围在0-255之间。
  2. 映射的整数值。
  3. 如果您希望能够拥有一个数组,其中0-255之间的每个整数代表一个灰色阴影,您可以使用此信息创建自己的灰度数组。您可以通过定义类来创建自己的数组。

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

    public static Bitmap StringToBitMap(String input) {
        byte[] decodedByte = Base64.decode(input, 0);
        return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
    }
    

    基于映射的整数值创建一个类可能有点抽象。我不知道这些值是如何映射的,但通过快速测试,可以很容易地确定每个灰色阴影的分隔值为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处的黑色开始。

    0

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

    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)
    

答案 2 :(得分:0)

从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帧...

答案 3 :(得分:0)

对于灰度图像,必须使用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')

以下函数将形状为( y x )的numpy.array转换为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()

另请参阅How do I convert an OpenCV (cv2) image (BGR and BGRA) to a pygame.Surface object