feat: 建立 SAM2 标注闭环基线
- 打通工作区真实标注闭环:支持手工多边形、矩形、圆形、点区域和线段生成 mask,并可保存、回显、更新和删除后端 annotation。 - 增强 polygon 编辑器:支持顶点拖动、顶点删除、边中点插入、多 polygon 子区域选择编辑,以及区域合并和区域去除。 - 接入 GT mask 导入:后端支持二值/多类别 mask 拆分、contour 转 polygon、distance transform seed point,前端支持导入、回显和 seed point 拖动编辑。 - 完善导出能力:COCO JSON 导出对齐前端,PNG mask ZIP 同时包含单标注 mask、按 zIndex 融合的 semantic_frame 和 semantic_classes.json。 - 打通异步任务管理:新增任务取消、重试、失败详情接口与 Dashboard 控件,worker 支持取消状态检查并通过 Redis/WebSocket 推送 cancelled 事件。 - 对接 Dashboard 后端数据:概览统计、解析队列和实时流转记录从 FastAPI 聚合接口与 WebSocket 更新。 - 增强 AI 推理参数:前端发送 crop_to_prompt、auto_filter_background 和 min_score,后端支持点/框 prompt 局部裁剪推理、结果回映射和负向点/低分过滤。 - 接入 SAM3 基础设施:新增独立 Python 3.12 sam3 环境安装脚本、外部 worker helper、后端桥接和真实 Python/CUDA/包/HF checkpoint access 状态检测。 - 保留 SAM3 授权边界:当前官方 facebook/sam3 gated 权重未授权时状态接口会返回不可用,不伪装成可推理。 - 增强前端状态管理:新增 mask undo/redo 历史栈、AI 模型选择状态、保存状态 dirty/draft/saved 流转和项目状态归一化。 - 更新前端 API 封装:补充 annotation CRUD、GT mask import、mask ZIP export、task cancel/retry/detail、AI runtime status 和 prediction options。 - 更新 UI 控件:ToolsPalette、AISegmentation、VideoWorkspace 和 CanvasArea 接入真实操作、导入导出、撤销重做、任务控制和模型状态。 - 新增 polygon-clipping 依赖,用于前端区域 union/difference 几何运算。 - 完善后端 schemas/status/progress:补充 AI 模型外部状态字段、任务 cancelled 状态和进度事件 payload。 - 补充测试覆盖:新增后端任务控制、SAM3 桥接、GT mask、导出融合、AI options 测试;补充前端 Canvas、Dashboard、VideoWorkspace、ToolsPalette、API 和 store 测试。 - 更新 README、AGENTS 和 doc 文档:冻结当前需求/设计/测试计划,标注真实功能、剩余 Mock、SAM3 授权边界和后续实施顺序。
This commit is contained in:
30
AGENTS.md
30
AGENTS.md
@@ -6,7 +6,7 @@
|
||||
|
||||
## 项目概述
|
||||
|
||||
本项目是一个**语义分割系统**(Semantic Segmentation System),当前形态是 React 前端 + FastAPI 后端的全栈 Web 应用,用于视频/DICOM 医学影像上传、服务器端拆帧、交互式 Canvas 标注、SAM 2/SAM 3 可选辅助分割、模板分类管理和标注导出。
|
||||
本项目是一个**语义分割系统**(Semantic Segmentation System),当前形态是 React 前端 + FastAPI 后端的全栈 Web 应用,用于视频/DICOM 医学影像上传、服务器端拆帧、交互式 Canvas 标注、GT mask 导入、SAM 2/SAM 3 可选辅助分割、模板分类管理和标注导出。
|
||||
|
||||
- **项目名称**: `react-example`(`package.json` 中的 `name`)
|
||||
- **前端入口**: `src/main.tsx` → `src/App.tsx`
|
||||
@@ -30,6 +30,7 @@
|
||||
| 前端请求 | Axios(`src/lib/api.ts`) |
|
||||
| 实时通信 | WebSocket 客户端(`src/lib/websocket.ts`) |
|
||||
| Canvas 渲染 | Konva + react-konva + use-image |
|
||||
| 几何布尔运算 | polygon-clipping |
|
||||
| 图标库 | lucide-react |
|
||||
| 动画依赖 | motion(在 `package.json` 中声明) |
|
||||
| AI SDK 依赖 | `@google/genai`(在 `package.json` 中声明;当前业务源码未直接调用) |
|
||||
@@ -38,9 +39,9 @@
|
||||
| 缓存 / 队列 Broker | Redis |
|
||||
| 后台任务 | Celery worker |
|
||||
| 对象存储 | MinIO |
|
||||
| AI 推理 | SAM 2 / SAM 3 可选模型 + PyTorch;`GET /api/ai/models/status` 返回真实 GPU/模型状态 |
|
||||
| AI 推理 | SAM 2 / SAM 3 可选模型 + PyTorch;SAM 3 通过独立 Python 3.12 conda 环境桥接;`GET /api/ai/models/status` 返回真实 GPU/模型/HF 权重访问状态 |
|
||||
| 视频 / 影像处理 | FFmpeg / OpenCV / pydicom |
|
||||
| 运行时 | Node.js ES Modules;Python 3.11 后端环境 |
|
||||
| 运行时 | Node.js ES Modules;Python 3.11 后端环境;可选 `sam3` Python 3.12 conda 环境 |
|
||||
|
||||
---
|
||||
|
||||
@@ -70,6 +71,7 @@ Seg_Server/
|
||||
│ ├── celery_app.py # Celery app 配置
|
||||
│ ├── worker_tasks.py # Celery 任务入口
|
||||
│ ├── download_sam2.py # SAM 2 权重下载脚本
|
||||
│ ├── setup_sam3_env.sh # SAM 3 独立 Python 3.12 环境安装脚本
|
||||
│ ├── requirements.txt # Python 依赖
|
||||
│ ├── routers/
|
||||
│ │ ├── auth.py # /api/auth/login
|
||||
@@ -81,7 +83,8 @@ Seg_Server/
|
||||
│ └── services/
|
||||
│ ├── frame_parser.py # FFmpeg/OpenCV 拆帧、pydicom 读片、帧上传
|
||||
│ ├── sam2_engine.py # SAM 2 懒加载推理封装和 fallback
|
||||
│ ├── sam3_engine.py # SAM 3 状态检测与文本语义推理适配器
|
||||
│ ├── sam3_engine.py # SAM 3 状态检测、外部环境桥接与文本语义推理适配器
|
||||
│ ├── sam3_external_worker.py # 独立 sam3 conda 环境中执行的状态/推理 helper
|
||||
│ └── sam_registry.py # SAM 模型选择、GPU 状态与推理分发
|
||||
└── src/ # React 前端
|
||||
├── main.tsx # React StrictMode 挂载
|
||||
@@ -188,10 +191,13 @@ uvicorn main:app --host 0.0.0.0 --port 8000 --reload
|
||||
- `POST /api/media/parse`
|
||||
- `GET /api/tasks`
|
||||
- `GET /api/tasks/{task_id}`
|
||||
- `POST /api/tasks/{task_id}/cancel`
|
||||
- `POST /api/tasks/{task_id}/retry`
|
||||
- `POST /api/ai/predict`
|
||||
- `GET /api/ai/models/status`
|
||||
- `POST /api/ai/auto`
|
||||
- `POST /api/ai/annotate`
|
||||
- `POST /api/ai/import-gt-mask`
|
||||
- `GET /api/ai/annotations`
|
||||
- `PATCH/DELETE /api/ai/annotations/{annotation_id}`
|
||||
- `GET /api/dashboard/overview`
|
||||
@@ -216,9 +222,11 @@ uvicorn main:app --host 0.0.0.0 --port 8000 --reload
|
||||
4. 拆帧入队:前端调用 `/api/media/parse`;后端创建 `ProcessingTask` 并投递 Celery。
|
||||
5. worker 执行:Celery worker 用 FFmpeg 优先拆视频帧,失败后用 OpenCV fallback,DICOM 使用 pydicom,并持续更新任务进度。
|
||||
6. 帧展示:`VideoWorkspace.tsx` 调用 `/api/projects/{id}/frames`,`CanvasArea.tsx` 和 `FrameTimeline.tsx` 显示当前帧与时间轴缩略图。
|
||||
7. AI 分割:前端工具包括正向点、反向点和框选;后端 `ai.py` 期望按 `image_id`、`prompt_type`、`prompt_data`、`model` 调用 SAM registry。SAM 2 支持点/框/自动分割;SAM 3 入口支持文本语义推理,运行时不满足官方要求时会在状态接口中标为不可用。
|
||||
8. 模板管理:`TemplateRegistry.tsx` 管理分类、颜色和 z-index;`OntologyInspector.tsx` 在工作区显示当前模板分类树。
|
||||
9. 导出:后端支持 COCO JSON 和 PNG mask ZIP 导出。
|
||||
7. 手工标注:`CanvasArea.tsx` 支持多边形、矩形、圆、点区域和线段生成 polygon mask;点击 mask 可拖动/删除 polygon 顶点、通过边中点插入新顶点,并能选择编辑多 polygon mask 的单个子区域;区域合并/去除使用 `polygon-clipping` 做 union/difference;Zustand 维护 `maskHistory/maskFuture` 支持撤销/重做。
|
||||
8. AI 分割:前端工具包括正向点、反向点和框选;后端 `ai.py` 期望按 `image_id`、`prompt_type`、`prompt_data`、`model` 和可选 `options` 调用 SAM registry。SAM 2 支持点/框/自动分割;`options.crop_to_prompt` 可对点/框 prompt 做局部裁剪推理并回映射,`options.auto_filter_background` 可按分数和负向点过滤结果;SAM 3 入口支持文本语义推理,主后端会通过 `sam3_external_worker.py` 调用独立 Python 3.12 环境;如果 Python/CUDA/包/Hugging Face gated 权重访问任一条件不满足,会在状态接口中标为不可用。
|
||||
9. GT 导入:工作区“导入 GT Mask”调用 `/api/ai/import-gt-mask`;后端按非零像素值和连通域生成 polygon 标注,并用 distance transform 生成 seed point;前端回显 seed point,拖动后可归档更新。
|
||||
10. 模板管理:`TemplateRegistry.tsx` 管理分类、颜色和 z-index;`OntologyInspector.tsx` 在工作区显示当前模板分类树。
|
||||
11. 导出:后端支持 COCO JSON 和 PNG mask ZIP 导出;PNG ZIP 包含单标注 mask、按 zIndex 融合的语义 mask 和 `semantic_classes.json`。
|
||||
|
||||
---
|
||||
|
||||
@@ -226,12 +234,16 @@ uvicorn main:app --host 0.0.0.0 --port 8000 --reload
|
||||
|
||||
- `src/lib/config.ts` 会优先读取 `VITE_API_BASE_URL` 和 `VITE_WS_PROGRESS_URL`;未配置时按当前浏览器 hostname 推导后端 `:8000` 地址。
|
||||
- 前端 `predictMask()` 已按后端 `PredictRequest` 发送 `image_id`、`prompt_type`、`prompt_data`、`model`,并将后端 `polygons` 转成 Konva 可渲染的 `pathData`。
|
||||
- 前端 `exportCoco()` 已对齐后端 `/api/export/{project_id}/coco`;工作区“导出 JSON 标注集”按钮已绑定下载流程,导出前会先保存当前待归档 mask。
|
||||
- 手工绘制工具会生成可保存的 `Mask.segmentation`;撤销/重做通过 `maskHistory/maskFuture` 工作。
|
||||
- Polygon 顶点编辑会重算 `pathData/segmentation/bbox/area`;已保存 mask 进入 dirty 状态后复用归档 PATCH 链路。
|
||||
- 区域合并/去除会重算主 mask 的几何;合并已保存的次级 mask 时会通过工作区回调删除对应后端标注。
|
||||
- 前端 `importGtMask()` 已对齐后端 `/api/ai/import-gt-mask`;工作区“导入 GT Mask”会导入后端生成的多类别标注和 seed point 并回显。
|
||||
- 前端 `exportCoco()` 已对齐后端 `/api/export/{project_id}/coco`;前端 `exportMasks()` 已对齐后端 `/api/export/{project_id}/masks`;工作区导出按钮会先保存当前待归档 mask。
|
||||
- 工作区“结构化归档保存”按钮已接入 `POST /api/ai/annotate` 和 `PATCH /api/ai/annotations/{id}`;加载工作区时会通过 `GET /api/ai/annotations` 回显已保存标注。
|
||||
- 工作区“清空遮罩”会调用 `DELETE /api/ai/annotations/{id}` 删除当前帧已保存标注,并清空当前帧本地 mask。
|
||||
- 项目状态已统一为 `pending`、`parsing`、`ready`、`error`;前端 `src/lib/api.ts` 会兼容归一化旧库中可能存在的 `Ready`、`Parsing`、`Error`。
|
||||
- `server.ts` 仍有旧版 `/api/login`、`/api/projects`、`/api/templates` mock;当前前端真实 API 调用主要走 FastAPI 的 `/api/auth/*`、`/api/projects`、`/api/templates` 等接口。
|
||||
- `Dashboard.tsx` 初始统计、队列和活动日志来自 `GET /api/dashboard/overview`;解析队列来自 `processing_tasks`,Celery worker 通过 Redis pub/sub 的 `seg:progress` 频道推送细粒度进度,再由 FastAPI 广播到 `/ws/progress`。
|
||||
- `Dashboard.tsx` 初始统计、队列和活动日志来自 `GET /api/dashboard/overview`;解析队列来自 `processing_tasks`,支持取消 queued/running 任务、重试 failed/cancelled 任务和查看失败详情。Celery worker 通过 Redis pub/sub 的 `seg:progress` 频道推送细粒度进度,再由 FastAPI 广播到 `/ws/progress`。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user