Picamera (version 1.9) : comment piloter la caméra du Raspberry Pi en Python • Domotique et objets connectés à faire soi-même

9f4aiggczfoemr46mzby-5864261
xq34u0sbundsiodonryh-3785561
fplsb6kaje4yzql8s7z0-4325119

Depuis sa sortie, la librairie Picamera qui permet de piloter et d’exploiter la caméra du Raspberry Pi a pas mal évoluée. Dans cet article, nous allons voir les changements introduits dans la version 1.8 ainsi que les nouveautés de la version 1.9 (si vous avez besoin, la documentation officielle se trouve ici). Pour ceux qui prennent le train en marche et qui découvrent le Raspberry Pi, nous allons commencer par un petit rappel des étapes à suivre pour activer la caméra sur la distribution Raspbian.

Quelle caméra choisir pour son Raspberry Pi ?

Avant de rentrer dans le vif du sujet, voici un petit rappel sur les caméras disponibles pour le Raspberry Pi. La version 2 actuelle est disponible en deux versions.

La première désignée v2.1 est une caméra couleur classique basée sur un capteur de type CMOS 8MP (les pixels ne débordent pas sur les voisins en cas de saturation).

La seconde caméra désignée v2.1 NoIR est équipée d’un capteur sur lequel le filtre Infra Rouge n’a pas été installé. La caméra est plus sensible lorsqu’il y a peu de lumière.

Attention, certaines dénominations sont trompeuses, ce n’est pas une caméra à vision nocturne. Dans le noir complet, le capteur sera totalement aveugle. Par contre en ajoutant une lumière complémentaire (2 ou 3 Led infra-rouge), le capteur est (vraiment) très performant. Dans le noir complet, vous pouvez espérer voir à 10m, ce qui est suffisant pour fabriquer une caméra de surveillance 100% DIY. Pour en savoir plus, vous pouvez lire ce comparatif détaillé.

Parallèlement aux produits officiels Raspberry, de nombreux fabricants (principalement chinois) commercialisent des caméras compatibles. Bien souvent les performances sont inférieures mais le budget aussi.

Voici une petite synthèse des principales caractéristiques techniques.

(1) La désignation NoIR signifie que la caméra n’est pas équipée de filtre infrarouge. C’est à dire qu’elle dispose d’une bien meilleure sensibilité par faible luminosité. Cette sensibilité peut être améliorée avec un éclairage à Led additionnel. Un éclairage additionnel est même obligatoire en extérieur ou en pleine nuit. Ce ne sont pas des caméras à vision nocturne. En contrepartie, l’image est beaucoup moins colorée. Ce type de caméra est surtout destiné à faire de la vidéosurveillance.

Quelle caméra pour le Raspberry Pi Zero W ?

Le Raspberry Pi Zero W tout comme la révision 1.3 dispose d’un connecteur caméra. Oui, mais il est plus petit que celui du Raspberry Pi. Il est tout à fait possible d’utiliser une caméra v2.1 ou v2.1 NoIR en remplaçant la nappe souple par une nappe compatible (aussi appelé camera ribbon).

Si vous avez déjà une caméra, vous pouvez en acheter sur Amazon pour environ 8€. En direct d’Asie, on en trouve pour environ 2€.

3elfeqxymhv8ddaekzq2-8845905

Connecter la caméra au Raspberry

Le Raspberry Pi dispose d’un connecteur CSI dédié à communiquer avec les caméras compatibles. Le connecteur CSI se trouve juste à coté de la sortie vidéo HDMI. Avant de connecter la caméra au Raspberry, arrêtez Raspbian et débranchez la carte.

Soulevez le connecteur

iwlz1xwyaotws1gigut1-7269833

Il n’y a pas de d’indicateur de sens sur le ruban. Insérez le ruban en plaçant les pistes en direction du connecteur HDMI.

Refermez le connecteur. On le verrouille en le descendant à fond vers le bas. Il n’y a pas de “clic” qui confirme la fermeture du connecteur. Tirez légèrement pour vous assurer que le ruban est en place et correctement maintenu. Vous l’avez compris, ce n’est pas un montage mécanique à toute épreuve. Il ne faut pas d’action mécanique trop intense sur le ruban sous peine de débrancher la caméra.

Activer le module caméra sur Raspbian

Avant de pouvoir utiliser le module caméra, il est nécessaire de l’activer. Ouvrez le Menu puis Préférences et enfin ouvrez le panneau de Configuration du Raspberry Pi. Allez à l’onglet Interfaces puis activez le module caméra.

