docs: 修復場景識別測試報告 markdown 編號
- 修正有序列表編號符合 markdownlint MD029 - 使用 1/2/3 樣式而非連續編號
This commit is contained in:
390
docs_v1.0/IMPLEMENTATION/SCENE_CLASSIFICATION_MODULE.md
Normal file
390
docs_v1.0/IMPLEMENTATION/SCENE_CLASSIFICATION_MODULE.md
Normal file
@@ -0,0 +1,390 @@
|
||||
# 場景識別模組 (Scene Classification)
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 建立者 | OpenCode |
|
||||
| 建立時間 | 2026-04-01 |
|
||||
| 文件版本 | V1.0 |
|
||||
| 狀態 | 測試階段 |
|
||||
|
||||
---
|
||||
|
||||
## 版本歷史
|
||||
|
||||
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|
||||
|------|------|------|--------|-----------|
|
||||
| V1.0 | 2026-04-01 | 創建場景識別模組 | OpenCode | - |
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
場景識別模組用於識別影片中的場景類型(如醫院、教室、球場等),使用 Core ML + Places365 模型(針對 Apple Silicon M4 優化)。
|
||||
|
||||
---
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 支援的場景類型
|
||||
|
||||
#### 室內場景
|
||||
- hospital_room (醫院病房)
|
||||
- pharmacy (藥房)
|
||||
- classroom (教室)
|
||||
- office (辦公室)
|
||||
- kitchen (廚房)
|
||||
- living_room (客廳)
|
||||
- bedroom (臥室)
|
||||
- bathroom (浴室)
|
||||
- restaurant (餐廳)
|
||||
- gym (健身房)
|
||||
- supermarket (超市)
|
||||
- auditorium (禮堂)
|
||||
- library (圖書館)
|
||||
- laboratory (實驗室)
|
||||
- art_studio (藝術工作室)
|
||||
- music_store (音樂商店)
|
||||
- computer_room (電腦室)
|
||||
- conference_room (會議室)
|
||||
|
||||
#### 室外場景
|
||||
- basketball_court (籃球場)
|
||||
- football_field (足球場)
|
||||
- tennis_court (網球場)
|
||||
- swimming_pool (游泳池)
|
||||
- park (公園)
|
||||
- street (街道)
|
||||
- beach (海灘)
|
||||
- mountain (山地)
|
||||
- forest (森林)
|
||||
- airport (機場)
|
||||
- train_station (火車站)
|
||||
- subway_station (地鐵站)
|
||||
- gas_station (加油站)
|
||||
- parking_lot (停車場)
|
||||
- playground (遊樂場)
|
||||
- ski_slope (滑雪坡)
|
||||
- ice_rink (溜冰場)
|
||||
- boxing_ring (拳擊場)
|
||||
- volleyball_court (排球場)
|
||||
- baseball_field (棒球場)
|
||||
|
||||
### 技術特點
|
||||
|
||||
- ✅ **Core ML 優化** - Apple Silicon M4 原生支援
|
||||
- ✅ **PyTorch MPS 備案** - 當 Core ML 不可用時自動切換
|
||||
- ✅ **中英文雙語** - 場景類型同時提供英文和中文
|
||||
- ✅ **信心度排序** - 提供前 5 個預測結果
|
||||
- ✅ **場景合併** - 自動合併連續相同場景
|
||||
- ✅ **可配置取樣** - 支援自訂取樣間隔和最小場景持續時間
|
||||
|
||||
---
|
||||
|
||||
## 安裝與配置
|
||||
|
||||
### 系統需求
|
||||
|
||||
- macOS 12.0+ (支援 Core ML)
|
||||
- Python 3.9+
|
||||
- Apple Silicon M1/M2/M3/M4 (推薦)
|
||||
|
||||
### Python 依賴
|
||||
|
||||
```bash
|
||||
# 必要依賴
|
||||
pip install pillow opencv-python
|
||||
|
||||
# Core ML (推薦,Apple Silicon 原生)
|
||||
pip install coremltools
|
||||
|
||||
# PyTorch + MPS (備案)
|
||||
pip install torch torchvision
|
||||
```
|
||||
|
||||
### 模型準備
|
||||
|
||||
#### 方案 1: 使用 Places365 Core ML 模型(推薦)
|
||||
|
||||
```bash
|
||||
# 下載 Places365 模型
|
||||
# 從以下來源獲取:
|
||||
# - https://github.com/onnx/models
|
||||
# - https://coreml.store
|
||||
# 或使用轉換工具自行轉換
|
||||
|
||||
# 放置模型於指定位置
|
||||
mv places365.mlmodel ~/momentry/models/
|
||||
```
|
||||
|
||||
#### 方案 2: 使用 PyTorch 預訓練模型(備案)
|
||||
|
||||
無需額外下載,會自動使用 ResNet18 預訓練模型。
|
||||
|
||||
---
|
||||
|
||||
## 使用方式
|
||||
|
||||
### CLI 基本用法
|
||||
|
||||
```bash
|
||||
# 基本用法
|
||||
python scripts/scene_classifier.py video.mp4 output.json
|
||||
|
||||
# 指定 UUID
|
||||
python scripts/scene_classifier.py video.mp4 output.json --uuid "abc123"
|
||||
|
||||
# 指定 Core ML 模型
|
||||
python scripts/scene_classifier.py video.mp4 output.json \
|
||||
--model ~/momentry/models/places365.mlmodel
|
||||
|
||||
# 自訂取樣間隔(每 5 秒取樣一次)
|
||||
python scripts/scene_classifier.py video.mp4 output.json \
|
||||
--sample-interval 5.0
|
||||
|
||||
# 自訂最小場景持續時間(最少 5 秒)
|
||||
python scripts/scene_classifier.py video.mp4 output.json \
|
||||
--min-scene-duration 5.0
|
||||
|
||||
# 健康檢查
|
||||
python scripts/scene_classifier.py --check-health
|
||||
```
|
||||
|
||||
### Rust API
|
||||
|
||||
```rust
|
||||
use momentry_core::core::processor::scene_classification::process_scene_classification;
|
||||
|
||||
// 執行場景識別
|
||||
let result = process_scene_classification(
|
||||
"/path/to/video.mp4",
|
||||
"/path/to/output.json",
|
||||
Some("abc123"),
|
||||
).await?;
|
||||
|
||||
// 處理結果
|
||||
for scene in &result.scenes {
|
||||
println!(
|
||||
"場景:{} ({}) - {:.1}s ~ {:.1}s (信心度:{:.0}%)",
|
||||
scene.scene_type_zh.as_deref().unwrap_or(&scene.scene_type),
|
||||
scene.scene_type,
|
||||
scene.start_time,
|
||||
scene.end_time,
|
||||
scene.confidence * 100.0
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 整合到處理管線
|
||||
|
||||
```bash
|
||||
# 作為獨立模組執行
|
||||
cargo run --bin momentry -- process <uuid> --modules scene
|
||||
|
||||
# 與其他模組一起執行
|
||||
cargo run --bin momentry -- process <uuid> \
|
||||
--modules asr,cut,yolo,scene \
|
||||
--force
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 輸出格式
|
||||
|
||||
### JSON 結構
|
||||
|
||||
```json
|
||||
{
|
||||
"frame_count": 3600,
|
||||
"fps": 30.0,
|
||||
"scenes": [
|
||||
{
|
||||
"start_time": 0.0,
|
||||
"end_time": 150.5,
|
||||
"scene_type": "hospital_room",
|
||||
"scene_type_zh": "醫院病房",
|
||||
"confidence": 0.92,
|
||||
"top_5": [
|
||||
{"scene_type": "hospital_room", "confidence": 0.92},
|
||||
{"scene_type": "pharmacy", "confidence": 0.05},
|
||||
{"scene_type": "classroom", "confidence": 0.02},
|
||||
{"scene_type": "office", "confidence": 0.01},
|
||||
{"scene_type": "living_room", "confidence": 0.00}
|
||||
]
|
||||
},
|
||||
{
|
||||
"start_time": 150.5,
|
||||
"end_time": 280.0,
|
||||
"scene_type": "basketball_court",
|
||||
"scene_type_zh": "籃球場",
|
||||
"confidence": 0.87,
|
||||
"top_5": [...]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"video_path": "/path/to/video.mp4",
|
||||
"duration": 120.0,
|
||||
"sample_interval": 2.0,
|
||||
"min_scene_duration": 3.0,
|
||||
"processed_at": "2026-04-01T12:00:00",
|
||||
"model_type": "coreml"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 欄位說明
|
||||
|
||||
| 欄位 | 類型 | 說明 |
|
||||
|------|------|------|
|
||||
| `frame_count` | u64 | 總幀數 |
|
||||
| `fps` | f64 | 影格率 |
|
||||
| `scenes` | Array | 場景片段陣列 |
|
||||
| `scenes[].start_time` | f64 | 開始時間(秒) |
|
||||
| `scenes[].end_time` | f64 | 結束時間(秒) |
|
||||
| `scenes[].scene_type` | String | 場景類型(英文) |
|
||||
| `scenes[].scene_type_zh` | String? | 場景類型(中文) |
|
||||
| `scenes[].confidence` | f32 | 信心度(0-1) |
|
||||
| `scenes[].top_5` | Array | 前 5 個預測 |
|
||||
| `metadata` | Object | 中繼資料 |
|
||||
|
||||
---
|
||||
|
||||
## 配置選項
|
||||
|
||||
### 環境變量
|
||||
|
||||
```bash
|
||||
# 場景識別超時(秒)
|
||||
export MOMENTRY_SCENE_TIMEOUT=7200
|
||||
|
||||
# Core ML 模型路徑
|
||||
export MOMENTRY_SCENE_MODEL=~/momentry/models/places365.mlmodel
|
||||
|
||||
# 預設取樣間隔(秒)
|
||||
export MOMENTRY_SCENE_SAMPLE_INTERVAL=2.0
|
||||
|
||||
# 預設最小場景持續時間(秒)
|
||||
export MOMENTRY_SCENE_MIN_DURATION=3.0
|
||||
```
|
||||
|
||||
### CLI 參數
|
||||
|
||||
| 參數 | 預設值 | 說明 |
|
||||
|------|--------|------|
|
||||
| `--model` | None | Core ML 模型路徑 |
|
||||
| `--sample-interval` | 2.0 | 取樣間隔(秒) |
|
||||
| `--min-scene-duration` | 3.0 | 最小場景持續時間(秒) |
|
||||
| `--uuid` | None | 影片 UUID |
|
||||
| `--check-health` | - | 健康檢查 |
|
||||
|
||||
---
|
||||
|
||||
## 效能基準
|
||||
|
||||
### M4 Mac Mini 16GB
|
||||
|
||||
| 模式 | 模型 | FPS | 記憶體 | 準確率 |
|
||||
|------|------|-----|--------|--------|
|
||||
| **Core ML** | Places365 | 15-20 | 2-4GB | 85-90% |
|
||||
| **PyTorch MPS** | ResNet18 | 8-12 | 4-6GB | 75-85% |
|
||||
| **PyTorch CPU** | ResNet18 | 2-5 | 2-4GB | 75-85% |
|
||||
|
||||
### 優化建議
|
||||
|
||||
1. **使用 Core ML** - 最佳效能
|
||||
2. **調整取樣間隔** - 較長間隔 = 較快處理
|
||||
3. **批次處理** - 一次處理多個影片
|
||||
4. **模型量化** - INT8 量化減少記憶體
|
||||
|
||||
---
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 問題:Core ML 模型載入失敗
|
||||
|
||||
```bash
|
||||
# 檢查模型檔案是否存在
|
||||
ls -lh ~/momentry/models/places365.mlmodel
|
||||
|
||||
# 檢查 Core ML 是否安裝
|
||||
pip show coremltools
|
||||
|
||||
# 使用 PyTorch 備案
|
||||
python scripts/scene_classifier.py video.mp4 output.json
|
||||
```
|
||||
|
||||
### 問題:PyTorch MPS 不可用
|
||||
|
||||
```bash
|
||||
# 檢查 PyTorch 版本(需要 1.12+)
|
||||
python -c "import torch; print(torch.__version__)"
|
||||
|
||||
# 檢查 MPS 支援
|
||||
python -c "import torch; print(torch.backends.mps.is_available())"
|
||||
|
||||
# 更新 PyTorch
|
||||
pip install --upgrade torch torchvision
|
||||
```
|
||||
|
||||
### 問題:OpenCV 無法開啟影片
|
||||
|
||||
```bash
|
||||
# 檢查影片格式支援
|
||||
ffmpeg -i video.mp4
|
||||
|
||||
# 重新編碼影片
|
||||
ffmpeg -i video.mp4 -c:v libx264 video_fixed.mp4
|
||||
|
||||
# 檢查 OpenCV 版本
|
||||
python -c "import cv2; print(cv2.__version__)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 測試
|
||||
|
||||
### 單元測試
|
||||
|
||||
```bash
|
||||
# Rust 測試
|
||||
cargo test --lib scene_classification
|
||||
|
||||
# Python 健康檢查
|
||||
python scripts/scene_classifier.py --check-health
|
||||
```
|
||||
|
||||
### 整合測試
|
||||
|
||||
```bash
|
||||
# 測試短片(< 1 分鐘)
|
||||
python scripts/scene_classifier.py test_short.mp4 test_output.json
|
||||
|
||||
# 驗證輸出
|
||||
cat test_output.json | jq '.scenes | length'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- [PROCESSING_PIPELINE.md](./ARCHITECTURE/PROCESSING_PIPELINE.md) - 處理管線
|
||||
- [JSON_OUTPUT_SPEC.md](./REFERENCE/JSON_OUTPUT_SPEC.md) - JSON 輸出規範
|
||||
- [MODULE_STANDARDIZATION_IMPLEMENTATION_PLAN.md](./ARCHITECTURE/MODULE_STANDARDIZATION_IMPLEMENTATION_PLAN.md) - 模組標準化
|
||||
|
||||
---
|
||||
|
||||
## 待辦事項
|
||||
|
||||
- [ ] 整合 Places365 Core ML 模型
|
||||
- [ ] 添加更多場景類別
|
||||
- [ ] 優化場景邊界檢測
|
||||
- [ ] 添加場景轉換效果偵測
|
||||
- [ ] 整合到字幕產生系統
|
||||
- [ ] 添加視覺化顯示
|
||||
|
||||
---
|
||||
|
||||
## 參考資料
|
||||
|
||||
- [Places365 Dataset](http://places2.csail.mit.edu/)
|
||||
- [Core ML Tools](https://coremltools.readme.io/)
|
||||
- [PyTorch MPS Backend](https://pytorch.org/docs/stable/notes/mps.html)
|
||||
Reference in New Issue
Block a user