Add Ego4D AV assisted annotation review workflow

This commit is contained in:
Xin Wang
2026-09-15 13:23:59 +08:00
parent 74b502f770
commit 86aa124a46
9 changed files with 953 additions and 19 deletions
+9 -3
View File
@@ -102,8 +102,14 @@ function formatTime(value) {
return `${String(minutes).padStart(2, "0")}:${(seconds % 60).toFixed(1).padStart(4, "0")}`;
}
function participantCode(value) {
const raw = String(value ?? "?");
return /^(p|person|wearer)/i.test(raw) ? raw : `P${raw}`;
}
function participantIdentity(row, verbose = false) {
const participant = `P${row.participant_id ?? "?"}`;
const raw = String(row.participant_id ?? "?");
const participant = participantCode(raw);
if (row.participant_role === "wearer") {
return verbose ? `W · ${participant} · wearer` : `W · ${participant}`;
}
@@ -282,7 +288,7 @@ function renderDetail(detail) {
for (const option of opportunityOptions) {
const control = document.createElement("option");
control.value = option.uid;
control.textContent = `${formatTime(option.anchor_seconds)} · P${option.participant_id ?? "?"} · ${option.transcription || "无转写"}`;
control.textContent = `${formatTime(option.anchor_seconds)} · ${participantCode(option.participant_id)} · ${option.transcription || "无转写"}`;
elements.opportunitySelect.append(control);
}
elements.saveState.textContent = detail.review ? "已保存" : "未保存";
@@ -501,7 +507,7 @@ function renderSpeakerTimeline(detail) {
const opportunity = document.createElement("i");
opportunity.className = "opportunity-anchor";
opportunity.style.left = `${100 * (Number(option.anchor_seconds) - left) / span}%`;
opportunity.title = `可选 release · ${formatTime(option.anchor_seconds)} · P${option.participant_id ?? "?"}`;
opportunity.title = `可选 release · ${formatTime(option.anchor_seconds)} · ${participantCode(option.participant_id)}`;
track.append(opportunity);
}
const anchor = document.createElement("i");
+3 -3
View File
@@ -3,19 +3,19 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>EasyCom Floor Event Review</title>
<title>Egocentric Floor Event Review</title>
<link rel="stylesheet" href="/app.css" />
</head>
<body>
<header class="topbar">
<div class="brand"><span class="brand-mark"></span><div><h1>Floor Event Review</h1><p>AI 粗标注 → 人工确认</p></div></div>
<div class="brand"><span class="brand-mark"></span><div><h1>Floor Event Review</h1><p>EasyCom / Ego4D AV · AI 粗标注 → 人工确认</p></div></div>
<div class="progress-block"><div class="progress-copy"><strong id="progressText">载入中</strong><span id="progressMeta">—</span></div><div class="progress-track"><span id="progressBar"></span></div></div>
<nav class="export-actions"><a href="/api/export.jsonl" download>导出 JSONL</a><a href="/api/export.csv" download>导出 CSV</a></nav>
</header>
<section class="filters" aria-label="候选筛选">
<label><span>Session</span><select id="sessionFilter"><option value="all">全部</option></select></label>
<label><span>Split</span><select id="splitFilter"><option value="all">全部</option><option value="train">train</option><option value="test">test</option></select></label>
<label><span>Split</span><select id="splitFilter"><option value="all">全部</option><option value="train">train</option><option value="val">val</option><option value="test">test</option></select></label>
<label><span>任务</span><select id="familyFilter"><option value="all">全部</option><option value="entry">WEARER ENTRY</option><option value="int">INT / YIELD</option></select></label>
<label><span>审核状态</span><select id="statusFilter"><option value="unreviewed">未审核</option><option value="all">全部</option><option value="reviewed">已审核</option></select></label>
<label class="search-field"><span>搜索</span><input id="searchFilter" type="search" placeholder="事件来源、AI 标签、session" /></label>