feat: 打通全栈标注闭环、异步拆帧与模型状态
后端能力: - 新增 Celery app、worker task、ProcessingTask 模型、/api/tasks 查询接口和 media_task_runner,将 /api/media/parse 改为创建后台任务并由 worker 执行 FFmpeg/OpenCV/pydicom 拆帧。 - 新增 Redis 进度事件模块和 FastAPI Redis pub/sub 订阅,将 worker 任务进度广播到 /ws/progress;Dashboard 后端概览接口改为聚合 projects/frames/annotations/templates/processing_tasks。 - 统一项目状态为 pending/parsing/ready/error,新增共享 status 常量,并让前端兼容归一化旧状态值。 - 扩展 AI 后端:新增 SAM registry、SAM2 真实运行状态、SAM3 状态检测与文本语义推理适配入口,以及 /api/ai/models/status GPU/模型状态接口。 - 补齐标注保存/更新/删除、COCO/PNG mask 导出相关后端契约和模板 mapping_rules 打包/解包行为。 前端能力: - 新增运行时 API/WS 地址推导配置,前端 API 封装对齐 FastAPI 路由、字段映射、任务轮询、标注归档、导出下载和 AI 预测响应转换。 - Dashboard 改为读取 /api/dashboard/overview,并订阅 WebSocket progress/complete/error/status 更新解析队列和实时流转记录。 - 项目库导入视频/DICOM 后创建项目、上传媒体、触发异步解析并刷新真实项目列表。 - 工作区加载真实帧、无帧时触发解析任务、回显已保存标注、保存未归档 mask、更新 dirty mask、清空当前帧后端标注、导出 COCO JSON。 - Canvas 支持当前帧点/框提示调用后端 AI、渲染推理/已保存 mask、应用模板分类并维护保存状态计数;时间轴按项目 fps 播放。 - AI 页面新增 SAM2/SAM3 模型选择,预测请求携带 model;侧边栏和工作区新增真实 GPU/SAM 状态徽标。 - 模板库和本体面板接入真实模板 CRUD、分类编辑、拖拽排序、JSON 导入、默认腹腔镜分类和本地自定义分类选择。 测试与文档: - 新增 Vitest 配置、前端测试 setup、API/config/websocket/store/组件测试,覆盖登录、项目库、Dashboard、Canvas、工作区、模型状态、时间轴、本体和模板库。 - 新增 pytest 后端测试夹具和 auth/projects/templates/media/AI/export/dashboard/tasks/progress 测试,使用 SQLite、fake MinIO、fake SAM registry 和 Redis monkeypatch 隔离外部服务。 - 新增 doc/ 文档结构,冻结当前需求、设计、接口契约、测试计划、前端逐元素审计、实现地图和后续实施计划,并同步更新 README 与 AGENTS。 验证: - conda run -n seg_server pytest backend/tests:27 passed。 - npm run test:run:54 passed。 - npm run lint、npm run build、compileall、git diff --check 均通过;Vite 仅提示大 chunk 警告。
This commit is contained in:
128
README.md
128
README.md
@@ -4,16 +4,16 @@
|
||||
|
||||
# 语义分割系统(SegServer)
|
||||
|
||||
> 基于 React + FastAPI + SAM 2 的全栈交互式图像/视频语义分割与标注平台。
|
||||
> 基于 React + FastAPI + 可选 SAM 2 / SAM 3 的全栈交互式图像/视频语义分割与标注平台。
|
||||
>
|
||||
> 支持本地多媒体资产上传、服务器端按帧解析、AI 视觉大模型实时推理(正反向选点、框选生成分割 Mask)、动态图层状态管理及最终标注数据结构化导出。
|
||||
> 支持本地多媒体资产上传、服务器端按帧解析、交互式 Canvas 标注、模板分类管理和标注数据结构化导出;工作区点/框 AI 推理默认走 SAM 2,语义文本可选择 SAM 3,前端会显示真实 GPU/模型状态。
|
||||
|
||||
---
|
||||
|
||||
## 核心功能
|
||||
|
||||
- **多媒体资产管理** — 支持视频(MP4/AVI/MOV)和 DICOM 医学影像的上传、存储与解析
|
||||
- **AI 智能分割引擎** — 集成 SAM 2 模型,支持点分割(point)、框分割(box)、语义分割(semantic)和自动分割(auto)
|
||||
- **AI 智能分割引擎** — 后端提供 SAM 2 / SAM 3 模型选择;SAM 2 支持点分割(point)、框分割(box)和自动分割(auto),SAM 3 入口支持文本语义提示并按真实运行环境显示可用性
|
||||
- **交互式画布标注** — 基于 Konva 的高性能 Canvas,支持缩放/平移/选点/框选,实时渲染 Mask 遮罩
|
||||
- **本体字典管理** — 可配置的分类体系、颜色映射、图层优先级(z-index)
|
||||
- **项目工作区** — 项目创建、帧浏览、多图层标注、进度追踪
|
||||
@@ -37,15 +37,16 @@
|
||||
│ ├── /api/auth 登录认证 │
|
||||
│ ├── /api/projects 项目 & 视频帧 CRUD │
|
||||
│ ├── /api/templates 本体字典(分类/颜色/z-index) │
|
||||
│ ├── /api/media 文件上传 & FFmpeg/pydicom 帧解析 │
|
||||
│ ├── /api/ai SAM 2 推理(点/框/语义/自动分割) │
|
||||
│ ├── /api/media 文件上传 & 异步拆帧任务创建 │
|
||||
│ ├── /api/tasks Celery 后台任务状态 │
|
||||
│ ├── /api/ai SAM 2 / SAM 3 推理与模型状态 │
|
||||
│ └── /api/export COCO JSON / PNG Masks 导出 │
|
||||
└──────────────────────────┬──────────────────────────────────┘
|
||||
│ SQLAlchemy 2.0
|
||||
┌──────────────────────────▼──────────────────────────────────┐
|
||||
│ 数据持久化层 │
|
||||
│ PostgreSQL 14 — 项目/帧/标注/Mask 元数据 │
|
||||
│ Redis 6 — 缓存 & 任务队列状态 │
|
||||
│ PostgreSQL 14 — 项目/帧/标注/Mask/Task 元数据 │
|
||||
│ Redis 6 — Celery broker/result backend + 进度 pub/sub │
|
||||
│ MinIO — 对象存储(原始视频/解析帧/Mask图像) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -63,11 +64,12 @@
|
||||
| Canvas 渲染 | Konva + react-konva | - |
|
||||
| HTTP 客户端 | Axios | - |
|
||||
| 后端框架 | FastAPI | v0.136+ |
|
||||
| 数据库 ORM | SQLAlchemy + Alembic | 2.0+ |
|
||||
| 数据库 ORM | SQLAlchemy(依赖中包含 Alembic) | 2.0+ |
|
||||
| 数据库 | PostgreSQL | 14 |
|
||||
| 缓存 | Redis | 6 |
|
||||
| 队列 Broker | Redis | 6 |
|
||||
| 后台任务 | Celery worker | 5.6+ |
|
||||
| 对象存储 | MinIO | 2025+ |
|
||||
| AI 推理 | SAM 2 (Meta) + PyTorch | - |
|
||||
| AI 推理 | SAM 2 / SAM 3 (Meta) + PyTorch | - |
|
||||
| 视频处理 | FFmpeg + OpenCV | 4.4+ |
|
||||
| DICOM 处理 | pydicom | 3.0+ |
|
||||
|
||||
@@ -78,13 +80,17 @@
|
||||
```
|
||||
Seg_Server/
|
||||
├── backend/ # FastAPI 后端
|
||||
│ ├── main.py # 应用入口(CORS/生命周期/路由注册)
|
||||
│ ├── main.py # 应用入口(CORS/生命周期/路由注册/WebSocket)
|
||||
│ ├── config.py # 环境变量配置(Pydantic Settings)
|
||||
│ ├── database.py # SQLAlchemy 引擎 + Session
|
||||
│ ├── models.py # ORM 模型(Project/Frame/Template/Annotation/Mask)
|
||||
│ ├── models.py # ORM 模型(Project/Frame/Template/Annotation/Mask/ProcessingTask)
|
||||
│ ├── schemas.py # Pydantic 请求/响应校验模型
|
||||
│ ├── minio_client.py # MinIO 上传/下载/预签名URL封装
|
||||
│ ├── redis_client.py # Redis 连接封装
|
||||
│ ├── progress_events.py # 任务进度事件 payload 与 Redis 发布
|
||||
│ ├── statuses.py # 项目/任务状态常量
|
||||
│ ├── celery_app.py # Celery app 配置
|
||||
│ ├── worker_tasks.py # Celery 任务入口
|
||||
│ ├── download_sam2.py # SAM 2 模型权重自动下载脚本
|
||||
│ ├── requirements.txt # Python 依赖
|
||||
│ ├── routers/ # API 路由
|
||||
@@ -92,10 +98,12 @@ Seg_Server/
|
||||
│ │ ├── projects.py # 项目 & 帧 CRUD
|
||||
│ │ ├── templates.py # 本体字典管理
|
||||
│ │ ├── media.py # 上传 & 解析
|
||||
│ │ ├── ai.py # SAM 2 推理接口
|
||||
│ │ ├── ai.py # SAM 推理与模型状态接口
|
||||
│ │ └── export.py # 数据导出
|
||||
│ └── services/ # 业务服务
|
||||
│ ├── sam2_engine.py # SAM 2 推理引擎(懒加载 + stub降级)
|
||||
│ ├── sam3_engine.py # SAM 3 状态检测与文本语义推理适配器
|
||||
│ ├── sam_registry.py # SAM 模型选择、GPU 状态与推理分发
|
||||
│ └── frame_parser.py # FFmpeg 拆帧 / pydicom 读片
|
||||
├── src/ # React 前端
|
||||
│ ├── main.tsx # 应用挂载点
|
||||
@@ -121,8 +129,11 @@ Seg_Server/
|
||||
├── models/ # SAM 2 模型权重(.pt 文件)
|
||||
├── uploads/ # 临时上传目录
|
||||
├── frames/ # 临时帧目录
|
||||
├── doc/ # 当前实现审计、接口契约与后续实施文档
|
||||
├── public/
|
||||
│ └── logo.png # 侧边栏 Logo 静态资源
|
||||
├── start_services.sh # 一键启动所有服务脚本
|
||||
├── server.ts # 旧版 Express 入口(已弃用)
|
||||
├── server.ts # Express + Vite 前端入口(也保留少量旧版 mock API)
|
||||
├── index.html # SPA HTML 入口
|
||||
├── vite.config.ts # Vite 构建配置
|
||||
├── package.json # npm 依赖与脚本
|
||||
@@ -131,12 +142,23 @@ Seg_Server/
|
||||
|
||||
---
|
||||
|
||||
## 项目文档
|
||||
|
||||
当前实现审计与接口契约文档在 `doc/` 目录:
|
||||
|
||||
- `doc/01-purpose-and-word-summary.md` — 项目目的、Word 方案摘要与当前落地程度
|
||||
- `doc/03-frontend-element-audit.md` — 前端逐元素功能审计,标注真实可用、部分可用、Mock/UI-only、接口不通
|
||||
- `doc/04-api-contracts.md` — 前后端接口契约和已知不一致
|
||||
- `doc/06-fastapi-docs-explained.md` — `http://192.168.3.11:8000/docs` 的作用说明
|
||||
|
||||
---
|
||||
|
||||
## 环境准备
|
||||
|
||||
### 系统要求
|
||||
|
||||
- **OS**: Ubuntu 22.04 LTS
|
||||
- **GPU**: NVIDIA GPU(推荐 RTX 4090 或同等算力),用于 SAM 2 推理
|
||||
- **GPU**: NVIDIA GPU(推荐 RTX 4090 或同等算力),用于 SAM 推理;SAM 3 官方要求 Python 3.12+、PyTorch 2.7+ 和 CUDA 12.6+ 环境
|
||||
- **CUDA**: 12.x / 13.x
|
||||
- **Node.js**: 22.x+
|
||||
- **Python**: 3.11(通过 Miniconda/Anaconda 管理)
|
||||
@@ -223,19 +245,32 @@ python download_sam2.py
|
||||
|
||||
### 步骤 5: 配置环境变量
|
||||
|
||||
项目根目录已提供默认配置,如需修改请编辑以下文件:
|
||||
后端通过 `backend/config.py` 中的 Pydantic Settings 读取 `backend/.env`。如需覆盖默认值,请编辑以下文件:
|
||||
|
||||
**backend/.env**(数据库/Redis/MinIO/SAM 路径):
|
||||
```ini
|
||||
DATABASE_URL=postgresql://seguser:segpass123@localhost:5432/segserver
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
MINIO_ENDPOINT=localhost:9000
|
||||
MINIO_ACCESS_KEY=minioadmin
|
||||
MINIO_SECRET_KEY=minioadmin
|
||||
MINIO_BUCKET_NAME=seg-media
|
||||
SAM2_MODEL_PATH=/home/wkmgc/Desktop/Seg_Server/models/sam2_hiera_tiny.pt
|
||||
db_url=postgresql://seguser:segpass123@localhost:5432/segserver
|
||||
redis_url=redis://localhost:6379/0
|
||||
minio_endpoint=192.168.3.11:9000
|
||||
minio_access_key=minioadmin
|
||||
minio_secret_key=minioadmin
|
||||
minio_secure=false
|
||||
sam_model_path=/home/wkmgc/Desktop/Seg_Server/models/sam2_hiera_tiny.pt
|
||||
sam_model_config=configs/sam2/sam2_hiera_t.yaml
|
||||
sam_default_model=sam2
|
||||
sam3_model_version=sam3.1
|
||||
cors_origins=["http://localhost:3000","http://192.168.3.11:3000"]
|
||||
```
|
||||
|
||||
前端根目录的 `.env.example` 包含 AI Studio 注入变量和前端 API 配置:
|
||||
|
||||
```ini
|
||||
VITE_API_BASE_URL=http://192.168.3.11:8000
|
||||
VITE_WS_PROGRESS_URL=ws://192.168.3.11:8000/ws/progress
|
||||
```
|
||||
|
||||
如果未配置 `VITE_API_BASE_URL`,前端会按当前浏览器 hostname 推导 `http://<host>:8000`。
|
||||
|
||||
### 步骤 6: 启动后端服务
|
||||
|
||||
```bash
|
||||
@@ -252,7 +287,21 @@ nohup uvicorn main:app --host 0.0.0.0 --port 8000 > /tmp/fastapi.log 2>&1 &
|
||||
- 创建数据库表(如果不存在)
|
||||
- 检查 MinIO bucket 是否存在
|
||||
- 测试 Redis 连接
|
||||
- 懒加载 SAM 2 模型(权重存在且 sam2 包已安装时)
|
||||
- 懒加载 SAM 模型;`GET /api/ai/models/status` 会返回 SAM 2、SAM 3 与 GPU 的真实可用状态
|
||||
|
||||
### 步骤 6.1: 启动 Celery Worker
|
||||
|
||||
```bash
|
||||
cd ~/Desktop/Seg_Server/backend
|
||||
source ~/miniconda3/etc/profile.d/conda.sh
|
||||
conda activate seg_server
|
||||
celery -A celery_app:celery_app worker --loglevel=info --concurrency=1
|
||||
|
||||
# 或使用后台模式
|
||||
nohup celery -A celery_app:celery_app worker --loglevel=info --concurrency=1 > /tmp/celery.log 2>&1 &
|
||||
```
|
||||
|
||||
`POST /api/media/parse` 只创建 `processing_tasks` 记录并把任务投递给 Celery;真正的 FFmpeg/OpenCV/pydicom 拆帧由 worker 执行。worker 每次更新任务状态后会发布到 Redis `seg:progress` 频道,FastAPI 订阅后转发到 `/ws/progress`,前端 Dashboard 可实时更新。
|
||||
|
||||
### 步骤 7: 安装前端依赖并构建
|
||||
|
||||
@@ -286,7 +335,7 @@ cd ~/Desktop/Seg_Server
|
||||
./start_services.sh
|
||||
```
|
||||
|
||||
脚本将依次检查并启动:PostgreSQL → Redis → MinIO → FastAPI 后端 → 前端。
|
||||
脚本将依次检查并启动:PostgreSQL → Redis → MinIO → FastAPI 后端 → Celery Worker → 前端。
|
||||
|
||||
---
|
||||
|
||||
@@ -307,10 +356,12 @@ cd ~/Desktop/Seg_Server
|
||||
|
||||
```bash
|
||||
npm install # 安装依赖
|
||||
npm run dev # Vite 开发模式(端口 5173)
|
||||
npm run dev # 运行 tsx server.ts,Express + Vite 中间件(端口 3000)
|
||||
npm run build # 生产构建(输出到 dist/)
|
||||
npm run lint # TypeScript 类型检查
|
||||
npm start # Node.js 运行 server.ts(旧版)
|
||||
npm run test # Vitest watch 模式
|
||||
npm run test:run # Vitest 单次运行
|
||||
npm start # Node.js 运行 server.ts(生产静态服务 / 旧版 mock API)
|
||||
```
|
||||
|
||||
### 后端
|
||||
@@ -318,8 +369,11 @@ npm start # Node.js 运行 server.ts(旧版)
|
||||
```bash
|
||||
# 在 conda seg_server 环境中
|
||||
cd backend
|
||||
pip install -r requirements-dev.txt # 安装后端测试依赖
|
||||
pytest tests # 后端接口测试
|
||||
uvicorn main:app --host 0.0.0.0 --port 8000 --reload # 开发模式(热重载)
|
||||
uvicorn main:app --host 0.0.0.0 --port 8000 # 生产模式
|
||||
celery -A celery_app:celery_app worker --loglevel=info --concurrency=1 # 后台任务 worker
|
||||
```
|
||||
|
||||
---
|
||||
@@ -375,7 +429,25 @@ pip install -e . --no-build-isolation
|
||||
**检查清单**:
|
||||
1. 后端是否已启动(`curl http://localhost:8000/health`)
|
||||
2. `backend/.env` 中的 `cors_origins` 是否包含 `http://localhost:3000`
|
||||
3. 前端 `src/lib/api.ts` 中的 `baseURL` 是否为 `http://localhost:8000`
|
||||
3. 前端是否配置了正确的 `VITE_API_BASE_URL`;未配置时会按当前浏览器 hostname 推导 `http://<host>:8000`
|
||||
|
||||
### Q5: 如何验证 AI 推理或 COCO 导出接口
|
||||
|
||||
**当前状态**:
|
||||
|
||||
- 前端 `predictMask()` 已发送后端需要的 `image_id`、`prompt_type`、`prompt_data`,并把后端 `polygons` 转成 Konva `pathData`。
|
||||
- 工作区点选/框选会使用当前帧的数据库 `frame.id` 调用 `/api/ai/predict`。
|
||||
- 前端 `exportCoco()` 已对齐到 `/api/export/{projectId}/coco`。
|
||||
- 工作区“导出 JSON 标注集”按钮已绑定下载流程;导出前会先保存当前待归档的前端 mask。
|
||||
- 工作区“结构化归档保存”按钮会把当前项目未保存 mask 写入 `POST /api/ai/annotate`,并把 dirty mask 写入 `PATCH /api/ai/annotations/{id}`。
|
||||
- 工作区“清空遮罩”会通过 `DELETE /api/ai/annotations/{id}` 删除当前帧已保存标注,并清空当前帧本地 mask。
|
||||
|
||||
**验证**:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/health
|
||||
curl http://localhost:8000/api/export/1/coco
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user