Files
Head_CT_Morph/工程分析/经验记录.md

9.6 KiB
Raw Permalink Blame History

经验记录

本文件作为项目统一知识库。每次最终执行项目修改前必须阅读;每次执行完成后,如遇到关键问题或形成可复用经验,必须按以下四段式追加记录。

2026-05-03-18-27-21 建立项目修改工作流

A. 具体问题

项目此前缺少统一的修改前分析、人工审核、测试确认、经验沉淀、Gitea 备份和重新部署流程,后续需求容易直接进入代码修改,导致风险不可追踪。

B. 产生问题原因

仓库中已有 README 和运行说明,但没有面向后续代码编纂工作的强制流程文件,也没有统一的 工程分析/ 知识库目录。

C. 解决问题方案

新增仓库根目录 AGENTS.md,明确后续项目修改需求必须记录开始时间、生成需求分析、实现方案、测试方案,并在实现方案和测试方案通过用户二次审核后再修改业务代码。新增 工程分析/工程整体分析.md、本经验记录,以及本次需求、实现、测试方案文档。

D. 后续如何避免问题

后续每次项目修改开始时先阅读 AGENTS.md工程分析/工程整体分析.md工程分析/经验记录.md,严格使用同一开始时间戳创建三类分析文档,并在用户确认实现方案和测试方案后再执行代码改动。

2026-05-03-22-02-15 调整硬边界与高斯平滑预览分界线

A. 具体问题

硬边界和高斯平滑预览图中的黄色分界线出现 Y 字形:一部分随头颈部形变变成斜线,另一部分仍横向延长,视觉上像多出一条不自然的横线。

B. 产生问题原因

旧逻辑先把黄色分界线画到原始 CT 预览图上,再把整张图传入 preview_deform_2d 做快速 2D 形变。硬边界和高斯平滑在分界附近存在不连续或快速变化的运动权重,导致同一条标注线被分裂成不同运动状态。

C. 解决问题方案

将硬边界和高斯平滑预览改为先对不含黄色线的 CT 图执行形变,再在形变结果上叠加单条黄色分界线。保留原始图的水平分界线,并尽量不改变软过渡原有视觉效果。

D. 后续如何避免问题

预览标注层、参考线、箭头等非 CT 内容应优先在形变结果上单独叠加,不要和医学影像像素一起参与形变采样。若必须参与形变,应先确认该标注能承受硬边界或快速变化权重造成的撕裂效果。

2026-05-03-22-36-18 增加 DICOM 阅览和单项下载

A. 具体问题

四状态结果区只有总 ZIP 下载入口,用户无法直接下载单个状态的 DICOM 序列;影像库卡片只能进入变换工作站或查看信息,缺少冠状位、矢状位阅览能力和 CT 显示模式切换。

B. 产生问题原因

后端已经具备单状态 DICOM ZIP 打包能力,但前端未暴露单状态按钮。影像库已有轴位缩略图接口,但该接口只读取单张 DICOM未提供基于整套 DICOM 体数据的冠状/矢状重建预览。

C. 解决问题方案

前端在四状态卡片标题旁增加单状态下载按钮,复用现有 ZIP job 轮询和下载逻辑。后端新增影像库冠状/矢状重建预览接口,并按平面、切片和窗宽窗位缓存 PNG。前端新增影像库阅览弹层支持冠状位、矢状位、切片滑杆和显示模式切换。

D. 后续如何避免问题

已有后端能力应先通过前端入口复用不重复实现打包逻辑。DICOM 阅览类预览需要使用缓存,避免每次切换切片或窗宽窗位都重复生成相同图像;新增缓存应继续放在现有 _preview_cache 下,避免污染仓库。

2026-05-03-23-22-10 修复阅览切换和下载触发

A. 具体问题

DICOM 阅览切片滑杆和显示模式切换时,浏览器出现 ERR_CONNECTION_RESET;同时 ZIP 文件下载可能在其他 UI 操作期间再次触发,并出现 HTTP 文件加载安全提示。

B. 产生问题原因

阅览重建接口每次请求都重新读取整套 DICOM 体数据,切片滑杆快速拖动和显示模式切换会并发触发多个重建请求。前端 AbortController 只能取消浏览器等待,不能停止后端已经开始的 DICOM 读取容易造成内存压力并导致后端被系统终止。ZIP 下载通过直接访问后端 /api/file URL 触发,且缺少已完成 ZIP job 的一次性下载保护。

C. 解决问题方案

后端为 DICOM 体数据增加基于目录签名的内存缓存,并限制缓存数量;阅览接口复用缓存体数据生成不同平面、切片和窗宽窗位的 PNG。前端为阅览切片请求增加防抖减少滑杆拖动时的请求数量。ZIP 下载增加已下载 job id 记录,并优先使用 fetch blob 转本地 blob: URL 触发下载,失败时再回退到直接 URL。

D. 后续如何避免问题

涉及整套 DICOM 体数据读取的接口必须考虑缓存、并发和请求节流,不能把滑杆这类高频 UI 操作直接绑定到重型后端计算。自动下载类逻辑必须记录已处理 job避免同一个完成状态在后续渲染或轮询中重复触发。

