docs: expanded trajectory section with interpretation guide and SQL
This commit is contained in:
@@ -81,7 +81,117 @@ face_density
|
|||||||
| `min_confidence` | float | 0.5 | Minimum detection confidence |
|
| `min_confidence` | float | 0.5 | Minimum detection confidence |
|
||||||
| `trace_ids` | string | — | Comma-separated trace_id filter (optional) |
|
| `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
|
```json
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user