Dans l’article précédent, nous avons fini d’assembler le Mark I. Pour résumer :
- une coque ColorCross avec ses lentilles
- 2 écrans SPI 2.8″ 320*240 montés à la verticale qui affichent le bureau X en mode clone
- une webcam PS3 Eye qui peut capturer en 640×480@30fps ou en 320×240@60fps, et qui dispose d’une série de 4 micros mono qui peuvent servir à faire du positionnement audio
- un Raspberry Pi-1 B pour piloter le tout
Le script pygame camera pass-through
Nous allons donc avoir besoin d’un programme pour capturer le flux de la caméra et l’afficher sur les 2 écrans clonés. Je vais utiliser un script Pygame, très simple dans un premier temps. Je me suis basé sur le tuto officiel pygame.camera.
camera.py
#! /usr/bin/env python # -*- coding: utf-8 -*- import pygame import pygame.camera from pygame.locals import * import os os.environ["SDL_FBDEV"] = "/dev/fb1" clock = pygame.time.Clock() # video capture size capturesize = (320,240) # screen size screensize = (240, 320) # create a display surface. standard pygame stuff display = pygame.display.set_mode(screensize, HWSURFACE|FULLSCREEN) pygame.init() pygame.mouse.set_visible(False) pygame.camera.init() # check cameras clist = pygame.camera.list_cameras() if not clist: raise ValueError("Sorry, no cameras detected.") # create camera cam = pygame.camera.Camera(clist[0], capturesize) fpsclock = pygame.time.Clock() font = pygame.font.Font(None, 20) cam.start() # create a surface to capture to. snapshot = cam.get_image() going = True while going: events = pygame.event.get() for e in events: if e.type == QUIT or (e.type == KEYDOWN and e.key == K_ESCAPE): # close the camera safely cam.stop() going = False # if you don't want to tie the framerate to the camera, you can check # if the camera has an image ready. note that while this works # on most cameras, some will never return true. if cam.query_image(): snapshot = cam.get_image() # blit it to the display surface. snapshot_x = screensize[0]/2 - snapshot.get_width()/2 snapshot_y = screensize[1]/2 - snapshot.get_height()/2 display.blit(snapshot, (snapshot_x, snapshot_y)) fpsclock.tick() fps = fpsclock.get_fps() fps = "{0:.2f}".format(fps) text = "fps : "+str(fps) label = font.render(text, 1, (0, 255, 0)) display.blit(label, (50, 50)) pygame.display.flip()
Lancer le script en mode clone
Puisque le multi-affichage clone ne fonctionne pas sous la console, nous allons devoir passer par le gestionnaire de fenêtres X, qui lui supporte le multi-affichage. Seulement, pour des raisons de performance et d’efficacité, je ne veux pas lancer tout le bureau. Nous allons donc utilser une petite astuce qui nous permettra de lancer juste ce qui est nécessaire pour faire fonctionner Pygame dans X.
Avant tous, nous avons besoin de xterm :
sudo apt-get install xterm
Admettons que le dossier dans lequel on a mis le script camera.py est « /home/pi/scripts/« .
Créez un second script camera_launcher.sh, et collez-y ceci :
python /home/pi/scripts/camera.py
Maintenant, on peut peut lancer le tout via cette commande :
xinit /home/pi/scipts/camera_launcher.sh
Il est très important de bien indiquer les chemins complets des scripts !
Puisqu’on a activé le mode clone dans X, quand on lance le script avec cette méthode, la capture vidéo s’affiche donc synchronisée sur les 2 écrans.
J’ai fait le test avec 2 caméras usb (PS3 eye et Xbox360), j’atteins ~10-12 fps avec chacune d’entre elles. Ce n’est pas énorme, mais le script ne dit pas si la limite vient du framerate de la camera, de la bande passante usb, du traitement vidéo par le CPU, ou des performances du script Pygame…
Je creuserai cette question dans un prochain article…
2 réflexions au sujet de « OpenHMD – le casque VR do-it-yourself, Mark I : camera pass-through »