CleanSight 基于图像识别,检测内镜人工清洗流程的规范性,同时存储近期的检测数据用于追溯。它确保每个人工清洗步骤都正确执行,从而保证患者安全。
- 实时视频流推理 — 后端以 RTSP 拉流(MediaMTX 负责 RTSP/RTMP 接入),多路并发解码
- 分层 AI 检测 — 不同清洗阶段使用不同模型组,支持 CUDA Stream 并行推理
- HLS 录制落盘 — raw / processed 双轨视频段自动分段归档,可追溯回放
- 告警上报 — 时序判定产告警,5s 去重闸门 + 批量异步上报
- 实时画面推送 — 渲染后帧经 WebSocket 供前端 / 运维面板轮询(非后端 push)
- 运维面板 — 后端自带 admin 运维面板(
/ui-f3m8/admin/),实时画面 / 队列健康 / 指标 / 告警列表一站观测
架构、数据流、各服务内部、配置与 API 等描述性内容以知识库为准,入口 docs/kb/INDEX.md。
install.sh / install.ps1 # 装环境(Linux / Windows),物料从源机拉
start_backend.sh / start_backend.ps1 # 一条命令拉起网关(含 MediaMTX)+ 后端,端口在此声明
build.sh # 构建机打物料(wheelhouse + vendor),只在升级版本时跑
app/
├── main.py # FastAPI 入口,lifespan 启停各 Service 单例
├── settings.py # 全局配置(Pydantic Settings,读 .env)
├── gateway.py # ASGI 网关中间件 + IP 白名单 / 限流(mediamtx_gateway 进程共用)
├── types/ # 跨层共用契约(纯 dataclass)+ AppError 异常体系:frame / detection / temporal / alarm / run / exceptions
├── routers/ # HTTP/WS 路由:api / ai / task / health / traceback / media / lab / admin / algorithm
│ └── utils/ # 本层通用:run 解析 / 媒体 token 签发与校验
├── services/
│ ├── run_control/ # RunControlService — 跨服务起停一次 run 的单一编排出口
│ ├── utils/ # 服务层通用:串行队列 / 线程自愈 / 压力日志 / Prometheus 指标 / VOD m3u8 / 媒体轴
│ ├── client/ # ClientService 注册表(int task_id 键)+ ClientQueues(per-run 不可变 + 状态机)
│ ├── stream/ # FFmpegDecoder(自持读循环,RTSP-only)+ StreamService
│ ├── inference/ # 分层推理:detection/ feature/ temporal/ visualization/ offline/(各契约包 impl/ 放业务实现)
│ ├── recording/ # HLS 录制编排:何时拉、按什么顺序写、算哪一代的产物
│ ├── alarm/ # 告警上报(队列 + worker 池 + 重试)
│ ├── lab/ # 送标裁剪 + Label Studio 上传
│ └── algorithm/ # 无状态算法服务(试纸比色),与主流程无关,只被 /algorithm/* 调用
├── daemons/ # 按时钟自驱的后台任务:可依赖 services,routers 只读其状态
│ ├── health_monitor/ # 断流重连 / 任务超时 / 孤儿清理(委托 RunControlService)
│ └── cleanup/ # 存储 TTL 清理(只依赖 storage)
├── storage/ # 数据层:盘上产物怎么读写,按资源域分 hls/ 与 inference/
├── db/ # 平台 DB(PostgreSQL,只读):database 连接池 + 一张表一个 ORM 模块 tasks / alarms
├── data/ # 模型权重(.pt)——不随 git 分发,从模型库取用,见 deploy skill
└── utils/ # 日志装饰器
config/ # 运维要改的配置:六份服务 YAML + uvicorn 日志 logging.json
requirements/ # 依赖清单:base.txt 底座 + 按部署路径分的 prod / gpu / ppu
mediamtx_gateway/ # RTSP TCP 代理网关(独立进程,对外部署可选)
tests/ # 单元 & 组件测试(裸 pytest 只跑这里)
integration_tests/ # 端到端集成测试(需真实 RTSP 流),fixtures/ 放测试视频
scripts/ # 偶尔手动跑的运维工具(迁移 / SQL);hospital_sync/ 是医院数据同步的独立交付物,不属后端主链路
docs/ # kb/ 知识库 · update/ 变更记录 · api/ 接口契约,外加开发规范与快速开始
.claude/skills/deploy/ # 部署规范唯一入口:先定平台与角色,再读对应 references
根目录只放每台机器都要跑的生命周期入口(装、起、打物料);偶尔跑的工具进 scripts/。
- GPU:RTX 4090(推荐)或其他 CUDA 兼容 GPU;支持降级 CPU 模式(性能较低)
- 内存:≥ 16GB RAM
- 系统:Windows 10/11、Ubuntu 20.04+
- FFmpeg:视频解码(必需)
- MediaMTX:流媒体网关,内部 RTSP 18004,经网关对外 8004;二进制不随 git 分发,安装脚本从源机拉到项目内
- PostgreSQL:任务与告警持久化
- 环境变量:
.env/.env.dev/.env.test(CLEANSIGHT_前缀,单一真源app/settings.py) - 服务 YAML:
config/下inference_config.yaml、stream_config.yaml、persistence_config.yaml、recording_config.yaml、client_config.yaml、health_monitor_config.yaml - 日志:
config/logging.json(uvicorn dictConfig,路径硬编码、无环境变量开关) - Python 工具配置(pytest / 覆盖率):
pyproject.toml
部署(Linux / Windows / PPU 装环境、物料、
.env与端口)见/deployskill:.claude/skills/deploy/SKILL.md;开发规范(分支/测试/模块解耦)见 开发指南。
./start_backend.sh dev # Linux(加载 .env.dev)
.\start_backend.ps1 dev # Windows一条命令拉起 RTSP 网关(网关再拉起 MediaMTX)+ 后端,不要再单独起 MediaMTX。装环境走 ./install.sh / .\install.ps1,细节见 /deploy skill。
起流后打开后端自带的 admin 运维面板观测运行状态(实时画面 / 队列健康 / 指标 / 告警列表):http://localhost:8000/ui-f3m8/admin/。上手流程与接口调用示例见 快速开始指南。
- 启动任务和流:
POST /api/start(合并 load_task + start_stream) - 接收渲染画面:
WebSocket /ai/video?task_id={task_id}(或?client_id=<source_ip>点位模式;双模互斥、task_id优先) - 拉取增量消息:
GET /task/message/{task_id}(告警增量 + signals_10s) - 终止任务:
POST /api/terminate?task_id={task_id}(完整清理资源)
CleanSight 采用流 / 推理 / 持久化解耦架构,RunControlService 统一编排一次 run 的起停,运行键为 int task_id。
graph LR
A[RTSP 流] --> B[StreamService / FFmpegDecoder]
B --> C[ClientQueues]
C --> D[Inference:Detector 检测→特征聚合/落盘→Operator 时序判定 1Hz→可视化]
D --> E[RecordingService]
D --> F[WebSocket 前端轮询]
D --> H[AlarmService]
E --> G[HLS 视频段]
H --> I[告警落库/上报]
RTSP (30fps)
↓ [FFmpegDecoder 自持读循环,ffmpeg 输出规范化 CFR raw_fps]
ca_ready(SPSC 无锁 deque,Bresenham 抽帧至 inference_fps) ca_raw(完整录制缓冲)
↓ [Detector 检测 → 多流对齐成帧并落盘 detections.jsonl → Operator(~1Hz,analyze+judge 合一,状态在内存 _sm)出告警 → 可视化]
ca_processed → [HLS 分段:recording 周期 PULL 拉取整段]
_latest_rendered 快照 → [WebSocket 前端 ~10ms 轮询,非后端 push]
ca_ready:待推理帧,无锁 SPSC deque(decoder 单产 / dispatcher 单消)ca_raw/ca_processed:raw / processed HLS 纯缓冲,recording 主动拉取分段_latest_rendered/_latest_detection/_slide_window/_latest_temporal:渲染帧 / 推理快照 / 检测滑窗 / 时序事件
线程角色:检测(StageAwareDispatcher + 每 stage 推理线程,可选 CUDA Stream)、时序(ClientTemporalActor per-run ~1Hz)、可视化(独立线程)、录制(段 sweeper + 一条 SerialTaskQueue 消费线程)、持久化(Alarm Worker×1 + 清理 worker)。详见 知识库。
四层边界:L1 guarded_run()(app/services/utils/worker_guard.py)兜线程崩溃 → L2 告警上报重试/快速失败(app/services/alarm/alarm_worker.py)→ L3 FastAPI handler 转 HTTP → L4 main() 顶层 fail-fast。自定义异常(retryable/fatal 标记)在 app/types/exceptions.py;丢帧不走异常,由 frame_drop_total 指标计数。详见 知识库。
配置驱动的多阶段推理,检测点拆为无状态 Detector(流源)+ per-run Operator(流算子,analyze+judge 合并)。当前阶段(config/inference_config.yaml):
- LEAK(step
"1"):bubble(气泡,出生率滑窗 3s、birth_rate>0.5实时告警)+bending(弯折,去抖 5 帧、合格需 4 次弯曲,结算告警) - CLEAN(step
"2"):clean_large+clean_small检测 →clean_monitor(GRU 动作识别,10s 窗口,gru-final.pt)叠加动作事件;当前rules: []不产告警
各 stage 的 offline 块只含 class + params(离线分段 producer = 类名,缺省/空块 = 不可跑);CLEAN 默认启用 CleanNodepGRUSegmenter(权重 clean-offline-gru-nodep.pt)。
新增检测点:用 /infer-workflow skill 生成 Detector + Operator 框架,规范见 知识库。
pytest # 单元 & 组件测试
pytest --cov --cov-report=html # 覆盖率报告(app/ + mediamtx_gateway/)
# 端到端(需真实 RTSP;观测走 admin 面板 /ui-f3m8/admin/)
python integration_tests/test_single_client.py --scenario 1 --task_id 1 --duration 30
python integration_tests/test_single_client.py --scenario 1 --task_id 1 --duration 60 --server <host>
python integration_tests/test_multi_client.py --max-tasks 10 --duration 60 # 并发压力生产已永久关闭
/docs、/redoc、/openapi.json。所有 HTTP/WS 先经GatewayMiddleware(IP 白名单 / 限流 / 反扫描;路由接线见知识库)。下表为速览,端点请求/响应契约与用法见 docs/api/(按 router 分文件)。
| 分组 | 端点 |
|---|---|
| 统一 API | POST /api/start、POST /api/terminate(task_id/client_id 双模) |
| 实时推流 | WebSocket /ai/video?task_id=... |
| 消息 / 告警 | GET /task/message/{task_id}、GET /task/{task_id}/alarms |
| 追溯 | GET /traceback/task/{task_id}/playlist.m3u8、/traceback/task/{task_id}/timeline |
| 媒体 | GET /media/segment/{token}、/media/init/{token}(HMAC token 鉴权) |
| 健康 | GET /health/status、/health/monitor/stats、/health/monitor/config |
| 运维 / 送标 | /admin-f3m8/*、/lab-f3m8/* |
| 现象 | 排查 |
|---|---|
ffmpeg not found |
后端只认项目内 .ffmpeg/bin/ffmpeg,不回退系统 PATH;重跑 install.sh / install.ps1 从源机拉钉版 ffmpeg,别装系统版 |
| 数据库连接失败 | 检查 .env 数据库配置、服务是否运行、网络/防火墙 |
CUDA not available |
nvidia-smi 查驱动,torch.cuda.is_available() 验证;否则自动降级 CPU |
| 推流超时 / Stream not found | 确认 8004 与 18004 都在听(网关日志看 MediaMTX 是否起来)、URL rtsp://<host>:8004/live/<name> |
| WebSocket 断开 | 检查网络、客户端超时、后端日志 |
日志按模块 [Module] 前缀着色输出(config/logging.json)。更多帮助见 知识库 与 /deploy skill。
本项目采用 MIT 许可证。
- 从
dev切特性分支:git checkout -b feature/your-feature - 遵循 PEP 8,激活项目
.venv后pytest全绿 - 描述性文档改动同步进知识库
docs/kb/(维护规则见 KB_MAINTENANCE) - 推送并创建 Pull Request(base:
dev)
完整开发规范(分支提交、测试、模块内聚与解耦)见 开发指南。