Pipeline cosma-qc

Vue d’ensemble

Le pipeline cosma-qc traite les vidéos GoPro brutes acquises par les drones sous-marins AUV COSMA pour produire des nuages de points 3D denses (PLY) et des exports web (GLB).

Flux de données global

z620 (/mnt/portablessd)
├── GX*.MP4  (brut)
     │
     ▼  [1. Ingest]
SQLite DB (jobs)
     │
     ▼  [2. Extraction ffmpeg]
GPU worker  /cosma-qc-frames/job_{id}/frame_%06d.jpg
     │
     ▼  [3. Reconstruction lingbot-map]
GPU worker  /cosma-qc-frames/job_{id}/reconstruction.ply
     │
     ▼  [4. Stitch per_auv]
GPU worker  /cosma-qc-frames/stitch_{N}.ply  (par AUV)
     │
     ▼  [5. Stitch cross_auv]
GPU worker  /cosma-qc-frames/stitch_global.ply
     │
     ▼  [6. Export GLB  (à la demande)]
GPU worker  /cosma-qc-frames/job_{id}/reconstruction.glb

Étape 1 — Ingest

Script : scripts/ingest.py

Rôle : Scanner le SSD de z620, regrouper les MP4 GoPro par AUV/GoPro/segment temporel et écrire les jobs dans la base SQLite.

Logique de regroupement :

  • Les fichiers sont groupés par numéro de caméra GoPro (GXXX).

  • Un nouveau segment est créé si l’écart entre deux fichiers dépasse 5 minutes.

  • Chaque segment → un job en base avec statut pending.

Structure d’un job en base :

CREATE TABLE jobs (
    id INTEGER PRIMARY KEY,
    auv TEXT,
    gopro TEXT,
    segment INTEGER,
    files TEXT,          -- JSON list of z620:/path/GX*.MP4
    status TEXT,         -- pending / running / done / failed
    worker TEXT,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

Les chemins vidéo sont stockés sous la forme z620:/chemin/absolu/GX*.MP4 pour indiquer que la source est sur z620, pas sur le worker GPU.

Étape 2 — Extraction des frames

Fonction : do_extract dans le dispatcher (core .82)

Outil : ffmpeg

Paramètres d’extraction :

ffmpeg -i input.mp4         -vf fps=2,scale=1920:1080         -q:v 2         {frames_dir}/job_{id}/frame_%06d.jpg

Particularité z620 : lorsque la source est z620:/…, ffmpeg s’exécute directement sur z620 via SSH — seuls les JPEG voyagent sur le réseau. Les MP4 bruts ne quittent jamais z620.

Filtre hors-eau (heuristique de luminosité) :

  • Les frames dont la luminosité moyenne est au-dessus d’un seuil sont supprimées (ciel, surface, hors-eau).

  • Ce filtre réduit le bruit dans la reconstruction.

Reprise sur crash :

  • Un fichier marqueur .video_N.done est créé après chaque MP4 traité.

  • En cas de redémarrage, les vidéos déjà traitées sont ignorées.

Étape 3 — Reconstruction 3D

Fonction : do_reconstruct

Outil : lingbot-map (demo.py) sur le worker GPU

Entrée : répertoire de frames {worker_frames_dir}/job_{id}/

Sortie : {worker_frames_dir}/job_{id}/reconstruction.ply (nuage de points dense, jusqu’à 150 millions de points)

Un viewer Viser est automatiquement démarré sur le port 8100 + job_id pendant la reconstruction pour visualisation en temps réel.

# Visualiser pendant reconstruction
# naviguer vers http://{worker_ip}:{8100+job_id}

Étape 4 — Stitch par AUV

Fonction : do_stitch_per_auv

Déclenchement : automatique quand tous les jobs d’un AUV sont en statut done.

Outil : cosma-stitch.py

Opération : alignement et fusion des PLY de tous les segments d’un même AUV.

Sortie : {worker_frames_dir}/stitch_{N}.ply

Ce stitch s’exécute sur le worker qui détient les PLY (pas de copie inter-workers).

Étape 5 — Stitch cross-AUV

Fonction : do_stitch_cross_auv

Déclenchement : automatique quand tous les stitches per_auv sont validés.

Opération : fusion de tous les PLY par AUV en un nuage de points global final.

Sortie : {worker_frames_dir}/stitch_global.ply

Étape 6 — Export GLB (à la demande)

Outil : trimesh (conversion PLY → GLB)

Sous-échantillonnage : 5 millions de points (adapté web/navigateur)

Sortie : {worker_frames_dir}/job_{id}/reconstruction.glb

Un serveur HTTP minimal est lancé sur le worker (port 8300) pour le téléchargement :

# Sur le worker
python3 -m http.server 8300 --directory {worker_frames_dir}

# Télécharger depuis un PC
wget http://{worker_ip}:8300/job_{id}/reconstruction.glb

Statuts de jobs

Statut

Description

pending

Job créé, en attente de dispatch

running

En cours de traitement (extraction ou reconstruction)

done

Reconstruction terminée, PLY disponible

failed

Erreur — voir logs du dispatcher