Files
Pre_Seg_Server/doc/05-implementation-plan.md
admin 481ffa5b67 完善项目导入、模板与分割工作区交互
- 增强 DICOM/视频项目导入与演示数据:DICOM 按文件名自然顺序处理,导入后展示上传与解析任务进度,恢复演示出厂设置保留演示视频和演示 DICOM 项目,并补充 demo media seed 逻辑。

- 完善项目管理:项目支持重命名、删除、复制,删除使用站内确认弹窗,复制支持新项目重置和全内容复制,DICOM 项目不显示生成帧入口。

- 完善 GT Mask 与导出链路:只支持 8-bit maskid 图导入,非法/全背景图明确拒绝,尺寸自动适配,高精度 polygon 回显;统一导出默认当前帧,GT_label 使用 uint8 和真实 maskid,待分类 maskid 0 与背景一致。

- 完善分割工作区交互:新增画笔和橡皮擦并支持尺寸控制,移除创建点/线段入口,工具栏按类别分隔,AI 智能分割使用明确 AI 图标,取消黄色 seed point,清空/删除传播 mask 后同步清理空帧时间轴状态。

- 完善传播与时间轴:自动传播使用 SAM 2.1 权重任务,参考帧无遮罩时提示,传播历史按同一蓝色系递进变暗,删除/清空传播链时保留人工或独立 AI 标注来源。

- 完善模板库:新增头颈部 CT 分割默认模板,所有模板保留 maskid 0 待分类,支持鼠标复制模板、拖拽层级、JSON 批量导入预览、删除 label 和站内删除确认。

- 完善用户与高风险确认:用户改密码、删除用户、恢复演示出厂设置和清空人工/AI 标注帧均改为站内确认交互,避免浏览器原生 prompt/confirm。

- 补充前后端测试与文档:更新项目、模板、GT 导入、导出、传播、DICOM、用户管理等测试,并同步 README、AGENTS 和 doc 下实现/契约/测试计划文档。
2026-05-03 17:11:59 +08:00

