feat(find_model gui): toggle to overlay full SAM21 cluster (yellow)

Adds a 4th checkbox 'Punti SAM21 (gialli)' that draws the full SAM21
segmentation (input to both the plane partition and Open3DModel) on
the RGB result canvas. The backend now returns sam21_points_px and
n_sam21 alongside the existing accepted/excluded splits.

Useful as a sanity check: visualise what was actually segmented vs
what the plane filter kept/rejected vs where the STL got placed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal PastroandClaude Opus 4.7 committed 2026-05-13 11:40:24 +02:00
1 parent 767d91acdc
commit 2fe7a7a7fa
3 files changed
+15 -4

No files matched your search

+7
View File
@@ -306,6 +306,11 @@ def find_model(req: FindModelReq) -> dict[str, Any]:
with sw.step("project_points"):
accepted_px = project_camera_to_pixels(accepted_m, K, (W, H))
excluded_px = project_camera_to_pixels(excluded_m, K, (W, H))
# Full SAM21 cluster (= input to the partition + Open3DModel search).
# Useful as a sanity-check overlay: shows everything segmented before
# any plane filtering. Equal to accepted ∪ excluded set-wise but kept
# as a separate field so the GUI can color it independently.
sam21_px = project_camera_to_pixels(seg.points_cv_m, K, (W, H))
with sw.step("encode_rgb"):
rgb_b64 = base64.b64encode(seg.rgb_jpeg).decode("ascii")
@@ -323,8 +328,10 @@ def find_model(req: FindModelReq) -> dict[str, Any]:
"model_points_px": model_px.tolist(),
"accepted_points_px": accepted_px.tolist(),
"excluded_points_px": excluded_px.tolist(),
"sam21_points_px": sam21_px.tolist(),
"n_accepted": int(accepted_m.shape[0]),
"n_excluded": int(excluded_m.shape[0]),
"n_sam21": int(seg.points_cv_m.shape[0]),
"plane_applied": bool(plane_info["plane_applied"]),
"fit_ok": fit_ok,
"fit_failed": fit_failed,
+7 -4
View File
@@ -540,7 +540,7 @@ $('findBtn').addEventListener('click', async () => {
}
});
['findShowModel', 'findShowAccepted', 'findShowExcluded'].forEach(id =>
['findShowModel', 'findShowAccepted', 'findShowExcluded', 'findShowSam21'].forEach(id =>
$(id).addEventListener('change', drawFindResult));
function drawFindResult() {
@@ -552,9 +552,12 @@ function drawFindResult() {
findCtx.fillStyle = color;
for (const [u, v] of pts) findCtx.fillRect(u - r, v - r, r*2+1, r*2+1);
};
if ($('findShowExcluded').checked) dot(findResult.excluded_points_px, '#e74c3c', 1);
if ($('findShowAccepted').checked) dot(findResult.accepted_points_px, '#3ecf8e', 1);
if ($('findShowModel').checked) dot(findResult.model_points_px, '#4da3ff', 1);
// Draw order: SAM21 cluster (background) -> excluded -> accepted -> model
// (foreground), so the Open3DModel STL projection wins over everything.
if ($('findShowSam21').checked) dot(findResult.sam21_points_px || [], '#ffd83d', 1);
if ($('findShowExcluded').checked) dot(findResult.excluded_points_px, '#e74c3c', 1);
if ($('findShowAccepted').checked) dot(findResult.accepted_points_px, '#3ecf8e', 1);
if ($('findShowModel').checked) dot(findResult.model_points_px, '#4da3ff', 1);
}
function loadRecipesIfNeeded() {
+1
View File
@@ -268,6 +268,7 @@
<label class="inline"><input type="checkbox" id="findShowModel" checked> Punti modello (blu)</label>
<label class="inline"><input type="checkbox" id="findShowAccepted"> Punti accettati (verdi)</label>
<label class="inline"><input type="checkbox" id="findShowExcluded"> Punti esclusi (rossi)</label>
<label class="inline"><input type="checkbox" id="findShowSam21"> Punti SAM21 (gialli)</label>
</div>
<pre id="findDetails" class="log small">—</pre>