feat: configurable track forward, track to end, skip-and-mark (REQ-189)
Track 5 Frames becomes Track Forward with a 1-100 count input, remembered in localStorage (default 5). A separate -> End action runs to the last frame behind a confirm and can be cancelled mid-flight. Frames that already hold a shape of the tracked class are skipped instead of re-annotated: hidden and dimmed shapes count as present. Skips are reported in the result banner and marked with a dot plus a class name on the filmstrip thumbnail. frames() now returns the class ids each frame holds, the same query row, no migration. Chaining and seed growth stay out: every frame is still seeded from the drawn box only.
This commit is contained in:
1 parent
f6b0335c93
commit
4f15335092
9 files changed
+226
-52
No files matched your search
+7
-2
@@ -137,11 +137,16 @@ def frames(batch_id: int) -> List[dict]:
|
||||
with db.cursor() as cur:
|
||||
cur.execute(
|
||||
"""SELECT f.*, (SELECT COUNT(*) FROM annotations a WHERE a.frame_id = f.id)
|
||||
AS annotation_count
|
||||
AS annotation_count,
|
||||
(SELECT GROUP_CONCAT(DISTINCT a.class_id) FROM annotations a
|
||||
WHERE a.frame_id = f.id) AS class_ids
|
||||
FROM frames f WHERE f.batch_id = ? ORDER BY f.idx""",
|
||||
(batch_id,),
|
||||
)
|
||||
return [dict(row) for row in cur.fetchall()]
|
||||
rows = [dict(row) for row in cur.fetchall()]
|
||||
for row in rows:
|
||||
row["class_ids"] = [int(v) for v in row["class_ids"].split(",")] if row["class_ids"] else []
|
||||
return rows
|
||||
|
||||
|
||||
def frame_path(frame_id: int) -> Optional[str]:
|
||||
|
||||
Reference in new issue
Block a user