feat: frame QC scoring + viser per-AUV button

Stage 04 frame extract:
- New lib_frame_qc.py: per-frame Laplacian/contrast/blue-dominance scoring
- Classes: bottom_visible / water_no_bottom / turbid_water / out_of_water
- Sample 1/5 frames after extraction, write qc.json per segment
- Record metrics (frames_total, frames_bottom_visible, bottom_visible_pct)
- Mark job degraded when bottom_visible_pct < 50%

Per-AUV viser view:
- scripts/viser_auv.py loads all PLYs of an AUV, color per file
- POST /pipeline/missions/{id}/auvs/{auv}/view rsyncs ply -> worker
- launches viser on hashed port 9300+, returns URL
- _pipeline.html exposes AUV list, JS handler opens viser tab
This commit is contained in:
Ubuntu
2026-05-11 11:05:37 +00:00
parent 1a4fffd2c1
commit 82f71fcc96
7 changed files with 625 additions and 0 deletions

View File

@@ -104,6 +104,31 @@ document.addEventListener('click', async (e) => {
btn.textContent = 'viser ↗';
btn.disabled = false;
});
document.addEventListener('click', async (e) => {
const btn = e.target.closest('.btn-viser-auv');
if (!btn) return;
e.preventDefault();
const url = btn.dataset.url;
if (!url) return;
const original = btn.textContent;
btn.textContent = 'launch…';
btn.disabled = true;
try {
const res = await fetch(url, { method: 'POST' });
const d = await res.json().catch(() => ({}));
if (res.ok && d.url) {
window.open(d.url, '_blank');
} else {
alert(d.error || d.detail || ('HTTP ' + res.status));
}
} catch (err) {
alert('Erreur réseau: ' + err);
} finally {
btn.textContent = original;
btn.disabled = false;
}
});
</script>
</body>
</html>