Comment une seule caméra peut-elle alimenter une vidéo, des analyses, un enregistrement et plusieurs interfaces sans que chaque fonction refasse le même travail ?
Au début, il n’y avait que PolarScope
En 2019, j’imagine déjà un viseur numérique pour ma monture d’astronomie EM-10 Takahashi autour d’une caméra Raspberry Pi et d’un Pi Zero. Mes notes de l’époque sur le viseur polaire retracent aussi mes essais de calibration de l’axe polaire et de corrélation stellaire. Je ne finalise pas cette première version, mais elle me sert de base pour la nouvelle mouture de 2026, beaucoup plus ambitieuse.
Pour ce premier projet, j’ai construit un support imprimé qui adapte un objectif CS à une caméra Raspberry Pi et permet de la monter sur l’EM-10. Ce travail mécanique allait de pair avec le logiciel que je voulais développer pour en faire un viseur polaire ; je le raconte dans mon projet mécanique de viseur polaire.
Le 14 août 2026, je consigne dans le dépôt actuel le premier commit de cette nouvelle mouture de PolarScope, mon application d’alignement polaire. Le lendemain, je pilote déjà la caméra du Raspberry Pi directement en mémoire. Deux jours plus tard, l’acquisition continue et des tampons alternés évitent d’attendre la fin de chaque traitement pour demander l’image suivante.
La séparation entre client et serveur arrive le 19 août. L’interface ne dépend plus d’une caméra particulière : elle dialogue avec un protocole générique. Le serveur web, PiNox, le Dashboard, la Projection et le banc de Caractérisation se sont ensuite construits autour de ce même état caméra. Le 23 septembre, ce socle prend officiellement le nom d’Embedded Imaging Platform. PolarScope en est l’origine historique et reste une application parmi d’autres : EIP est devenu une plateforme générique d’imagerie embarquée.
Une seule main sur le volant de la caméra
Plusieurs programmes capables de reconfigurer indépendamment le capteur finiraient par se gêner. EIP choisit donc une règle simple : un seul serveur possède la caméra, son mode, son exposition et son cycle de vie. Les interfaces deviennent des clients de ce serveur ; elles demandent un service sans reprendre la main sur le matériel.
Cette organisation forme un monolithe modulaire. Le déploiement reste celui d’un service unique, mais son code est séparé en pilotes, cœur d’imagerie, services astronomiques et applications. Une nouvelle caméra remplace un pilote ; une nouvelle application réutilise les services existants.
Une trame, plusieurs vies
Une image destinée à être regardée dans un navigateur n’a pas les mêmes contraintes qu’une mesure scientifique. EIP conserve donc deux chemins complémentaires issus de la même capture :
La voie scientifique préserve les valeurs du capteur dans les données brutes (RAW). Elle peut être enregistrée localement avant que le réseau ne devienne une contrainte. La voie visuelle peut réduire l’image, la dématricer, appliquer une balance et l’encoder en JPEG. Avec une caméra Raspberry Pi compatible, le processeur de signal d’image (ISP) peut accélérer cette prévisualisation tandis que le RAW associé reste disponible.
Faire travailler les cœurs sans faire attendre la caméra
Le serveur utilise plusieurs fils d’exécution. L’un entretient l’acquisition, d’autres servent les connexions, préparent les annotations, suivent une planète ou écrivent les fichiers. Les calculs appliqués à beaucoup de pixels peuvent en plus être répartis entre les cœurs avec OpenMP (Open Multi-Processing, une interface de programmation parallèle), au-dessus d’un seuil où le travail parallèle devient utile.
L’enregistrement utilise une file asynchrone : la caméra dépose une trame et reprend son travail pendant que le stockage l’écrit. Le calcul astronomique peut réserver un cœur au reste du serveur. Les réglages d’affichage restent séparés des réglages du capteur afin qu’un changement de gamma ne redémarre pas une pose longue. Ajouter des fils d’exécution ne fait toutefois pas courir un capteur plus vite que sa propre cadence.
Recouvrir des phases : le double tampon
Sans recouvrement, la capture attend la fin du traitement avant de reprendre. Avec deux tampons, le traitement d’une trame peut se poursuivre pendant qu’une autre phase prépare la suivante. Cela autorise un recouvrement des travaux, sans promettre que toutes les opérations s’exécutent exactement en même temps.
Le benchmark du 29 août compare les images JPEG distinctes, sans confondre répétition HTTP et nouvelle trame. Sur Pi 4 en bin1, la cadence reste proche de 15 IPS avant et après : la lecture du capteur est alors le facteur limitant.
Le meilleur calcul est parfois celui que l’on évite
L’architecture associe chaque produit à l’identifiant de sa trame. La luminance utilisée par la prévisualisation et les annotations est partagée ; le JPEG est encodé une seule fois même lorsque plusieurs clients le regardent ; une trame n’est envoyée qu’une fois à chaque client MJPEG. Les buffers RAW, couleur et JPEG sont réutilisés pour limiter allocations et pics de mémoire.
Cette mutualisation a un résultat vérifiable : en IMX477 1332 × 990, EIP mesure 47,7 images capturées, 47,7 RAW et 47,7 images MJPEG distinctes par seconde, avec 0 % de doublons. L’identifiant frame_id permet de maintenir cette chronologie commune.
Un serveur, plusieurs applications
Le serveur expose trois familles de services. Le plan de données transporte le RAW et le MJPEG. Le plan de contrôle reçoit les réglages et publie l’état. Les services métier fournissent l’astrométrie, les annotations, le suivi, la caractérisation, le stockage et les rapports. Les dépendances logicielles suivent ces couches, mais chaque application n’a pas besoin de traverser tous les services astronomiques.
Une tablette peut afficher PolarScope, un ordinateur surveiller le Dashboard et un écran HDMI montrer la Projection, tandis que le serveur peut continuer à enregistrer localement le RAW sans le faire transiter par le réseau.
Grandir sans confondre taille et qualité
L’historique montre l’ampleur prise par le projet, mais un nombre de lignes ne mesure ni la qualité ni la performance. Il indique ici l’étendue fonctionnelle et l’effort de vérification. Entre le 14 août et le 5 octobre, le logiciel livré passe de 11 792 à 87 870 lignes non vides ; les tests passent de 279 à 24 030 lignes.
src/ et les applications web embarquées de assets/web/. Les tests sont comptés séparément. Documentation, site éditorial, données, images, catalogues, outils et lignes vides sont exclus. Données CSV.La forte progression de fin septembre correspond à la consolidation de PiNox, du stockage et des interfaces web, puis à l’augmentation des tests pendant la modularisation et l’intégration de l’ISP. Au 5 octobre, le bilan est de 87 870 lignes non vides de logiciel livré, 24 030 lignes de tests, soit 111 900 au total. Le périmètre et ses exclusions sont détaillés dans la légende et le CSV.
Ce que cette architecture apporte
Elle permet
- un propriétaire unique de la caméra ;
- plusieurs usages d’une même trame ;
- des rythmes de capture, d’analyse et d’écriture découplés ;
- des calculs et buffers partagés ;
- l’enregistrement local avant la contrainte réseau ;
- plusieurs applications autour d’un même état caméra.
Elle ne garantit pas
- qu’un Pi dépasse la cadence du capteur ;
- que tout parallélisme améliore les performances ;
- qu’un serveur monolithique convienne à des milliers de clients ;
- qu’un code plus volumineux soit de meilleure qualité.
EIP ne prétend pas qu’un processus unique résout tout. Le serveur HTTP reste volumineux et certaines fonctions applicatives doivent encore être extraites de sa couche d’orchestration. Le parallélisme ne compense pas non plus une limite du capteur, du réseau ou du stockage. L’intérêt tient à la cohérence : une caméra, une chronologie et plusieurs usages qui ne refont pas chacun leur propre pipeline.
Pour continuer
Autre niveau de lecture
Architecture concurrente d’EIP — version scientifique · Modules, mesures, protocoles et limites.