Si vous utilisez le Raspberry Pi uniquement en ligne de commande ou depuis une connexion externe SSH, vous pouvez également accéder à raspi-config avec la commande sudo raspi-config. Allez au menu 6 (Enable Camera) et répondez par Yes.

Dans tous les cas, vous devrez redémarrer pour prendre en compte le nouveau réglage.

Installation de la librairie Picamera

La librairie Picamera fait partie des paquets de base de la distribution Raspbian. Toutefois, ça ne coute rien de vérifier que tous les paquets nécessaires sont bien présents sur votre système. Exécutez la commande dpkg-query -l ‘picamera‘ qui permet d’énumérer les paquets qui contiennent la chaîne de caractères picamera. Vous devriez avoir les 3 paquets suivants d’installés sur votre système.

dpkg-query -l '*picamera*'
Souhait=inconnU/Installé/suppRimé/Purgé/H=à garder
| État=Non/Installé/fichier-Config/dépaqUeté/échec-conFig/H=semi-installé/W=attend-traitement-déclenchements
|/ Err?=(aucune)/besoin Réinstallation (État,Err: majuscule=mauvais)
||/ Nom                               Version               Architecture          Description
+++-=================================-=====================-=====================-========================================================================
ii  python-picamera                   1.12                  armhf                 Pure Python interface to the Raspberry Pi's camera module.
un  python-picamera-docs                                          (aucune description n'est disponible)
ii  python3-picamera                  1.12                  armhf                 Pure Python interface to the Raspberry Pi's camera module.

Si ce n’est pas le cas, commencez par les installer

sudo apt-get install python-picamera python3-picamera

Profitez en pour mettre à votre votre système

sudo apt-get update
sudo apt-get upgrade
sudo reboot 

Mise à jour du firmware du Raspberry Pi

Attention. Il est préférable de faire une copie de sauvegarde de la carte SD avant de mettre à jour le firmware. Suivez ce guide si nécessaire.

Autre point à vérifier, le firmware du Raspberry (dépôt GitHub). Avant de mettre à jour le firmware, vous pouvez vérifier le numéro de version de ce dernier avec la commande uname -a

$ uname -a
Linux raspberrypi 4.4.26-v7+ #915 SMP Thu Oct 20 17:08:44 BST 2016 armv7l GNU/Linux

Le numéro de révision se trouve à coté de #. Ici c’est la 915.

Ensuite, exécutez la commande rpi-update pour mettre à jour le firmware. L’opération dure quelques minutes

$ sudo rpi-update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
 *** Performing self-update
 *** Relaunching after update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
 *** We're running for the first time
 *** Backing up files (this will take a few minutes)
 *** Remove old firmware backup
 *** Backing up firmware
 *** Remove old modules backup
 *** Backing up modules 4.4.26-v7+
This update bumps to rpi-4.4.y linux tree
Be aware there could be compatibility issues with some drivers
Discussion here:
https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=144087
##############################################################
 *** Downloading specific firmware revision (this will take a few minutes)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   168    0   168    0     0     58      0 --:--:--  0:00:02 --:--:--    58
100 51.8M  100 51.8M    0     0   262k      0  0:03:22  0:03:22 --:--:-- 1452k^N
 *** Updating firmware
 *** Updating kernel modules
 *** depmod 4.4.37-v7+
 *** depmod 4.4.37+
 *** Updating VideoCore libraries
 *** Using HardFP libraries
 *** Updating SDK
 *** Running ldconfig
 *** Storing current firmware revision
 *** Deleting downloaded files
 *** Syncing changes to disk
 *** If no errors appeared, your firmware was successfully updated to df7fffc29d6f0e561f324699d0018756a0d0afbc
 *** A reboot is needed to activate the new firmware

Enfin, redémarrez le Raspberry

sudo reboot 

Après la mise à jour, le firmware est passé à la révision #936.

$ uname -a
Linux raspberrypi 4.4.37-v7+ #936 SMP Fri Dec 9 16:56:49 GMT 2016 armv7l GNU/Linux

Fonctions dépréciées depuis la version 1.8

Depuis la version 1.8 de la librairie piCamera, ne nombreux changements ont été opérés. Ces fonctions seront définitivement retirées de la librairie à partir de la version 2.0. Pour le moment, tous les codes existants peuvent fonctionner. Les développeurs ont clarifiés l’écriture de nombreuses fonctions.

Il est possible d’ajouter un marqueur dans votre code pour repérer plus facilement les fonctions dépréciées. Pour cela ajoutez ce morceau de code à vos projets :

import warnings
warnings.filterwarnings('default', category=DeprecationWarning)

Par exemple si vous exécutez le code suivant (tiré de la documentation officielle)

import io
import time
import picamera

import warnings
warnings.filterwarnings('error', category=DeprecationWarning)

with picamera.PiCamera() as camera:
    camera.resolution = (1280, 720)
    camera.framerate = (24, 1)
    camera.start_preview()
    camera.preview_fullscreen = True
    camera.preview_alpha = 128
    time.sleep(2)
    camera.raw_format = 'yuv'
    stream = io.BytesIO()
    camera.capture(stream, 'raw', use_video_port=True)

vous obtiendrez les messages suivants :

python livepreview.py 
/usr/lib/python2.7/dist-packages/picamera/mmalobj.py:297: PiCameraDeprecated: Setting framerate or gains as a tuple is deprecated; please use one of Python's many numeric classes like int, float, Decimal, or Fraction instead
  "Setting framerate or gains as a tuple is "
/usr/lib/python2.7/dist-packages/picamera/camera.py:3396: PiCameraDeprecated: PiCamera.preview_fullscreen is deprecated; use PiCamera.preview.fullscreen instead
  'PiCamera.preview_fullscreen is deprecated; '
/usr/lib/python2.7/dist-packages/picamera/camera.py:3340: PiCameraDeprecated: PiCamera.preview_alpha is deprecated; use PiCamera.preview.alpha instead
  'PiCamera.preview_alpha is deprecated; use '
/usr/lib/python2.7/dist-packages/picamera/camera.py:1854: PiCameraDeprecated: PiCamera.raw_format is deprecated; use required format directly with capture methods instead
  'PiCamera.raw_format is deprecated; use required format '
/usr/lib/python2.7/dist-packages/picamera/camera.py:1365: PiCameraDeprecated: The "raw" format option is deprecated; specify the required format directly instead ("yuv", "rgb", etc.)
  'The "raw" format option is deprecated; specify the '
/usr/lib/python2.7/dist-packages/picamera/camera.py:1848: PiCameraDeprecated: PiCamera.raw_format is deprecated; use required format directly with capture methods instead
  'PiCamera.raw_format is deprecated; use required format '

Fonction camera.capture

Le format de capture devait être définit dans une variable raw_capture puis ensuite appelé

Ancienne syntaxe

camera.raw_format = 'rgb'
camera.capture('output.data', format='raw')

Nouvelle syntaxe

Maintenant, on passe directement le paramètre souhaité directement dans l’option format comme ceci.

camera.capture('output.data', format='rgb')

Qualité d’enregistrement : le paramètre quantization devient quality

La drôle de dénomination quantization est abandonnée au profit tu terme quality beaucoup plus clair.

camera.start_recording('foo.h264', quantization=25)

Devient

camera.start_recording('foo.h264', quality=25)

Nombres fractionnaires

Auparavant, il était nécessaire de passer les nombre fractionnaire (très employé pour des ratios d’image) sous la forme (numérateur , dénominateur). Depuis la version 1.8, la librairie piCamera supporte les types Python int, float, Decimal, et fraction. Par exemple, pour indiquer le framerate, on peut faire comme ceci maintenant

camera.framerate = Fraction(72, 3)
camera.framerate = Decimal('24')
camera.framerate = Fraction('48/2')

Prévisualisation : fonction preview

Il est possible d’avoir plusieurs couches overlay. Pour cela, la fonction preview a été séparée de la librairie. Les attributs preview_alpha, preview_fullscreen et preview_window sont maintenant des méthodes de la fonction preview.

Ancienne syntaxe

camera.start_preview()
camera.preview_alpha = 128
camera.preview_fullscreen = False
camera.preview_window = (0, 0, 640, 480)

Nouvelle syntaxe

camera.start_preview()
camera.preview.alpha = 128
camera.preview.fullscreen = False
camera.preview.window = (0, 0, 640, 480)

Encore plus facile, on peut maintenant passer tous les paramètres au moment de l’appel de la fonction preview comme ceci

camera.start_preview(alpha=128, fullscreen=False, window=(0, 0, 640, 480))

Enfin, l’attribut previewing est maintenant obsolète. Pour tester si la caméra est déjà démarrée, on doit faire ainsi maintenant

if camera.preview: print('The camera preview is running')
else: print('The camera preview is not running')

Zoom remplace crop

La fonction crop pouvait porter à confusion car il pouvait laisser penser que cette fonction permettait de découper l’image alors qu’il n’en était rien. La sémantique est corrigée.

Ancienne syntaxe

camera.crop = (0.25, 0.25, 0.5, 0.5)

Nouvelle syntaxe

camera.zoom = (0.25, 0.25, 0.5, 0.5)

Nouveautés de la version 1.9

La version 1.9 est surtout est version qui corrige plusieurs bugs et introduit quelques nouvelle fonctions :

  • La paramètre sensor_mode permet de forcer le réglage de la caméra durant la phase d’initialisation (#165)
  • La vitesse de rafraichissement ainsi que la résolution de la caméra peuvent être spécifiés comme arguments à l’initialisation ce qui permet de réduire le temps d’initialisation (#180)
  • Prise en charge de still_stats  de raspstill  (#166)
  • Correction de l’attribut led  qui devrait maintenant fonctionner sur le modèle Raspberry Pi B+(#170)
  • Correction d’une fuite mémoire dans le moteur de rendu qui pouvait apparaître après la création / destruction répétée d’une couche d’overlay (#174)
  • Correction d’un bug lors de l’enregistrement d’une séquence MPEG lorsque la résolution était supérieure au VGA (#47 and #179).
  • Correction d’un bug sur les metadata de la fonction PiCameraCircularIO. La compatibilité ascendante n’est plus assurée, il faudra reprendre tous les codes existants en suivants les nouvelles spécifications des attributs (#177)
  • Autres bugs corrigés #176#167, #168, #171, #172, #182

Exemple : affichage en live de l’image de la caméra avec prise de cliché au clavier

La distribution Raspbian est livrée sans aucun utilitaire par défaut pour visualiser directement l’image produite par le module caméra. Ce n’est pas grave, c’est l’occasion de montrer comment mettre en oeuvre la librairie Picamera pour interagir avec le module caméra. Disposer d’un affichage en direct, permet de régler facilement la mise au point de l’optique sans devoir enregistrer une longue vidéo.

Voici donc un petit programme Python qui réalise les opérations suivantes :

  • Affichage en direct de la caméra en plein écran
  • Fonctions au clavier (à l’aide de la librairie Pygame)
    • Barre d’espace : enregistrer un cliché. L’image est enregistrée dans le même répertoire que le programme Python. Un compteur s’incrémente à chaque cliché. Attention, le compteur est réinitialisé à chaque démarrage du programme.
    • Enter/Return : enregistre un clip vidéo de 10 secondes. Il est possible de modifier la durée dans la fonction take_video
    • Echap : quitter le programme

Pour récupérer les événements du clavier (on peut aussi récupérer les événements de la souris, d’un écran tactile…), nous allons utiliser la librairie Pygame qui est dédiée à la création de jeux en Python. Commencez par installer la librairie Pygame sur votre environnement.

pip install pygame

Placez vous dans le dossier /home/pi/Documents par exemple et ouvrez l’éditeur de texte en nommant le fichier (par exemple livecamera.py). Collez le code ci-dessous.

import io, time, os, sys, picamera, pygame

# Display warning for deprecated Picamera functions (since v1.8) / affiche alerte si une fonction depreciee est utilisee 
import warnings
warnings.filterwarnings('default', category=DeprecationWarning)

pics_taken = 0
vid_taken = 0

# Init pygame and screen / initialise pygame et ecran
pygame.init()
res = pygame.display.list_modes() # return the resolution of your monitor / resolution du moniteur
width, height = res[0] # In case of trouble, set manually the resolution with: width, height = 1650, 1050
print "Screen resolution :", width, "x", height
screen = pygame.display.set_mode([width, height])
pygame.display.toggle_fullscreen()
pygame.mouse.set_visible = False

# Picamera object / objet Picamera
camera = picamera.PiCamera()
#camera.resolution = (1280, 720)
camera.framerate = float(24)

# Define functions / fonctions
def take_pic():
    global pics_taken
    pics_taken += 1
    camera.capture('image_' + str(pics_taken) + '.jpg')

def take_video() :
    global vid_taken
    vid_taken += 1
    camera.start_recording('video_' + str(vid_taken) + '.h264')
    #Recording duration / duree enregistrement (15s)
    camera.wait_recording(15)
    camera.stop_recording()

def quit_app():
    camera.close()
    pygame.quit()
    print "You've taken", pics_taken, " pictures ", vid_taken, " videos. Don't forget to back them up (or they'll be overwritten next time)"
    sys.exit(0)

#Start camera preview / Demarre affichage en direct
camera.start_preview()

while(True):
  pygame.display.update()
  for event in pygame.event.get():
      if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_ESCAPE:
          quit_app()
        elif event.key == pygame.K_SPACE:
          take_pic()
        elif event.key == pygame.K_RETURN:
          take_video()
        elif event.key == pygame.K_TAB:
           camera.start_preview()

Avez-vous aimé cet article ?