Webcam : la relève

11/2014 : le cahier des charges est à peu près le même que la précédente webcam : filmer une mangeoire d'oiseau avec une image de meilleure qualité, une détection de mouvement accompagnée d'une IHM de visualisation un peu plus moderne. Le POE doit être conservé et pour augmenter la difficulté, le tout doit être dehors.
Gourmands

Le renouveau de la webcam est dans un Raspberry pi B+ avec sa caméra. J'ai opté pour un modèle avec un objectif de 12mm testé dans ce billet. Ce type de caméra possède la particularité d'avoir un objectif avec un pas de vis compatible CCTV (caméra de surveillance) ce qui offre une large gamme d'objectif interchangeable et donc pouvoir le changer si nécessaire.

Caméra avec objectif de 21 mm

La caméra embarque un capteur de 5 Mega Pixel. Elle peut prendre des photos avec une résolution de 2592×1944 et filmer en 1080p à 30fps.

Mon idée initiale est d'éloigner la caméra du Pi afin de la mettre dans un petit boitier comme mon installation précédente. Il me faut donc relier la webcam et le pi avec un câble plus long. La nappe reliant la camera au Raspberry est petite (15 cm) et rigide et les nappes les plus longues mesurent 30 cm max.

Nappe de la caméra de type FFC 15 broches

Il me faut donc relier la webcam et le Pi avec un câble plus long. Qu'à cela ne tienne, je vais donc m'en fabriquer une ! J'ai utilisé une nappe de câble souple de 2m de long au pas de 1,27 mm de type DIP.

Nappe de 2m au pas de 1,27 mm de type DIP

Le pas de la nappe d'origine est très fin, 0,7 mm de type FFC, j'ai utilisé des adaptateurs FFC ⇔ DIP sur lesquels je vais souder d'un côté la nappe et de l'autre l'adaptateur. Le connecteur FFC doit être soudé sur l'adaptateur.

Connecteur FFC et Adaptateur

Après quelques soudures, voici le premier connecteur assemblé :

Connecteur monté

L'assemblage consiste donc à relier la webcam avec sa nappe d'origine à l'adaptateur lui même relié à la longue nappe puis de repasser sur l'adaptateur pour se brancher sur le Raspberry Pi. Je craignais que la longueur de câble pose des problèmes de stabilité d'image mais ce n'est pas le cas. :whew: La caméra est bien reconnue et les images transmises sont parfaites.

Webcam avec le connecteur

 

Raspberry pi connecté

J'ai assemblé le tout dans un boîtier électrique étanche et découpé le couvercle pour y loger une ouverture avec une plaque de plexiglas transparente.

Webcam du Raspberry Pi dans une boîte électrique

J'ai voulu alors réduire la largeur de la nappe en séparant en 4 et dans le sens de la longueur les brins mais la webcam ne se synchronise plus :'( Je pense qu'il y a désormais trop d'interférences électromagnétiques; une hypothèse serait que l'alternance habituelle d'un fil faisant circuler un signal positif avec son voisin qui fait passer le signal contraire n'est plus conservée. Cela a pour conséquence que le signal reçu n'est plus aussi “propre” et la webcam décroche.

Pour pallier à cet échec, j'ai décidé de tout mettre dans une même boîte : Raspberry + webcam. J'ai déniché une petite maison d'oiseau de décoration trouvée dans une grande surface de jardinage. En l'adaptant, j'ai tout fait rentrer dedans.

Maison d'oiseau

J'ai arrangé une fenêtre sur la face centrale pour y loger la webcam du Raspberry pi à l'aide de ma Dremel. La webcam est fixée avec des vis à tête fraisée et des petites entretoises. Avec un morceau de plexiglas provenant d'une boîte de chocolat, j'ai fabriqué une petite vitre placée devant la webcam pour refermer la boîte 8-). La petite porte de devant a été fermée à l'aide d'un fond en bois de boîte de camembert découpée à la bonne taille.

J'ai également vernis la maison d'oiseau pour résister aux intempéries :rainbow: :rainning:.

Maison d'oiseau convertie en caméra de surveillance

