docs: expanded trajectory section with interpretation guide and SQL

This commit is contained in:
Warren
2026-05-08 13:40:10 +08:00
parent e5f252a3ec
commit a0f3382d13

View File

@@ -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
{