Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Pygame surface to opencv image object (not file saving)

I have a rectangle area on a pygame surface. I want to convert that area into opencv image object (without saving into a file) for further image processing on that rectangle area only. How can I do that?

selected_area =  mysurface.subsurface((x,y,w,h))
img_array=numpy.array(pygame.surfarray.array2d(selected_area))

#image_object = ..... ?

gray = cv2.cvtColor(image_object, cv2.COLOR_BGR2GRAY)
cv2.imshow("test",gray)

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Actually, a cv2 image is just a three-dimensional numpy array. the 1st dimension is the height, the 2nd the width and the 3rd the number of channels in the order blue, green, red.
Use pygame.surfarray.pixels3d to reference pixels into a 3d array:

img_array = numpy.array(pygame.surfarray.pixels3d(selected_area))

Unfortunately, this array is flat and the pixels are stored in row mayor order. The color channels are in the order red, green, blue. So you need to reformat this array. reshape the and transpose the array:

image_object = numpy.rollaxis(img_array.reshape((w, h, 3)), 1)

Finally swap the red and blue color channel:

image_object[:, :, [0, 2]] = image_object[:, :, [2, 0]]

Convert function:

def pygameSurfaceToCv2Image(mysurface, x, y, w, h):
    selected_area =  mysurface.subsurface((x, y, w, h))
    img_array = numpy.array(pygame.surfarray.pixels3d(selected_area))
    image_object = numpy.rollaxis(img_array.reshape((w, h, 3)), 1)
    image_object[:, :, [0, 2]] = image_object[:, :, [2, 0]]
    return image_object

Minimal example:

import pygame
import cv2, numpy

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

def pygameSurfaceToCv2Image(mysurface, x, y, w, h):
    selected_area =  mysurface.subsurface((x, y, w, h))
    img_array = numpy.array(pygame.surfarray.pixels3d(selected_area))
    image_object = numpy.transpose(img_array.reshape((w, h, 3)), (1, 0, 2))
    image_object[:, :, [0, 2]] = image_object[:, :, [2, 0]]
    return image_object

apple_surf = pygame.image.load("Apple1.bmp")
image_object = pygameSurfaceToCv2Image(apple_surf, 20, 20, 200, 120)
gray = cv2.cvtColor(image_object, cv2.COLOR_BGR2GRAY)
cv2.imshow("apple subsurface", image_object)
cv2.imshow("gray apple subsurface", gray)

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 

    window.fill(0)
    window.blit(image, image.get_rect(center = window.get_rect().center))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
exit()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading