IMA3/IMA4 2019/2021 P6+

De Wiki de Projets IMA
Révision datée du 21 juin 2021 à 14:55 par Ederisbo (discussion | contributions) (Semaine 4)


Présentation générale

Description

Un boitier Raspberry Pi et deux cameras permettent de monitorer le positionnement d'une fibre optique avec précision.

Objectifs

L'objectif de ce projet est de redévelopper une interface permettant de visualiser simultanément les images de deux caméras. L'interface de visualisation actuelle présente de nombreux défauts. Les deux caméras sont connectées à une Raspberry Pi grâce à un multiplexeur sur le bus CSI.

Préparation du projet

Cahier des charges

Choix techniques : matériel et logiciel

Multiplexeur de caméra : https://www.arducam.com/product/multi-camera-v2-1-adapter-raspberry-pi/ Dépôt git : https://github.com/ArduCAM/RaspberryPi/tree/master/Multi_Camera_Adapter/Multi_Adapter_Board_4Channel

Liste des tâches à effectuer

  • Installation de Raspberry OS
  • Installation software caméra multiplexer
  • Compréhension du logiciel constructeur
  • Recherche d'un bottleneck dans le programme
  • Etude des technologies disponibles pour redévelopper l'interface

Calendrier prévisionnel

Réalisation du Projet

Prologue

Semaine 1

Installation de Raspberry OS Installation du script fourni avec la carte => Suivre le git, attention à activer la caméra (SPI) et le bus I2C dans le raspi-config.

Le logiciel constructeur fonctionne. Problème :

  • Impossible de fermer la fenêtre sans kill le programme.
  • Faible fps (~6)
  • Impossible de redimensionner

Fonctionnement du logiciel de la carte multiplexeur : Le choix de la camera relié au bus SPI se fait commande I2C. Le logiciel commence par l'analyse des caméras connectées (1 à 4) en interrogeant les capteurs sur la carte à travers le bus I2C. Pour afficher les deux caméras simultanément le logiciel va switch très rapidement entre les caméras détecté et appeler l'affichage OpenCV pour chaque caméra à chaque switch.

Toutes mes tentatives d'amélioration se sont soldées par une instabilité de l'image, que ce soit en augmentant la résolution ou en diminuant la période entre chaque switch (augmentation FPS).

Pour déterminer d'où venait le blocage j'ai décidé d'essayer une camera connecté au bus SPI sans le multiplexeur : On atteint des performances bien supérieures avec un script de lecture du flux vidéo avec un OpenCV (1440x1080 30 fps).

Le switch rapide des caméras entraine forcément une réduction des FPS mais cela n'explique pas la faible résolution imposée.

Un essais avec une seule caméra placée sur la carte multiplexeur (pas encore effectué) permettrait de déterminer si le module empêche une meilleure qualité. (Une caméra sur le module avec le code constructeur est à 6 fps)

Recherches effectuées :

  • Choix de l'interface : la combinaison OpenCV pour la gestion de la vidéo et Qt pour l'interface semble tout indiqué. Je me suis donc renseigné sur le fonctionnement de ces deux bibliothèques.
  • Remise à niveau en C++
  • Faibles performances des caméras Raspberry pi de manière générale : Diviser l'action en deux thread différents semblerait grandement améliorer les performances ? (Sources peu fiables : Forum et Blogs personnels)

Semaine 2

J' ai décidé de travailler en Python pour continuer d'effectuer différents tests plus simplements sur le materiel, dans l'idée que si un developpement C++ est necessaire par la suite, la retranscription du code reste possible.

J' ai donc crée dans le dossier git /python différents scripts permettant de faire fonctionner les caméras sur le module multiplexeur. On obtient des performances similaires à celles du code constructeur ( ~6 fps + latence)

Le changement de résolution semble n'avoir que très peu d'impact sur les performances. Pour avoir des images stables on est obligé de forcer une baisse des FPS, pour laisser le temps au module de changer de caméra. Il semblerait donc que ce changement de caméra soit le goulot d'étranglement du système.

Afin de vérifier qu'il ne s'agit pas d'un problème de puissance de calcul je vais essayer de diviser les opérations en différents threads. Si il s'agit d'un problème de puissance sur le GPU alors un essai sur Raspberry Pi 4 pourrait obtenir de bien meilleures performances. --> Les tests sur raspberry pi 4 n'ont pas donné de résultats significativement meilleurs.

J'ai ensuite chercher à confirme l'hypothèse que le temps de changement de camera est trop lent pour obtenir de belles performances pour l'affichage des deux caméras simultanement : Pour cela j'ai crée un programme nommé meaure_min_swap_time.py, celui-ci permet de faire varier le temps d'attente entre chaque changement de camera avant d'afficher l'image. Ce pourrait permettre de nous donner une idée plus precise de la fréquence maximale pour maintenir une stabilité d'image.

Semaine 3

Finalisation du programe mesure : Il semblerait que la période minimale de changement de caméra soit autour de 0.05s, ce qui laisse penser que nous pourrions atteindre 10 fps par caméra. Peut être plus puisque les performance de ce programme de sont pas optimisées (python, appels systeme...)

Bien que la bibliothèque OpenCV soit reconnu pour avoir de bonnes performances j'ai tout de même voulu verifier que le problème ne venait pas de là non plus (Problème à l'installation ? Mauvaise optoin de compilation ? mauvaise utilisation, etc). Pour cela j'ai installé droidcam sur mon telephone et sur la rapsberry pour simuler une webcam passant l'USB. J'ai affiché l'image de la caméra USB et de la caméra SPI avec OpenCV. Les performances étaient très bonnes.

Semaine 4

Maintenant que le fonctionnement du materiel est plus ou moins compris, je vais réecrire le programme en C++ afin de ne pas perdre de performance à cause du langage de programation. Les bibliothèques sont similaires pour OpenCV et pour le reste je m'inspirerai du programme fourni par le constructeur. Afin de simplifier le programme je ne verifierai pas si les caméras sont présentes sur le module avec des interrogations I2C; je considère donc que les deux caméras sont toujours presente sur le port A et le port C. C'est en cherchant dans la documentation de la bibliothèque i2c du kernel linux que je me suis rendu compte que le bus i2c n'est utile que pour la detection des caméras (test sur code Python + test sur code constructeur modifié)

Semaine 5

Semaine 6

Documents Rendus

lien gitlab