diff --git a/docs_v1.0/API_V1.0.0/TRACE/TRACE_HEATMAP_SPEC_V1.0.0.md b/docs_v1.0/API_V1.0.0/TRACE/TRACE_HEATMAP_SPEC_V1.0.0.md index 9b4e95b..e37ddfa 100644 --- a/docs_v1.0/API_V1.0.0/TRACE/TRACE_HEATMAP_SPEC_V1.0.0.md +++ b/docs_v1.0/API_V1.0.0/TRACE/TRACE_HEATMAP_SPEC_V1.0.0.md @@ -81,7 +81,117 @@ face_density | `min_confidence` | float | 0.5 | Minimum detection confidence | | `trace_ids` | string | — | Comma-separated trace_id filter (optional) | -#### Response: Spatial +##### Type: `trajectory` — 2D 軌跡圖 (縱向位置 × 時間) + +將畫面 Y 軸位置對應時間,把 3D 時空 (x, y, t) 投影到 2D (y, t) 平面上。 + +#### 為什麼只看縱向 (y)? + +- 鏡頭多為水平固定,橫向移動(x 軸)通常反映的是鏡頭 pan,不是人物的真實移動 +- 縱向(y 軸)才是人物本身的動作:**站 → 蹲 → 坐下 → 離開畫面** +- 時間軸(t 軸)則顯示這些動作發生的**節奏** + +#### 視覺化範例 + +一個人從上往下走,在畫面上的軌跡就是一條斜線: + +``` +畫面 Y 位置 (畫面高度 %) + 0% ┤ top of frame + │ + │ ╔══╗ ← Audrey 出現在畫面偏上位置 (t=1200s) + 25% ┤ ╔══╝ + │ ╔═╝ ╔══╗ ← Cary 從下方入鏡 + 50% ┤ ╔═╝ ╔═╝ + │ ╔═╝ ╔═╝ + 75% ┤╔═╝ ╔═╝ + │╚═╗ ╔═╝ + 100% ┤ ╚═╗ ╔═══╝ + └─────────────────────────→ 時間 + 0s 1500s 3000s 4500s 5954s + ╔══╗ Audrey Hepburn + ╚═╗ Cary Grant +``` + +#### 判讀方式 + +| 圖形 | 意義 | +|------|------| +| 水平線 `══` | 人物停留在同一高度(坐著、站著不動) | +| 斜線 `/` `\` | 人物在畫面中移動(站起來 / 蹲下 / 走遠) | +| 垂直跳躍 `║` | 鏡頭切換(cut),人物出現在不同位置 | +| 密集區 `██` | 同一人物長時間出現在該區域 | +| 空白區 | 人物不在畫面中(或未被偵測到) | + +#### 多 Identity 疊加 + +不同 identity 用不同顏色疊在同一張圖上,可直接對比: + +- **誰出現在畫面上的時間最長?** → 水平線最長的那條 +- **誰一直在移動?** → 斜線最多的那條 +- **誰和誰同時出現在畫面?** → 時間軸上重疊的段落 +- **誰的位置最高/最低?** → Y 軸位置對比 + +#### 資料格式 + +```json +{ + "type": "trajectory", + "description": "Vertical position (y%) over time for selected entities", + "frame_height": 1080, + "duration": 5954, + "entities": [ + { + "trace_id": 3128, + "identity_name": "Cary Grant", + "color": "#ff4444", + "points": [ + {"t": 0, "y_pct": 0.15, "confidence": 0.78}, + {"t": 0.5, "y_pct": 0.18, "confidence": 0.79}, + {"t": 1.0, "y_pct": 0.22, "confidence": 0.77} + ] + }, + { + "trace_id": 3126, + "identity_name": "Audrey Hepburn", + "color": "#4488ff", + "points": [ + {"t": 1200, "y_pct": 0.12, "confidence": 0.85}, + {"t": 1201, "y_pct": 0.13, "confidence": 0.84} + ] + } + ] +} +``` + +#### SQL 查詢 + +```sql +-- 單一 trace: y_position 隨時間變化 +SELECT + (frame_number / fps) AS t, + (y + height / 2)::float / frame_height AS y_pct, + confidence +FROM dev.face_detections +WHERE file_uuid = $1 AND trace_id = $2 +ORDER BY frame_number; + +-- 多個 identity 疊加 +SELECT + fd.trace_id, + (fd.frame_number / v.fps) AS t, + (fd.y + fd.height / 2)::float / v.height AS y_pct, + fd.confidence, + i.name AS identity_name +FROM dev.face_detections fd +JOIN dev.videos v ON v.file_uuid = fd.file_uuid +LEFT JOIN dev.identities i ON i.id = fd.identity_id +WHERE fd.file_uuid = $1 AND fd.identity_id IN ($2, $3, ...) +ORDER BY fd.frame_number; +``` +``` + +## Response: Spatial ```json {