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:
@@ -16,6 +16,16 @@
|
||||
{% if m.counts.get('error') %}<span class="cnt err">{{ m.counts.error }} error</span>{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% if m.auvs %}
|
||||
<div class="pm-auvs">
|
||||
<span class="pm-auvs-label">Viser AUV:</span>
|
||||
{% for auv_id in m.auvs %}
|
||||
<button class="btn-viser-auv"
|
||||
data-url="/pipeline/missions/{{ m.id }}/auvs/{{ auv_id }}/view"
|
||||
type="button">{{ auv_id }} ↗</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class="pipeline-jobs-table">
|
||||
<thead>
|
||||
<tr><th>AUV</th><th>Segment</th><th>Stage</th><th>Status</th><th>Worker</th><th>Duree</th></tr>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user