2ème article sur ma mangeoire d’oiseau filmée par un Raspberry Pi : je vous parle aujourd’hui de la mise en place logicielle pour être capable de diffuser la vidéo capturée par la caméra du Raspberry Pi sur le réseau local et ajouter de la détection de mouvement pour prendre des photos lorsque cela est nécessaire.
Remémorons nous le projet initial : je veux filmer une mangeoire d’oiseau avec un Raspberry Pi au milieu de mon jardin et prendre des photos lorsque des moineaux, mésanges, colombes… viennent picorer. Je ne souhaite pas non plus avoir un nombre très important d’images, donc la détection de mouvement doit être configurable.
Après quelques recherches et expérimentations, la solution est composée de 2 logiciels :
- mjpg-streamer : capture le flux vidéo de la webcam et permet via une interface web de consultation soit de prendre une photo instantanée soit de visionner le « live »;
- motion : lit le flux vidéo diffusé par mjpg-streamer et sauvegarde des photos en fonction des mouvements détectés.
Matériel
La caméra utilisée est un clone du modèle officiel avec en plus un objectif interchangeable de 22 mm compatible CCTV (caméra de surveillance) testée dans ce billet. Elle embarque un capteur de 5 Mega Pixel. Elle peut prendre des photos avec une résolution de 2592×1944 et filmer en 1080p à 30fps.
La première chose à faire est de vérifier que la caméra fonctionne bien à l’aide de l’outil raspistill :
$ raspistill -o $(date +"%Y-%m-%d_%H%M%S").jpg
A chaque exécution de la commande raspistill, une image sera sauvegardée dans le dossier courant avec un nom de la forme : 2017-03-19_122629.jpg.
Capture de mouvement
mjpg-streamer est le premier maillon de la chaîne : il s’occupe de capturer le flux vidéo pour le rendre accessible sur le réseau local via une interface web.
Il n’existe pas de paquet précompilé à l’heure actuelle, il faut le compiler, voici la procédure :
Installation des dépendances
Il faut installer quelques paquets au préalable :
$ sudo apt-get install libjpeg8-dev imagemagick libv4l-dev git
Récupération des sources et compilation
Plusieurs fork du projet initial mjpg-streamer existent dont un notamment qui inclus un driver pour la caméra de notre framboise préférée que nous allons cloner. Malheureusement, ce projet ne tag pas les sources ni n’effectue de release, donc la récupération des sources peut être périlleuse si elle s’opère en plein cœur d’un refactoring :’(
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
Cloning into 'mjpg-streamer'...
remote: Counting objects: 2579, done.
remote: Total 2579 (delta 0), reused 0 (delta 0), pack-reused 2578
Receiving objects: 100% (2579/2579), 3.41 MiB | 569 KiB/s, done.
Resolving deltas: 100% (1604/1604), done.
pour mémoire, la version que j’utilise est :
$ git rev-parse HEAD
3ed3f4cad86c4ad6e58bdc70a91c3cc3c949276a
Lancement de la compilation des sources :
$ cd mjpg-streamer/mjpg-streamer-experimental
$ make USE_LIBV4L2=true clean all
$ sudo make install
Il est important d’inspecter les logs de la première commande make pour vérifier les plugins compilés :
-- The following features have been enabled:
* PLUGIN_INPUT_FILE , File input plugin
* PLUGIN_INPUT_HTTP , HTTP input proxy plugin
* PLUGIN_INPUT_RASPICAM , Raspberry Pi input camera plugin
* PLUGIN_INPUT_UVC , Video 4 Linux input plugin
* PLUGIN_OUTPUT_FILE , File output plugin
* PLUGIN_OUTPUT_HTTP , HTTP server output plugin
* PLUGIN_OUTPUT_RTSP , RTSP output plugin
* PLUGIN_OUTPUT_UDP , UDP output stream plugin
Les plugins qui nous intéressent sont PLUGIN_INPUT_RASPICAM et PLUGIN_OUTPUT_HTTP
Lancement
Finalement exécuter la commande suivante :
$ LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_raspicam.so -fps 30 -q 75 -x 1920 -y 1080 -ex verylong" -o "output_http.so -p 9000 -w /usr/local/share/mjpg-streamer/www/"
MJPG Streamer Version.: 2.0
[...]
i: fps.............: 30
i: resolution........: 1920 x 1080
i: camera parameters..............:
Sharpness 0, Contrast 0, Brightness 50
Saturation 0, ISO 400, Video Stabilisation No, Exposure compensation 0
Exposure Mode 'verylong', AWB Mode 'auto', Image Effect 'none'
Metering Mode 'average', Colour Effect Enabled No with U = 128, V = 128
Rotation 0, hflip No, vflip No
o: www-folder-path...: /usr/local/share/mjpg-streamer/www/
o: HTTP TCP port.....: 9000
o: username:password.: disabled
o: commands..........: enabled
i: Starting Camera
[...]
DBG(/home/pi/mjpg-streamer/mjpg-streamer-experimental/plugins/input_raspicam/input_raspicam.c, worker_thread(), 880): Starting video output
Les options disponibles sont décrites sur le site web du projet :
- plugin raspicam : capture effectuée en 1080p à 30 fps
- plugin http : IHM web lancée sur le port 9000 et servant les fichiers statiques à partir du dossier /usr/local/share/mjpg-streamer/www/
Ouvrir un navigateur et le faire pointer sur l’ip du Raspberry Pi, port 9000, l’IHM ressemble à cela :
Le menu de gauche offre différentes vues :
- static : photo unique de la caméra, il faut rafraichir la page pour en avoir une nouvelle;
- stream : flux vidéo live de la caméra. mplayer, vlc savent lire la vidéo à l’url indiquée;
- java : lance une applet java pour lire la vidéo dans le navigateur;
- javascript : affiche une vidéo à l’aide d’un script javascript. La perception utilisateur est une vidéo mais n’est en réalité que la succession de photos prises et affichées très rapidement
Détection de mouvement
Motion est un programme qui surveille le signal vidéo d’une ou plusieurs caméras en détectant si une part significative de l’image a changé. Il sauvegarde les images dans un dossier prédéfini en fonction des événements détectés sur la caméra.
Installation
le paquet Debian armf est disponible dans les dépôts officiels :
$ sudo apt-get install motion
Configuration
La configuration par défaut nécessite un peu de paramétrage, notamment l’url du flux vidéo exposé par mjpg-streamer.
netcam_url http://localhost:9000/?action=stream
Les photos sont sauvegardées sur un partage NFS monté sur /mnt/media/webcam, il faut indiquer à motion où écrire :
target_dir /mnt/media/webcam/
Il est possible de spécifier un format de nom de fichier pour les photos prises lors de la détection d’un mouvement :
jpeg_filename %m-%d/%Y%m%d-%H.%M.%S
Les fichiers produits seront stockés dans un dossier <MOIS>-<JOUR> et le nom du fichier sera de la forme <ANNEE><MOIS><JOUR>-<HEURE>.<MINUTES>.<SECONDES>. Avec cette configuration, un dossier par jour sera créé contenant les photos de la journée. Cela va nous être vite utile car il y a entre 50 et 300 photos chaque jour. Motion créé tout seul le dossier spécifié dans le nom de fichier.
J’en profite pour mettre les logs dans le dossier racine :
logfile /mnt/media/webcam/log/motion-pi.log
La taille de l’image reçue est spécifiée :
width 1920
height 1080
La configuration ci dessous est empirique. Je l’ai mise au point en fonction des réactions de la webcam par rapport au soleil, aux mouvements des oiseaux et des ombres projetées etc…
L’idée est de ne pas produire 30 images par secondes à chaque mouvement sur la mangeoire, mais plutôt prendre une photo de temps en temps. La documentation est très détaillée et vaut le détour.
J’ai diminué le nombre d’image par seconde analysé (option framerate), augmenté le seuil de détection de mouvement (threshold, threshold_tune), augmenté le nombre d’images devant avoir du mouvement (minimum_motion_frames), affiné le vieillissement des pixels pour que motion ne détecte pas le mouvement des arbres ou l’ombre (despeckle)…
framerate 2
threshold 3500
threshold_tune on
despeckle EedDl
minimum_motion_frames 5
smart_mask_speed 1
Lancement de la détection de mouvement
Exécuter la commande pour démarrer motion :
$ sudo service motion start
Yapluka attendre que les oiseaux passent pour que les photos se déclenchent !