Dans ce tutoriel nous allons réaliser un time-lapse (vidéo accélérée) avec un Raspberry Pi Zero 2 W et le Module caméra v3 Raspberry Pi.
Configuration du Raspberry Pi 2 W
Installez le système d’exploitation Raspberry Pi OS sur une carte Micro-SD d’au moins 8 GB à l’aide de l’outil Raspberry Pi Imager.
Pour ce tutoriel j’ai utilisé la version Raspberry Pi OS (Legacy 32-bit) Lite sans application ni environnement desktop.
La version Lite sans environnement desktop est plus légère et suffisante pour les besoins de ce tutoriel dans lequel j’utilise le Raspberry Pi Zero 2 W sans écran au travers d’une connexion SSH en WiFi.
Note : Je rencontre des problèmes de durée de capture d’image lorsque j’utilise la version de Raspberry Pi OS basée sur Debian Bookworm. Aussi je recommande d’utiliser la version basée sur Debian Bullseye tant que le problème n’est pas résolu (voir plus loin).
Personnalisez l’OS en modifiant les réglages. Définissez un nom d’utilisateur et son mot de passe. Configurez la connexion WiFi en entrant le SSID (nom de votre réseau WiFi) et son mot de passe. Activez le SSH dans le menu services, il sera indispensable si vous n’avez pas de clavier/écran connecté au Raspberry Pi Zero 2 W.
Une fois que la carte micro SD est prête, insérez là dans le Raspberry Pi Zero 2 W et branchez l’alimentation USB. Une fois que le Raspberry Pi Zero 2 W a démarré (le premier démarrage est long), vous pouvez vous y connecter via une session SSH depuis votre ordinateur.
Une fois connecté en SSH sur le Raspberry Pi Zero 2 W, mettez l’OS à jour et installez la librairie picamera2 si elle n’est pas déjà installée :
sudo apt update
sudo apt upgrade
sudo apt install -y python3-picamera2
Installation du module caméra v3 Raspberry Pi
Le module caméra est livré avec une nappe (câble plat) conçue pour le Raspberry Pi, il faudra acquérir une nappe spécifique pour le Raspberry Pi Zero 2 W ou bien utiliser la nappe qui est incluse dans le boîtier officiel conçu pour la Raspberry Pi Zero 2 W (la caméra v3 n’est pas compatible avec ce boîtier).
Attention lorsque vous insérez la nappe, le côté avec les contacts dorés doit être positionnés du côté du circuit imprimé.
Installez la nappe entre le Raspberry Pi Zero 2 W et le module caméra :
- Tirez doucement le verrou du connecteur de la caméra (morceau noir) vers l’extérieur pour le débloquer
- Insérez la nappe dans le connecteur de la caméra
- Refermez le verrou, la nappe est maintenant maintenue dans le module caméra
- Répétez la même opération avec le connecteur du Raspberry Pi Zero 2 W.
Une fois que le module caméra est connecté au Raspberry Pi Zero 2 W et que la carte micro SD est en place, vous pouvez connecter le cordon d’alimentation sur le port micro USB de droite.
Capture d’images avec un programme Python
Pour réaliser la captures des différentes images qui composeront la vidéo time-lapse, nous allons utiliser la librairie Picamera2 et réaliser un programme en Python.
Le programme est relativement simple, il suffit de configurer et démarrer la caméra en mode fixe et image haute résolution, d’effectuer un cycle d’autofocus et ensuite de capturer les images avec un temps d’attente entre chaque image.
Le nombre d’images à capturer nb_pictures et l’intervalle entre deux captures interval doivent être passés en paramètre au programme. Si vous ne passez pas de paramètre au programme, les valeurs par défaut sont nb_pictures=500 et interval=5.
Les images sont stockées sous le nom “imageXXXXX.jpg” (XXXXX étant le numéro de la capture) sur la carte micro SD dans un répertoire nommé avec la date et l’heure du début de la capture.
#!/usr/bin/python3
import time, datetime
import libcamera
import signal
import os
import argparse
from picamera2 import Picamera2
# Create Picamera2 global object
picam2 = Picamera2()
# Ctrl-C signal handler to stop the camera before program exit
def handler(signum, frame):
print("Ctrl-c was pressed, stop camera and exit.")
picam2.stop()
exit(1)
# Configure the Ctrl-C signal handler
signal.signal(signal.SIGINT, handler)
def getArgs():
# Parse the arguments to get number of pictures and interval
parser = argparse.ArgumentParser(
description='Time-lapse')
parser.add_argument(
"--nb_pictures", help="Number of pictures in the time-lapse (default: 500)", default=500, type=int)
parser.add_argument("--interval", help="Interval between 2 pictures (default 5s)", default=5, type=int)
args = parser.parse_args()
return args
def config_camera():
# Configure the camera for high resolution still capture
picam2.configure(picam2.create_still_configuration())
picam2.start()
# Configure daylight white balance, disable automatic exposure and set framerate to 1 img/s
# Give time for default still configuration to settle
time.sleep(1)
picam2.set_controls({"AwbEnable": False, "AwbMode": libcamera.controls.AwbModeEnum.Cloudy.Daylight, "FrameRate": 1.0})
# And wait for those settings to take effect
time.sleep(1)
# Run autofocus cycle
success = picam2.autofocus_cycle(wait=False)
status = picam2.wait(success)
def capture_images(nb_pictures, wait_time):
# Create a folder based on current date and time to store images
now = datetime.datetime.now()
dir = "/home/pi/" + now.strftime("%m-%d-%Y-%H-%M-%S")+"/"
if not os.path.exists(dir):
os.makedirs(dir)
print("Pictures will be saved in directory {}".format(dir))
print("Starting to capture {} pictures at interval {} seconds".format(nb_pictures,wait_time))
# Start main loop to capture and save pictures
for i in range(0, nb_pictures):
filename = "image{:05d}.jpg".format(i)
time_before_capture = time.time()
r = picam2.capture_request()
r.save("main", dir+filename)
r.release()
current_time = time.time()
print("File {} saved at {}".format(filename, time.strftime("%H:%M:%S", time.localtime())))
capture_and_save_duration = current_time-time_before_capture
# Check the capture process duration is correct
if (capture_and_save_duration >= 2*wait_time):
print("Timing issue!")
picam2.stop()
exit(1)
time.sleep(wait_time-capture_and_save_duration)
picam2.stop()
def main():
args = getArgs()
config_camera()
#time.sleep(15)
capture_images(args.nb_pictures,args.interval)
if __name__ == '__main__':
main()
Si tout se déroule correctement, le programme va capturer 500 images, au rythme d’une image toutes les 5 secondes. Le programme affiche le nom de l’image qui vient d’être sauvegardée sur la carte micro SD ainsi que l’heure de la capture. L’affichage de l’heure permet de vérifier que l’intervalle entre chaque capture est bien configurée et stable tout au long de la capture.
Exécution automatique du programme au démarrage du Raspberry
Pour que la capture des images commence dès le démarrage du Raspberry Pi, vous pouvez ajouter un script et l’ajouter dans la table de planification linux (crontab).
Créer un script shell start.sh ayant le contenu suivant :
python3 /home/pi/timelapse.py
Créer un répertoire pour stocker les logs du programme :
mkdir /home/pi/logs
Il faut configurer le crontab pour qu’il exécute ce script au démarrage du Raspberry, pour cela éditer le crontab avec la commande suivante :
sudo crontab -e
Ajouter la ligne suivante en bas du fichier :
@reboot sh /home/pi/start.sh > /home/pi/logs/logs.txt 2>&1
Il est indispensable de rajouter une temporisation avant de commencer les captures d’images, en effet au boot la charge du Raspberry est importante et le temps entre 2 captures est plus élevée. Une temporisation de 30 secondes est souhaitable (ligne à décommenter dans le code).
Au prochain boot du Raspberry la capture des images devrait démarrer automatiquement.
Un problème dans la librairie picamera2 sur Raspberry Pi OS Bookworm ?
Mon programme affiche une alerte si le temps entre 2 captures est anormalement élevé (supérieur à 2 fois la variable wait_time). En effet, j’ai observé ce phénomène assez régulièrement lorsque j’utilisais Raspberry Pi OS Bookworm (la dernière version officielle de Raspberry Pi OS).
Dans ce cas, la fonction picam2.capture_request() prend un temps anormalement long a s’exécuter et le temps entre 2 captures est très long (>100 secondes). Ce qui nuit fortement à la qualité de la vidéo accélérée en créant un effet de saut (voir exemple ci-dessous).
Il s’agit d’un problème potentiel dans la libcamera2 sous Raspberry Pi OS Bookworm. Il est en cours d’investigation, à suivre…
Capture d’image avec la ligne de commande
Il est également possible de réaliser le time-lapse en ligne de commande, sans avoir à écrire de programme en Python.
Voici la ligne de commande équivalente au programme ci-dessus :
rpicam-still -t 2500sec --timelapse 5sec --hdr sensor --awb daylight --framestart 0 --autofocus-mode auto -o "image%05d.jpg" -v 0
Cette commande va effectuer un time-lapse d’une durée de 41 minutes (2500 secondes), capturant 500 image avec un intervalle de 5 secondes. Comme pour les programmes Python ci-dessus, les images seront stockées sur la carte micro SD sous le nom “image00000.jpg”, “image00001.jpg”… “image00099.jpg”.
Sur Raspberry Pi OS Bullseye, la commande suivante est équivalente :
libcamera-still -t 1000000 --timelapse 5000 --hdr --awb daylight --framestart 0 --autofocus-mode auto -o "image%05d.jpg" -v 0
Choix de l’intervalle de capture
Le temps d’attente entre chaque capture d’image dépend principalement de la scène que vous capturez et de la vitesse de déplacement des personnes ou des objets au sein de cette scène.
A titre d’exemple, voici quelques intervalles :
- 1 seconde pour la circulation de véhicules
- 2 secondes pour un lever ou coucher de soleil
- 5 secondes pour le mouvement des nuages
- 10 secondes pour le déplacement du soleil
- 60 secondes pour la croissance des plantes
- 300 secondes pour la construction d’un bâtiment
Balance des blancs et time-lapse
La balance des blancs est un réglage qui permet d’adapter la dominante de couleur à l’éclairage.
Je recommande de configurer manuellement la balance des blancs pour faire un time-lapse. En effet, les conditions lumineuses changes au cours de prises de vues longues et le changement de balance des blancs est visible et dommageable pour le rendu du time-lapse.
Il convient donc de configurer la balance des blancs manuellement en fonction de l’éclairage de la scène :
- Tungsten – tungsten lighting
- Fluorescent – fluorescent lighting
- Indoor – indoor illumination
- Daylight – daylight illumination
- Cloudy – cloudy illumination
- Custom – custom setting
Voici comment configurer manuellement la balance des blancs :
picam2.set_controls({"AwbEnable": False, "AwbMode": libcamera.controls.AwbModeEnum.Daylight})
Durée d’exposition et time-lapse
La durée d’exposition (aussi appelée temps de pose) est le temps pendant lequel l’obturateur de la caméra laisse passer la lumière lors d’une prise de vue, et donc la durée de l’exposition du capteur à la lumière.
En fonction de l’effet rechercher sur la vidéo, il peut être nécessaire de désactiver la durée d’exposition automatique.
Voici comment désactiver la configuration automatique de la durée d’exposition :
picam2.set_controls({"AeEnable": False})
Création de la vidéo accélérée avec FFmpeg
Nous allons utiliser le logiciel FFmpeg afin de créer une vidéo à partir des images capturées. Ce logiciel open source est extrêmement puissant et je vous le recommande vivement. La procédure d’installation est différente en fonction de votre système d’exploitation, mais la commande pour générer la vidéo est la même pour Linux (dans un terminal) et Windows (dans PowerShell).
Installation de FFmpeg sous Linux
Installez FFmpeg via le gestionnaire de paquet de votre distribution :
sudo apt install ffmpeg
Installation de FFmpeg sous Windows
Installez FFmpeg via winget dans un fenêtre PowerShell :
Création du time-lapse
Copiez les images depuis la carte micro SD vers un répertoire sur votre PC, et lancez la ligne de commande suivante dans ce répertoire (la commande est identique dans un terminal sous Linux et dans un PowerShell sous Windows) :
ffmpeg -framerate 24 -i image%05d.jpg my-timelapse.mp4
Vous obtiendrez un time-lapse de 24 images par seconde au format MP4 qui inclura toutes les images capturées par votre Raspberry Pi.
Voici quelques exemples de time-lapse à 24 images par seconde avec des images capturées toutes les 5 ou 10 secondes avec le module camera v3 Wide (grand angle) :
Taille de l’espace de SWAP sur le Raspberry Pi Zero 2 W
Le Pi Zero 2 W dispose de 512 Ko de mémoire. L’allocation par défaut de l’espace de swap est de 200 Mo, ce qui n’est pas suffisant dans certains cas, le Pi risque donc de passer en mode « swap thrashing »… On voit dans la capture ci-dessous que le SWAP est utilisé à 169M/200M lors de la capture des images par le programme Python du Time-lapse.
La solution consiste à augmenter l’espace de swap en éditant /etc/dphys-swapfile, en modifiant CONF_SWAPSIZE de 100 à 2048, en enregistrant et en redémarrant.
Conclusion
Le time-lapse offre une infinité de sujets intéressants, que ce soit l’éclosion de fleurs, la course des nuages, la circulation dans les grandes villes ou encore la chute des feuilles en automne… Pour chaque sujet il faudra déterminer le délai entre chaque capture ainsi que le nombre de captures totales.
Le Raspberry Pi Zero 2 W et le module caméra v3 offre une solution abordable au niveau prix, un faible encombrement et une excellente qualité d’image. Le fait de pouvoir prévisualiser et contrôler le Raspberry Pi Zero 2 W via une connexion Wifi est particulièrement appréciable. Il est par contre indispensable d’acquérir ou de réaliser un boîtier afin de maintenir la caméra stable lors de toute la durée de l’acquisition des images.
Vous trouverez plus d’informations sur le module camera v3 dans le test réalisé sur le site framboise314.fr. Voir également mon autre tuto sur la réalisation de time-lapse avec un ESP32S3 Sense.
Le matériel nécessaire à ce tutoriel est disponible chez Kubii.
J’espère que ce tuto vous aura intéressé. N’hésitez pas à donner votre avis en cliquant sur les étoiles ci-dessous. Je ne suis pas rémunéré au nombre d’étoiles mais c’est important pour moi afin de voir que mon travail est utile aux autres 🙂