Skip to content Skip to sidebar Skip to footer

How To Iterate Through A Pygame 3d Surfarray And Change The Individual Color Of The Pixels If They're Less Than A Specific Value?

I'm trying to iterate a pygame 3d surfarray, more specifically pygame.surfarray.array3d('your image'). I'm receiving video captured from my webcam then converting them into a 3d ar

Solution 1:

Rather than iterating over the pixels in a list comprehension (which is bound to be slow in python) and then converting that list result into the desired numpy array, we can "vectorize" the problem using the magic of numpy. This is convenient here, since pygame.surfarray.array3d already returns a numpy array!

Here is a possible solution that takes an image (loaded from disk; I could not get your code to work since it relies on some linux directories like /dev/video0 for the webcam input and the espeak command, which is unavailable in Windows):

import numpy as np
import pygame
import sys

if __name__ == "__main__":
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    img = pygame.image.load("test.jpg").convert_alpha()
    clock = pygame.time.Clock()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        data = pygame.surfarray.array3d(img)
        mask = data[..., 2] < 200 #mark all super-NOT-blue pixels as True (select the OPPOSITE!)
        masked = data.copy() #make a copy of the original image data
        masked[mask] = [0, 0, 0] #set any of the True pixels to black (rgb: 0, 0, 0)
        out = pygame.surfarray.make_surface(masked) #convert the numpy array back to a surface
        screen.blit(out, (0, 0))
        pygame.display.update()
        print clock.get_fps()
        clock.tick(60)

On my computer, this runs at ~30 fps, which, while not great, should be a significant improvement! The slowness here appears to be due to masked[mask] = [0, 0, 0] in particular. If any numpy experts could chime in, that would be terrific! Otherwise, I can chime in with an additional cython answer instead (where adding type data should significantly improve loop performance).

Solution 2:

I'm not sure if it works, but please try it

outArr = np.array( [[w if w[2] > 200else np.zeros(3) forwin h] forhinself.imageArr], dtype='uint8')

The idea is that the three dimensional array has three indices, the first describing the position's height, the second its width and the last the color of a pixel. So a list comprehension of the color lists is made where the third entry of each, corresponding to blue, is compared if its greater than 200. If this is not the case, all color values are reset.

Post a Comment for "How To Iterate Through A Pygame 3d Surfarray And Change The Individual Color Of The Pixels If They're Less Than A Specific Value?"