2026-05-08-02-36-12 实现 STL 模型切分 mask

A. 具体问题

用户要求模型切分不能再用象征性画圈或无意义 CT MASK 图,而要根据 STL 模型真实穿透 DICOM 的位置生成 mask并在 DICOM 起点帧、终点帧上显示。

B. 产生问题原因

当前仓库主线没有 STL 模型切分实现,只有 DICOM 冠状/矢状阅览。若用前端绘制圆圈或固定区域替代,会与 STL 几何和 DICOM 切片没有真实关系,无法表达语义分割切片形态。

C. 解决问题方案

后端新增 STL 上传、ASCII/Binary STL 解析、DICOM patient 坐标到体素坐标转换、STL 三角面与冠状/矢状切片平面求交、交线栅格化和填充形成 mask并叠加到 DICOM 阅览 PNG。前端新增模型切分开关、STL 上传、单条双端点进度条,以及起点帧/终点帧双图 mask 展示。

D. 后续如何避免问题

涉及医学影像与模型叠加时mask 必须来自真实几何或分割数据,不能用装饰性形状替代。若 STL 与 DICOM 坐标系不一致,应优先补充配准矩阵或平移/旋转/缩放参数,而不是在图像上手工假标。

2026-05-08-02-54-30 调整模型切分范围条

A. 具体问题

模型切分的起点和终点虽然逻辑上共用一段范围,但 UI 使用两个原生 range 叠加,浏览器仍显示两条完整蓝色轨道,看起来像两个独立进度条。

B. 产生问题原因

原生 <input type="range"> 会绘制自己的轨道。两个 range 即使绝对定位叠在同一区域,也会各自显示一条轨道,不能自然表现为单条范围选择器。

C. 解决问题方案

将可见轨道改为自定义 div一条灰色总轨道和一段蓝色选中范围两个原生 range 仅保留透明拖拽层和手柄。通过 CSS 隐藏 WebKit/Firefox 的原生轨道,并分别给起点、终点手柄设置颜色。

D. 后续如何避免问题

实现双端范围选择器时,不要直接依赖两个原生 range 的默认轨道。应使用自定义轨道绘制范围,仅让原生 input 提供拖拽能力,或引入明确支持 range selection 的组件。

2026-05-08-03-45-01 调整 Mask 双图展示

A. 具体问题

用户强调逆向工作区右侧“Mask 展示”应在点击“模型切分”后显示,并且展示前后两张由 DICOM 切分 STL 模型得到的图片,而不是单张 CT mask、交互式模型视图或混杂普通 DICOM 阅览结果。

B. 产生问题原因

此前模型切分展示复用了 DICOM 重建预览图叠加 mask 的接口语义,虽然已有起点帧和终点帧两张图,但视觉上仍容易被理解为 CT 图叠加结果,没有把“模型切面 mask 图片”与普通 DICOM 阅览明确区分。

C. 解决问题方案

在后端重建预览接口增加 maskOnly=1 输出模式,复用真实 STL/DICOM 切面 mask 计算结果生成纯 mask 图片,并用独立缓存后缀避免复用普通 CT 预览。前端在模型切分启用且 STL 已载入时将右侧区域切换为明确的“Mask 展示”双图布局,分别展示起点帧和终点帧。

D. 后续如何避免问题

涉及 mask 或语义分割结果展示时应区分“CT 背景叠加图”和“mask-only 结果图”。如果用户要求展示模型切面或分割形态,优先提供独立 mask 图片,并在 UI 上明确区分普通阅览与切分结果。

2026-05-08-03-57-51 接入 DICOM SEG 双切面展示

A. 具体问题

用户进一步明确右侧“Mask 展示”不能显示切分后的三维模型外壳、点云、空心模型,也不能用 STL 截面封顶 Cap 作为结果;模型切分后应展示上、下两个二维实心切面,并且像素数据必须来自 DICOM 语义分割影像。

B. 产生问题原因

此前实现虽然把右侧改成了双图,但数据仍可来自 STL 与 DICOM 平面求交后的 mask-only 渲染。该结果属于几何投影/轮廓填充,不等价于真实 DICOM Segmentation Mask label map。

C. 解决问题方案

新增与影像库条目绑定的 DICOM SEG 上传、列表和预览接口,后端将 SEG 像素解析成与 CT 体数据对齐的三维 label map并按当前切分范围上、下端点渲染二维实心 mask 图片。前端新增 DICOM SEG 上传入口模型切分后的“Mask 展示”改为请求 segmentation 预览接口;没有绑定 SEG 时只提示缺少数据,不再回退到 STL 生成假结果。

D. 后续如何避免问题

凡是用户明确要求 DICOM 语义分割或 Segmentation Mask 时,不能用 STL、mesh cap、点云投影或图形填充替代。实现前应先确认真实 label map 数据源;若数据源缺失,界面应提示上传或关联,而不是生成看似合理的伪 mask。