158 lines
8.8 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.
# 后续实施建议
目标是把当前“能看、能上传、能拆帧”的系统推进到“能真实完成标注闭环”的系统。
## 阶段 1先修接口契约已完成基础对齐
优先级最高。AI 点/框推理和 COCO 导出的基础契约已经按当前代码完成对齐。
已完成:
1. `src/lib/api.ts``updateProject()` 已改为 `PATCH`
2. `exportCoco()` 路径已改为 `/api/export/{projectId}/coco`
3. Canvas 调 AI 时已使用当前帧真实 `frame.id` 作为 `image_id`
4. Canvas 点/框坐标已转成后端需要的归一化坐标。
5. 后端 `polygons` 已转成前端可渲染的 Konva path。
剩余边界:
1. SAM 3 相关源码和安装脚本保留,但当前产品入口已禁用:前端不展示 SAM 3后端 registry 不暴露 `sam3``model=sam3` 请求返回不支持。若后续重新需要文本语义提示再恢复前端入口、registry、状态接口和对应测试。
2. 标注删除/更新接口已打通基础能力;逐点几何编辑器已支持顶点拖动/删除、边中点插入和多 polygon 子区域选择编辑,复杂洞结构仍待增强。
## 阶段 2打通标注保存已完成基础闭环
当前工作区可将未保存 mask 写入后端标注表,并在加载项目帧后回显。
已完成:
1. 前端根据 `Mask.segmentation` 构造后端需要的 normalized `mask_data.polygons`
2. 用户点击顶栏保存状态按钮后,未保存 mask 调用 `POST /api/ai/annotate`dirty mask 调用 `PATCH /api/ai/annotations/{annotation_id}`;按钮文案会按待保存数量显示“保存 X 个改动”或“已全部保存”。
3. 后端保存或更新 `project_id``frame_id``template_id``mask_data``bbox`;具体分类写入 `mask_data.class`
4. 工作区加载帧后调用 `GET /api/ai/annotations` 回显已保存标注。
5. 工作区“清空遮罩”调用 `DELETE /api/ai/annotations/{annotation_id}` 删除当前帧已保存标注。
剩余建议:
1. 加入保存冲突处理和批量保存错误提示。
2. 逐点几何编辑器已支持拖动/删除顶点、边中点插入新点和多 polygon 子区域编辑;后续增强为复杂洞结构编辑。
3. 区域合并/去除已支持基础 union/difference后续增强为更明确的多选列表、操作预览和冲突确认。
## 阶段 3接入导出按钮已完成统一分割结果导出
当前工作区“分割结果导出”会先保存未归档 mask再调用后端统一结果导出接口。旧 COCO JSON 和 PNG Mask ZIP 接口保留为兼容路径。
已完成:
1. COCO JSON 调用 `/api/export/{projectId}/coco`
2. PNG Mask ZIP 调用 `/api/export/{projectId}/masks`
3. 兼容 PNG Mask ZIP 仍保留单标注二值 `mask_*.png`,同时输出 `semantic_frame_*.png``semantic_classes.json`
4. 统一导出调用 `/api/export/{projectId}/results`,支持整体视频、特定范围帧、当前图片三种范围,以及分开 mask、GT_label 黑白图、Pro_label 彩色图和 Mix_label 原图叠加图ZIP 固定包含 maskid/GT 像素值映射 JSON 和原始图片文件夹,各输出文件夹按客户指定的 `视频名称_0h00m00s000ms_项目帧序号` 规则命名GT_label 图固定为 8-bit uint8 PNG背景为 0类别值优先使用模板中的真实 maskid其中 `maskid:0` 的“待分类”和背景同为 0缺失 maskid 的旧标注才补下一个可用正整数,正整数 maskid 超出 1-255 会拒绝导出。
剩余建议:
1. 无标注时给出更明确的空导出提示。
## 阶段 4替换 Dashboard mock
当前 Dashboard 已通过 `GET /api/dashboard/overview` 读取后端聚合快照,不再使用硬编码初始统计、队列或活动日志。
已完成:
- 聚合项目、帧、标注、模板数量和主机 load average。
-`processing_tasks` queued/running/failed/cancelled 任务生成解析队列。
- 按最近任务、项目、标注、模板记录生成活动流。
已完成补充:
1. Dashboard 对 queued/running 任务提供取消按钮。
2. Dashboard 对 failed/cancelled 任务提供重试按钮。
3. Dashboard 详情弹窗展示任务 error、payload、result、Celery ID 和时间。
剩余建议:
1. 为 Dashboard 增加任务历史筛选。
## 阶段 5异步拆帧和进度
Word 方案中提到 Celery + Redis。当前已经有 Celery app、worker task 和 `processing_tasks` 表。
已完成:
1. 新建 Celery app。
2. `POST /api/media/parse` 只创建任务并立即返回 task id。
3. worker 执行 FFmpeg/OpenCV/pydicom。
4. worker 写 PostgreSQL 任务进度。
5. worker 发布 Redis `seg:progress`FastAPI 广播到 `/ws/progress`
已完成补充:
1. `POST /api/tasks/{task_id}/cancel` 取消 queued/running 任务,并尝试 revoke Celery。
2. `POST /api/tasks/{task_id}/retry` 为 failed/cancelled 任务创建新的 queued 任务。
3. worker 在关键阶段检查 cancelled 状态,避免取消后继续写帧。
4. Redis/WebSocket 进度事件增加 `cancelled` 类型。
Dashboard 的解析队列现在已经从“项目状态派生”升级为任务表驱动,实时推送也已通过 Redis/WebSocket 打通;剩余重点是任务历史筛选和更细的 worker 中断粒度。
## 阶段 6GT 导入与点区域(已完成基础增强版)
Word 方案中的完整版本包含距离变换、骨架提取和聚类。当前已经完成基础增强版:导入二值/标签 mask 图片后,后端按非零像素值拆分类别,再按连通域生成高精度 polygon 标注;导入结果与普通 mask 共用拓扑统计、边缘平滑、编辑和保存链路,前端不显示或拖动 seed point。
已完成:
1. 工作区左侧工具栏提供“导入 GT Mask”入口位置在“重叠区域去除”之后。
2. 前端调用 `POST /api/ai/import-gt-mask` multipart 接口。
3. 后端按非零像素值拆分多类别 mask。
4. 后端使用 OpenCV 高精度 contour 提取每个类别下的连通域,尽量保留边界细节,并用点数上限保护前端性能。
5. 后端保留 distance transform `points` seed 供数据兼容。
6. 导入结果写入 `annotations` 表并回显为工作区 mask。
7. 前端不显示 seed point也不提供 seed point 拖动;导入 mask 与普通 mask 保持一致的可选中、顶点编辑、拓扑统计、边缘平滑和保存体验。
剩余建议:
1. 增加骨架提取和聚类增强。
2. 为多类别像素值提供模板分类自动映射规则。
## 阶段 7模板优先级融合已完成导出侧裁决
当前导出 PNG Mask ZIP 时已经按 class/template z-index 做重叠裁决,从低到高覆盖,生成每帧 `semantic_frame_*.png`
已完成:
1. 标注保存时记录 template class id / name / maskid并保留内部覆盖优先级。
2. 导出 mask 时按内部优先级从低到高覆盖。
3. 同类语义值在融合图中共享同一个 class value。
4. 跨类重叠由更高内部优先级覆盖更低内部优先级maskid 不作为排序规范。
剩余建议:
1. 在前端预览重叠裁决结果。
2. 对多帧多类导出增加颜色 palette PNG 或可视化 legend。
## 阶段 7.5:视频片段传播(已完成基础闭环)
当前工作区传播功能会使用当前打开参考帧的全部 mask 作为 seed按用户设置的传播起始帧和传播结束帧向前、向后或双向传播并把结果写入后端标注表。前端只保留一个“自动传播”按钮减少传播对象选择带来的歧义。
已完成:
1. 前端 `propagateMasks()` 已接入 `POST /api/ai/propagate`
2. 工作区会把 seed mask 的 normalized polygon、bbox、label、color 和 class 元数据传给后端。
3. SAM 2 路径使用官方 `SAM2VideoPredictor.add_new_mask()``propagate_in_video()`
4. SAM 3 video tracker 路径已从当前产品入口禁用,相关 helper 仅保留作后续恢复参考。
5. 后端会跳过源帧,把传播结果保存到后续帧 `annotations`,并在完成后由前端刷新回显。
6. 前端已经支持参考帧、起止帧范围和单按钮自动传播;多个 seed 或前后双向范围会拆成多次顺序调用单 seed 后端接口。
剩余建议:
1. 把传播任务改为异步任务,接入 Dashboard 和 WebSocket 进度。
2. 增加覆盖已有标注策略设置,例如跳过已有、覆盖同类、全部覆盖。
3. 用真实长视频做 SAM 2 tracker smoke test 和质量评估;如果未来恢复 SAM 3再单独补充 SAM 3 tracker 评估。
## 阶段 8清理 UI 文案与 Mock
建议统一这些文案和真实能力:
- SAM/GPU 状态已改为 `GET /api/ai/models/status` 驱动。
- 撤销/重做按钮已接全局 mask 历史栈。
- “重新提取内侧中轴树骨架”接真实接口,否则标为未实现。
- AI 独立页已移除固定 Unsplash 演示图;没有当前项目帧时显示空状态。后续如果要支持独立图片分析,应接正式上传入口和项目/帧关联。