2026-05-20-01-38-33 完善NII导出与位姿持久化
This commit is contained in:
71
工程分析/实现方案-2026-05-20-01-38-33.md
Normal file
71
工程分析/实现方案-2026-05-20-01-38-33.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# 实现方案-2026-05-20-01-38-33
|
||||
|
||||
## 实现方案文档路径
|
||||
|
||||
`工程分析/实现方案-2026-05-20-01-38-33.md`
|
||||
|
||||
## 修改目标
|
||||
|
||||
完善逆向工作区导出与位姿持久化:移除自动配准演示入口,新增可选导出 DICOM NIfTI、分割 NIfTI 和位姿 JSON,修复 blob 下载警告,增加三维坐标轴示意,并让保存位姿跨项目进入持久保留。
|
||||
|
||||
## 涉及路径
|
||||
|
||||
- `WebSite/server.ts`
|
||||
- `WebSite/src/lib/api.ts`
|
||||
- `WebSite/src/types.ts`
|
||||
- `WebSite/src/components/ReverseWorkspace.tsx`
|
||||
- `工程分析/需求分析-2026-05-20-01-38-33.md`
|
||||
- `工程分析/实现方案-2026-05-20-01-38-33.md`
|
||||
- `工程分析/测试方案-2026-05-20-01-38-33.md`
|
||||
- `工程分析/经验记录.md`
|
||||
|
||||
## 技术路线
|
||||
|
||||
1. 后端扩展项目状态:
|
||||
- 增加 `modelPoses` 字段,保存默认、俯视、侧视与用户自定义位姿。
|
||||
- 新增 `PATCH /api/projects/:projectId/model-poses`。
|
||||
2. 后端重写导出:
|
||||
- 新增通用 NIfTI-1 写入函数。
|
||||
- DICOM 原始影像导出为 int16 HU `.nii.gz`,维度与 spacing 来自 DICOM。
|
||||
- 分割影像导出为 STL 构件采样切面填充后的 uint8 label map `.nii.gz`,维度与 spacing 与 DICOM 完全一致。
|
||||
- 位姿数据导出为 JSON,并记录导出时的当前 activePose。
|
||||
- 保留 `/export-mask` 兼容旧分割导出。
|
||||
3. 前端下载方式:
|
||||
- 用直链 `<a href>` 下载替代 `fetch -> Blob -> URL.createObjectURL`。
|
||||
- 新增导出选项复选框和“导出所选”动作,分割和位姿导出会携带当前模型位姿。
|
||||
4. UI 调整:
|
||||
- 去掉“开始自动配准”按钮和相关演示进度状态。
|
||||
- 顶部按钮改为“导出全部 NII.GZ”。
|
||||
- 三维融合视角右下角增加固定 XYZ 坐标轴示意。
|
||||
5. 位姿持久化:
|
||||
- 项目加载时读取 `project.modelPoses`。
|
||||
- 保存/重命名位姿时写回后端。
|
||||
|
||||
## 执行步骤
|
||||
|
||||
- 更新类型定义和后端状态归一化。
|
||||
- 实现 NIfTI/位姿导出接口。
|
||||
- 更新前端 API 下载方法。
|
||||
- 更新 ReverseWorkspace UI、导出选项、位姿保存逻辑和坐标轴。
|
||||
- 执行 `npm run lint` 与 `npm run build`。
|
||||
- 验证新导出接口返回文件,重新部署并推送。
|
||||
|
||||
## 兼容性与回滚方案
|
||||
|
||||
- 旧 `downloadMask` 与 `/export-mask` 保持可用,只把底层分割 NIfTI 改为同维度数据。
|
||||
- 如果完整 DICOM NIfTI 导出耗时过高,可后续增加范围导出或后台任务。
|
||||
- 如果浏览器仍对 HTTP 下载提示安全警告,需要部署 HTTPS;本次先消除 blob URL 警告来源。
|
||||
|
||||
## 预计文件变更
|
||||
|
||||
- `server.ts`:项目位姿字段、DICOM NIfTI 导出、STL Label Map 导出、位姿导出、兼容旧导出。
|
||||
- `api.ts`:直链下载和导出选项 API。
|
||||
- `types.ts`:项目位姿类型。
|
||||
- `ReverseWorkspace.tsx`:移除自动配准、导出选项、坐标轴、位姿持久化。
|
||||
- 新增本次三份工程文档,更新经验记录。
|
||||
|
||||
## 提交与部署策略
|
||||
|
||||
- 提交信息:`2026-05-20-01-38-33 完善NII导出与位姿持久化`
|
||||
- 显式暂存本次相关文件,避免提交历史删除状态。
|
||||
- 推送到 Gitea `origin/main` 并重新部署。
|
||||
59
工程分析/测试方案-2026-05-20-01-38-33.md
Normal file
59
工程分析/测试方案-2026-05-20-01-38-33.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# 测试方案-2026-05-20-01-38-33
|
||||
|
||||
## 测试方案文档路径
|
||||
|
||||
`工程分析/测试方案-2026-05-20-01-38-33.md`
|
||||
|
||||
## 静态检查
|
||||
|
||||
- 在 `WebSite/` 下执行 `npm run lint`。
|
||||
|
||||
## 构建检查
|
||||
|
||||
- 在 `WebSite/` 下执行 `npm run build`。
|
||||
|
||||
## 关键业务场景验证
|
||||
|
||||
- 顶部不再显示“开始自动配准”。
|
||||
- 顶部显示“导出全部 NII.GZ”,并能展开 DICOM 原始影像、分割影像、位姿数据选项。
|
||||
- 三维融合视角右下角显示小型 XYZ 坐标轴。
|
||||
- 保存自定义位姿后重新进入项目,位姿仍存在。
|
||||
- 重命名自定义位姿后刷新项目,名称仍保留。
|
||||
|
||||
## 导出验证
|
||||
|
||||
- `curl` 验证 DICOM 原始影像导出接口返回 `.nii.gz`。
|
||||
- `curl` 验证分割影像导出接口返回 `.nii.gz`。
|
||||
- `curl` 验证位姿数据导出接口返回 JSON。
|
||||
- 使用 gzip 文件头或响应大小确认导出不是旧 `64x64x64` 演示 Mask。
|
||||
- 确认前端下载不再使用 `URL.createObjectURL(blob)`。
|
||||
|
||||
## 部署验证
|
||||
|
||||
- 重启 `tmux` 会话 `revoxelseg-dicom`。
|
||||
- 验证:
|
||||
- `curl http://127.0.0.1:4000/api/health`
|
||||
- `curl -I http://127.0.0.1:4000/`
|
||||
|
||||
## Git/Gitea 备份验证
|
||||
|
||||
- 显式暂存本次相关代码和文档。
|
||||
- 创建包含时间戳和描述的 commit。
|
||||
- 推送到 Gitea `origin/main`。
|
||||
|
||||
## 实测结果
|
||||
|
||||
- `npm run lint`:通过。
|
||||
- `npm run build`:通过;仅保留 Vite chunk size 提醒。
|
||||
- 临时服务 `127.0.0.1:4100` 导出 DICOM 原始影像:HTTP 200,`.nii.gz` 约 75.76 MB。
|
||||
- DICOM NIfTI 头验证:`512x512x300`,datatype `4`,bitpix `16`,vox_offset `352`。
|
||||
- 临时服务导出 STL 分割影像:HTTP 200,`.nii.gz` 约 146 KB。
|
||||
- STL 分割 NIfTI 头验证:`512x512x300`,datatype `2`,bitpix `8`,非零体素 `1131842`,最大标签 `9`。
|
||||
- 临时服务导出位姿数据:HTTP 200,JSON 内包含 `project=head-ct-demo`、当前 `activePose` 和 3 个默认/保存位姿。
|
||||
- 前端下载实现已确认不再使用 `URL.createObjectURL(blob)`,改为后端直链附件下载。
|
||||
|
||||
## 回归关注点
|
||||
|
||||
- 右侧分割 NII/NII.GZ 导出按钮仍可工作。
|
||||
- 项目库中的 Mask 下载入口仍可工作。
|
||||
- DICOM/STL 预览与三维融合视图不受导出改动影响。
|
||||
54
工程分析/经验记录.md
54
工程分析/经验记录.md
@@ -991,3 +991,57 @@ C. 解决问题方案
|
||||
D. 后续如何避免问题
|
||||
|
||||
调整任何滑条或步进按钮的 step 时,同步检查数值展示、长按步进和手动输入精度,避免控制精度和显示精度不一致。
|
||||
|
||||
## 2026-05-20-01-38-33 NIfTI 导出必须与 DICOM 体数据同维同距
|
||||
|
||||
A. 具体问题
|
||||
|
||||
旧的 NII/NII.GZ 导出生成的是固定 `64x64x64` 演示 Mask,用户在 ITK-SNAP 中打开时无法与真实 DICOM 序列对应,表现为尺度、层数和内容都不可信。
|
||||
|
||||
B. 产生问题原因
|
||||
|
||||
早期导出接口没有读取真实 DICOM Pixel Data、Pixel Spacing 和 slice spacing,而是直接写入一个合成球体数据;这类演示数据适合验证下载链路,但不能用于医学影像工具复核。
|
||||
|
||||
C. 解决问题方案
|
||||
|
||||
后端新增真实 NIfTI-1 写入链路:DICOM 原始影像导出为 `512x512x300` int16 HU volume,分割影像导出为同维度 uint8 Label Map,并把 spacing 写入 NIfTI header。分割数据复用 STL 构件采样切面、当前位姿变换和扫描线填充逻辑生成,标签值对应构件 `partId`。
|
||||
|
||||
D. 后续如何避免问题
|
||||
|
||||
任何影像导出功能都必须先确认维度、spacing、datatype、vox_offset 和真实数据来源。不能用固定尺寸演示数据替代生产导出;新增导出后至少用脚本读取 NIfTI header,并确认体素数和 DICOM 序列一致。
|
||||
|
||||
## 2026-05-20-01-38-33 浏览器下载不应依赖 blob:http 临时地址
|
||||
|
||||
A. 具体问题
|
||||
|
||||
浏览器控制台出现 `blob:http://... was loaded over an insecure connection`,用户误以为导出的 NII.GZ 文件本身或服务部署存在安全错误。
|
||||
|
||||
B. 产生问题原因
|
||||
|
||||
前端先 `fetch` 后端文件,再用 `URL.createObjectURL(blob)` 生成临时 `blob:http` 地址触发下载;在 HTTP 部署环境下,浏览器会对 blob 来源继承非安全上下文并给出警告。
|
||||
|
||||
C. 解决问题方案
|
||||
|
||||
将 NIfTI、DICOM 压缩包和多文件导出统一改成后端直链附件下载,由 Express 设置 `Content-Disposition`,前端只创建 `<a href="/api/...">` 触发下载,不再生成 blob URL。
|
||||
|
||||
D. 后续如何避免问题
|
||||
|
||||
面向大文件、医疗影像和压缩包下载时优先使用后端附件直链。如果必须用 blob,应明确浏览器安全提示的影响;生产环境仍应考虑 HTTPS,但不能把 blob 临时地址当作常规下载路径。
|
||||
|
||||
## 2026-05-20-01-38-33 位姿列表需要进入项目状态而不是组件内存
|
||||
|
||||
A. 具体问题
|
||||
|
||||
用户保存的可视化工具栏位姿在重新进入项目后消失,造成调好的 STL/DICOM 对齐姿态无法继续复核或用于导出。
|
||||
|
||||
B. 产生问题原因
|
||||
|
||||
旧实现把 `savedPoses` 放在 `ReverseWorkspace` 组件本地 state 中,页面重新加载或重新进入项目时只会恢复默认、俯视、侧视三组临时位姿,没有写回后端项目状态。
|
||||
|
||||
C. 解决问题方案
|
||||
|
||||
为项目状态新增 `modelPoses` 字段,后端归一化默认位姿并提供 `PATCH /api/projects/:projectId/model-poses`;前端加载项目时读取 `project.modelPoses`,保存或重命名位姿时立即写回后端。
|
||||
|
||||
D. 后续如何避免问题
|
||||
|
||||
凡是用户明确“保存”的可视化参数都应进入项目级持久状态,不能只存在于组件 state。新增保存类交互时同时设计读取、写入、归一化和刷新后的回显验证。
|
||||
|
||||
55
工程分析/需求分析-2026-05-20-01-38-33.md
Normal file
55
工程分析/需求分析-2026-05-20-01-38-33.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# 需求分析-2026-05-20-01-38-33
|
||||
|
||||
## 开始时间
|
||||
|
||||
2026-05-20-01-38-33
|
||||
|
||||
## 原始需求摘要
|
||||
|
||||
用户提出五项修改:去掉“开始自动配准”;将上方导出改为“导出全部 NII.GZ”,并提供 DICOM 原始影像、分割影像、位姿数据选项,方便 ITK-SNAP 打开检查;在三维融合视角右下角增加小型 XYZ 坐标轴;解决重新进入项目后可视化工具栏保存位姿丢失;处理浏览器对 `blob:http` 下载的 insecure connection 报错。
|
||||
|
||||
## 业务目标
|
||||
|
||||
- 顶部操作区更聚焦导出,不再展示自动配准演示按钮。
|
||||
- 导出的医学影像文件与 DICOM 原始序列维度、spacing 对齐,能被 ITK-SNAP 作为主影像/分割影像加载。
|
||||
- 位姿数据能随项目保存,并能作为导出侧车 JSON 下载。
|
||||
- 三维融合视角提供固定的 XYZ 空间方向提示。
|
||||
- 前端下载避免 `URL.createObjectURL(blob)`,减少 `blob:http` insecure connection 警告。
|
||||
|
||||
## 输入与输出
|
||||
|
||||
- 输入:
|
||||
- 当前项目 DICOM 序列、模块样式、已保存位姿。
|
||||
- 用户在导出选项中勾选的 DICOM 原始影像、分割影像、位姿数据。
|
||||
- 输出:
|
||||
- DICOM 原始影像 `.nii.gz`。
|
||||
- 与原始影像同维度/spacing 的分割影像 `.nii.gz`。
|
||||
- 项目位姿与构件样式 JSON。
|
||||
- 重新进入项目仍可读取的已保存位姿。
|
||||
|
||||
## 影响范围
|
||||
|
||||
- `WebSite/server.ts`
|
||||
- `WebSite/src/lib/api.ts`
|
||||
- `WebSite/src/types.ts`
|
||||
- `WebSite/src/components/ReverseWorkspace.tsx`
|
||||
- 本次工程分析文档与 `工程分析/经验记录.md`
|
||||
|
||||
## 关键约束
|
||||
|
||||
- 不引入新依赖。
|
||||
- 旧的分割导出入口仍需兼容。
|
||||
- NIfTI 文件需要保持标准 NIfTI-1 单文件布局,设置正确 dim、datatype、pixdim、vox_offset、magic。
|
||||
- 位姿保存不能只停留在 React 组件内存中,需要写入项目状态文件。
|
||||
- 本次提交不能混入历史 `工程分析` 文档删除状态。
|
||||
|
||||
## 风险点
|
||||
|
||||
- 导出完整 512x512x300 体数据会比旧 64x64x64 演示 Mask 大很多,生成和下载耗时增加。
|
||||
- 当前分割影像仍是后端基于 DICOM 像素阈值生成的同维度标签图,不等同于完整 STL 体素化算法。
|
||||
- HTTP 访问环境下浏览器仍可能对非 HTTPS 下载有提示,但去掉 blob URL 可消除当前报错指向的 `blob:http` 链路。
|
||||
|
||||
## 默认假设
|
||||
|
||||
- “DICOM 原始影像”导出优先保证 ITK-SNAP 可打开与空间尺寸匹配,使用当前解析到的 CT HU int16 数据写入 NIfTI。
|
||||
- “位姿数据”作为 JSON 侧车文件导出,供复现实验参数使用,不作为 ITK-SNAP 主影像打开。
|
||||
Reference in New Issue
Block a user