Pour gagner de la place dans la petite maison d'oiseau, je n'utilise pas le connecteur d'alimentation Micro-USB du Raspberry. En remplacement, j'utilise les connecteurs 4 et 6 du port GPIO pour l'alimenter.

Le Raspberry intègre un régulateur de tension branché juste après le port Micro-USB. En l'alimentant directement par le port GPIO, cet étage de régulation est by-passé. Il faut donc être très vigilant sur la tension appliquée sur les pins au risque de le griller.

Pinout du Raspberry B+

La mangeoire a été déplacée dans le jardin et est plus éloignée de la maison : la longeur du câble entre le Raspberry et le serveur est désormais de 35m. J'ai adapté ma solution de POE mise en place pour le NSLU2 à l'aide d'injecteur passif.

Connecteur POE passif

Voici un schéma de l'assemblage final :

POE sur le Raspberry Pi

En reprenant les calculs de chute de tension, j'ai :

La résistance du conducteur est de : $$R=\frac{ρ*L}{S} \Rightarrow \frac{17 * 10^{-9} * 70}{0.327 * 10^{-6}}\approx3.7\,Ω$$

Le PI est donné pour consommer environ 5 W minimum, soit 1 A avec son alimentation de 5 V. La chute de tension est donc au minimum : $3.7*1=3.7\,V$. En l'alimentant directement avec son transformateur à l'extrémité du câble, il ne recevra que $5-3.7=1.3\,V$, il ne fonctionne pas avec si peu de courant. Il faut donc une tension d'entrée plus élevée.

Dans la solution précédente, le 12V était issu de l'alimentation de Popeye. Comme le Pi est dehors, en cas de problème d'étanchéité de son abri, un court-circuit peut se produire. Je ne veux pas que ce soit l'alimentation du serveur qui prenne un coup, je vais donc utiliser un bloc d'alimentation dédié. Le Pi consommant régulièrement plus de 1 A, il faut donc prévoir une alimentation conséquente, celles habituellement vendues avec les appareils hi-tech sont trop justes.

J'ai finalement opté pour un adaptateur secteur multi tension de 24W environ et j'ai sélectionné une tension de 12V. En réglant le régulateur de tension de sortie LM2596 mis en oeuvre pour le NSLU2, j'obtiens 5V parfaitement stable.

Régulateur LM2596

Le réglage de ce régulateur s'effectue à l'aide d'un potentiomètre, d'abord à vide puis en branchant le pi afin de charger l'alimentation.

Réglage de la tension

Ensuite, yapluka© faire l'assemblage final, fixer le tout près de la mangeoire et régler l'objectif de la webcam pour avoir une image nette.

Le plus dur a été de tout faire rentrer dedans sans abimer le matériel : le Raspberry, l'adaptateur POE, la webcam et le régulateur d'alimentation.

Raspberry Pi dans sa petite maison

Le lecteur attentif aura remarqué que je n'ai rien décrit par rapport à l'étanchéité de l'ensemble : je n'ai en effet rien fait de spécial, le toit de la mangeoire protège bien de l'eau et n'empêche pas l'air de circuler afin d'éviter les phénomènes de condensation. Cela fait maintenant plus d'un an que l'ensemble est dehors de tout temps et je n'ai aucun dysfonctionnement à signaler !

Je les ai fixés sur le haut d'une claustrat avec une grosse équerre.

Gros plan sur la maison d'oiseau avec le Raspberry Pi

L'ensemble fini est plutôt propre et le WAF est à un niveau très acceptable ;).

Vue de l'ensemble : webcam avec le Raspberry pi et la mangeoire

Je veux filmer la mangeoire d'oiseau 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 3 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;
  • go-gallery : gallery web de visualisation de photos très simple

Capture vidéo

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

Il est important d'inspecter les logs 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.

L'installation sur le système est fait avec :

$ sudo make install

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, port 9000, l'IHM ressemble à cela :

IHM de mjpg-streamer

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

Voici le fichier de configuration complet.

Utilisation

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 ! 8-)

Quelques photos de la webcam. Les oiseaux les plus fréquents sont des moineaux, tourterelles, pies, rouge-gorges…