pyronear / pyronear/pyro-annotator

Object-split cross-dedup leaves orphan others_bboxes and duplicates sibling objects across overlapping alerts

Open
#262 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
0
Forks
1
Avg merge
1d 2h
Merged PRs (30d)
2

Description

Symptom

On /classify/48 (alert 55757, camera sampzon-ldd-01), the missed-smoke player shows a dashed others_bboxes box at x≈0.81 — to the right of both objects — that corresponds to no object row of this alert. Annotators reasonably ask "why isn't this an object?"

Forensics (local import of 2026-07-27, camera 99)

Two alert-API alerts overlap in time on the same camera:

platform alert lane (sequence id) own track at window
55757 48 (primary) x≈0.44 15:45–16:25
55757 49 (sibling 1055757001) x≈0.72 15:45–16:25
55738 51 (primary) x≈0.81 13:39–16:15
55738 52 (sibling 1055738001) x≈0.72 15:36–16:15

From ~16:13 the shared frames carry three boxes (0.44, 0.72, 0.81). Lane 48/49 detections then hold others_bboxes = [0.72, 0.81], e.g.:

48 | 16:13:31 | own [0.438..0.461] | others [[0.721..0.73], [0.807..0.824]]

Why the 0.81 box has no lane in alert 55757

object_split.split_all_records cross-dedups a sibling cluster whose boxes match another alert sequence's own (bbox-sourced) boxes — here the 0.81 cluster matches alert 55738's primary — so it is intentionally not imported again under 55757. Two follow-on effects make this confusing in the UI:

  1. Orphan others_bboxes. The kept lanes' others_bboxes were rewritten by split_sequence_records before the drop happens in split_all_records, so they still reference the dropped cluster's boxes. The classify alert view groups lanes strictly by platform_alert_id, so the annotator sees a dashed box that belongs to no rail object, with no hint that it is tracked as /classify/51 under alert 55738.

  2. Sibling-vs-sibling duplication (double annotation work). Cross-dedup only compares a sibling's boxes against other sequences' own boxes. The 0.72 plume is others-sourced in both alerts, so it matches neither side's own boxes and gets imported twice — lane 49 (alert 55757) and lane 52 (alert 55738). The same physical object will be classified twice, potentially with conflicting labels, and each copy shows up as a dashed "sibling" box in the other alert.

Possible directions

  • Rewrite the kept groups' others_bboxes after cross-dedup (drop the deduped cluster's boxes), and/or annotate them with a provenance marker ("tracked in alert N") the frontend can surface as a link instead of an anonymous dashed box.
  • Extend cross-dedup to sibling-vs-sibling comparison (same bucket-key + rounded coords machinery), keeping one canonical lane — probably under the alert whose window starts first.
  • Frontend-only mitigation: in the classify cockpit's whole-alert player, label dashed boxes as "untracked / tracked elsewhere" so they read as hints, not missing objects.

Related: the object-split design in annotation_api/scripts/data_transfer/ingestion/alert_api/object_split.py (see its module docstring, which already notes the dedup is per-run only), issue #166.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with annotation_api/scripts/data_transfer/ingestion/alert_api/object_split.py and its module docstring, then trace split_sequence_records and split_all_records for the orphan-box and sibling-dedup cases. Review the classify cockpit's whole-alert player before choosing a direction. Done means dropped clusters are not shown as anonymous orphan boxes and the shared sibling object is not imported twice, with issue #166 as related context.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, typescript
Domain
backend, data-engineering, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.