python traitement de webcam

a marqué ce sujet comme résolu.

Bonjour,

J’essaye de faire du traitement en temps réel d’images venant d’une webcam. Pour ce faire, j’ai écrit le programme suivant :

import cv2
from PIL import Image
import pygame as pg
from itertools import product
from multiprocessing import Pool

class NoCameraError(Exception):
    pass

cam = cv2.VideoCapture(0)

def PIL_to_Surface(image):
    mode = image.mode
    size = image.size
    data = image.tobytes()
    return pg.image.fromstring(data, size, mode)

pg.init()

ret, image = cam.read()

done = False
w, h = 0, 0

if not ret:
    raise NoCameraError
image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB)

image = Image.fromarray(image)

w, h = image.width, image.height

screen = pg.display.set_mode((w,h))

pixels = tuple(product(range(w), range(h), repeat=1))

clock = pg.time.Clock()

def filter(pixel):
    global image
    r, g, b = image.getpixel(pixel)
    r *= 2

    if r > 255:
        r = 255

    image.putpixel(pixel,(r, g, b))

while not done:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            done = True
    screen.fill("white")

    last_image = image

    ret, image = cam.read()
    if not ret:
        raise NoCameraError
    print(type(image))
    #from cv2 to PIL
    image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB)
    image = Image.fromarray(image)

    w, h = image.width, image.height

    #PIL processes
    for pixel in pixels:
        filter(pixel)

    #pygame conversion
    surface = PIL_to_Surface(image)

    #pygame processes
    screen.blit(surface,(0,0))

    pg.display.update()

J’essaye pour l’instant d’appliquer un filtre rouge à l’image. En théorie, ça fonctionne, mais en pratique ça rame énormément (j’ai plusieurs secondes d’attente entre deux images successives). J’ai, à l’aide de quelques testes, déterminé que le problème venait des méthodes "getpixel" et "putpixel" de PIL, trop lentes, mais je ne vois pas comment les contourner.

Merci d’avance,

@flopy78

Bonjour,

J’ai essayé de traiter directement le tableau numpy au lieu de traiter l’image via PIL : ça ne change rien au niveau performance.

import cv2
from PIL import Image
import pygame as pg


class NoCameraError(Exception):
    pass

cam = cv2.VideoCapture(0)


def PIL_to_Surface(image):
    mode = image.mode
    size = image.size
    data = image.tobytes()
    return pg.image.fromstring(data, size, mode)

pg.init()

ret, image = cam.read()

done = False
w, h = 0, 0

if not ret:
    raise NoCameraError

image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB)

image = Image.fromarray(image)

w, h = image.width, image.height


screen = pg.display.set_mode((w,h))

clock = pg.time.Clock()

def filter(pixel):
    global image
    r, g, b = pixel
    r *= 2

    if r > 255:
        r = 255

    return (r, g, b)

while not done:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            done = True
    screen.fill("white")

    last_image = image

    ret, image = cam.read()

    frames.append(image)

    if not ret:
        raise NoCameraError
    #from cv2 to PIL
    #image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB)
    #image = Image.fromarray(image)

    w, h, *left = image.shape

    image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB)

    #PIL processes
    for x in range(w):
        for y in range(h):
            image[x][y] = filter(image[x][y])
            pass
    image = Image.fromarray(image)
    #pygame conversion
    surface = PIL_to_Surface(image)
    surface = pg.transform.flip(surface,True,False)

    #pygame processes
    screen.blit(surface,(0,0))

    clock.tick(200)

    pg.display.update()

A terme, mon objectif est d’observer l’évolution de la couleur des pixels pour détecter les mouvements.

Bonne journée,

@flopy78

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte