Files
OperationRoomMonitor/README.md
2026-06-05 15:12:15 +08:00

163 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 手术室耗材篮子识别包(离线 + 推流)
段内流程:**手检≥2 手 union→ 好坏帧门控 → 耗材分类****推流**在每个接触段内与耗材**并行**医生识别;**离线**在全片结束后追加一行医生信息。
`configs/default_config.yaml` 当前参数一致(`imgsz_det: 1920``contact+3~+10` 等)。
## 环境要求
- Python 3.10+(推荐 conda 环境 `yolo`
- NVIDIA GPU + CUDA
- `python3-tk`(每次运行首帧弹窗框选篮子 ROI
- `ffmpeg` / `ffprobe`HEVC 视频建议先转 H.264,见下文)
## 快速安装
```bash
cd /path/to/6.1
bash setup.sh
# 若用 conda推荐
conda activate yolo
pip install -r requirements.txt
```
## 三个入口
| 脚本 | 用途 |
|------|------|
| `main_basket.py` | **离线**:全片篮子接触分段 → Phase2 → gap 合并 → 医生识别 |
| `main_basket_stream.py` | **推流/本地 MP4 模拟推流**:逐帧触发 → 段内耗材+医生并行 → 实时写 15 列 TSV |
| `main_segments_offline.py` | 按 TSV 时间段对离线 MP4 重跑段内识别(校验用) |
## 1. 离线跑视频
```bash
conda activate yolo
cd /path/to/6.1
python main_basket.py \
--video /path/to/your.mp4 \
--excel input/视频中的商品信息表.xlsx \
--out output/result_offline.txt \
--save-basket-roi output/basket_roi.json \
--config configs/default_config.yaml
```
运行后**弹窗框选篮子 ROI**,然后自动全片扫描 + 段内识别。
## 2. 推流(或本地 MP4 测试)
```bash
python main_basket_stream.py \
--rtsp /path/to/your.mp4 \
--excel input/视频中的商品信息表.xlsx \
--out output/result_stream.txt \
--save-basket-roi output/basket_roi_stream.json \
--config configs/default_config.yaml
```
- 本地 MP4`stream.infer_source: file` → 段内**回源 4K**(与离线一致)
- 真 RTSP无法 seek 时回退 JPEG 缓存(`cache_max_width: 1920`
- 医生识别:`doctor_identity.stream_enabled: true`每段并行识别TSV 追加 `doctor_id` / `doctor_name` / `doctor_conf`
## 3. HEVC 视频
4K HEVC 可能导致 OpenCV 解码不稳定,建议先转码:
```bash
bash scripts/remux_hevc.sh /path/to/source.mp4
# 输出: input/remuxed/<name>_h264.mp4
```
## 配置说明(`configs/default_config.yaml`
| 段 | 关键参数 |
|----|----------|
| `phase2` | `imgsz_det: 1920``pad_bottom_ratio: 0.5``det_conf: 0.6` |
| `classification` | 好帧 0.9,耗材 0.8,重试 0.7 / 0.5 |
| `basket` | `iou_on: 0.03``confirm: 0.1``cooldown: 10`,窗口 contact+3~+10 |
| `stream` | 段窗口与 basket 一致;`infer_source: file` |
| `io` | `use_whitelist: false`(全 41 类) |
| `doctor_identity` | `enabled` / `stream_enabled`;推流用 `segment_sample_fps` 在段 `[start,end]` 内采样 |
## 模型文件(`weights/`
- `hand_detect.pt` — 手部检测
- `goodbad_frame.pt` — 好坏帧门控
- `haocai_classify.pt` — 耗材分类
- `doctor_identity_package/doctor_info.pth` — 医生 ReID需同目录 `train_reid_contrastive.py`
## 输出格式
- **推流**12 列耗材 TSV各段内在 **居中 3s** 窗跑医生 ReID 后 **投票取 Top1**,末尾一行 `医生信息:...``doctor_identity.segment_window_sec`)。末段时长不足 7s 判为误触丢弃
- **离线**12 列 TSV + 末尾一行 `医生信息:...`(全片中间窗口识别)
## 可视化演示(标注 MP4
跑完 `main_basket.py` 后,可用独立脚本把 **视频 + TSV** 合成带框演示片段内复现手检框Top3/医生文字直接读 TSV不重跑耗材模型
```bash
conda activate yolo
cd /path/to/6.3
python scripts/visualize_pipeline.py \
--video /path/to/your.mp4 \
--tsv output/result_offline.txt \
--basket-roi output/basket_roi.json \
--config configs/default_config.yaml \
--out output/demo_vis.mp4
```
| 叠加层 | 说明 |
|--------|------|
| 青色虚线框 | 篮子 ROI`--basket-roi`,与 `--save-basket-roi` 配套) |
| 绿色框 | 段内手部检测(与 `configs/default_config.yaml``hand.backend` 一致;默认 **MediaPipe** `weights/hand_landmarker.task`,标签为「手 mp」 |
| 黄色粗框 | 双手 union ROI与 Phase2 一致) |
| 顶部信息条 | TSV 该段时间段的 rank、Top3 或失败原因 |
| 片头 | 视频/TSV 路径 + 离线 `医生信息:` 汇总 |
**性能建议**(长片/4K`--preview-width 1280 --det-stride 5`。依赖系统已安装 `ffmpeg`
**中文显示**:叠加文字使用 Pillow + 系统 CJK 字体(默认 `NotoSansCJK-Regular.ttc`)。若出现方框/乱码,请安装 `fonts-noto-cjk`,或通过 `--font /path/to/font.ttc` / 环境变量 `VIS_CJK_FONT` 指定字体。
**手部后端**:与 `main_basket` 共用 `hand` 配置段。默认 `hand.backend: mediapipe` + `hand.mediapipe_task: weights/hand_landmarker.task`(每帧最多 2 只手)。对比 YOLO 旧行为:`--hand-backend yolo`
**篮筐附近手框与 ROI**:提供 `--basket-roi` 时,默认只绘制靠近篮子的手(篮子框外扩 20% 后 IoU > `contact_iou_on`**黄色 ROI** 由其中与篮子 IoU 最高的两只手合并。背景手不再绘制。关闭过滤用 `--no-hand-basket-filter`;贴边漏检可试 `--basket-expand-frac 0.3` 或略降 `--hand-basket-min-iou 0.02`
**本地 smoke**(无真实手术视频时):
```bash
conda run -n yolo python scripts/make_smoke_fixture.py
conda run -n yolo python scripts/visualize_pipeline.py \
--video output/smoke/smoke.mp4 \
--tsv output/smoke/smoke_result.txt \
--basket-roi output/smoke/smoke_basket_roi.json \
--out output/smoke/demo_vis.mp4 \
--det-stride 2 --preview-width 640 --title-sec 1
```
## 目录结构
```
6.1/
├── main_basket.py # 离线入口
├── main_basket_stream.py # 推流入口
├── main_segments_offline.py # TSV 段内重跑
├── configs/default_config.yaml
├── weights/ # 3 个 YOLO 权重
├── input/视频中的商品信息表.xlsx
├── doctor_identity_package/ # 医生识别(离线整片 + 推流段内)
├── src/ code/ # 编排与算法
├── output/ # 结果输出目录
├── scripts/visualize_pipeline.py # TSV → 标注演示 MP4
├── setup.sh requirements.txt
└── README.md
```
## 常见问题
1. **CUDA OOM**:勿将 `imgsz_det` 设为 3840当前 1920 在 8GB 显卡可用。
2. **无 GUI**:无法弹窗框选 ROI需另备 ROI JSON当前入口每次仍弹窗
3. **分段过多**:可调大 `basket.confirm_seconds``cooldown_seconds`