3. DICOM 元数据与标准化标签

DICOM 文件并不是“一张图 + 一段说明”,而是由文件头、数据集和像素数据共同构成的容器。真正决定这张影像能否被正确重建、配准、测量和归档的,是数据集中的元数据标签。每个标签由组号(Group)和元素号(Element)唯一标识,例如 (0010,0010) 是患者姓名,(0020,0032) 是图像位置,(0028,0030) 是像素间距。预处理流水线的第一步,往往不是滤波或重采样,而是把这些标签可靠地读出来、校验清楚,并在合规前提下完成匿名化。

一、标签的解析:从字节流到可读语义

解析 DICOM 时,先要判断传输语法(Transfer Syntax UID,(0002,0010))。隐式 VR 小端、显式 VR 小端、显式 VR 大端以及各类压缩语法,决定了后续如何读取每个元素的 VR(值表示)和长度。解析器通常按“标签 → VR → 长度 → 值”的顺序推进,遇到 SQ(序列)时递归进入子数据集,遇到未定义长度时依赖定界项结束。解析结果应落到一个以标签为键的结构中,同时保留原始 VR 和值长度,便于后续校验。

解析阶段最容易出问题的是私有标签和厂商扩展。私有标签以奇数组号出现,语义依赖私有创建者(如 (0009,0010) 的私有创建者 UID)。工程上不应盲目丢弃,而应保留原始字节,仅在明确映射规则时才解释其含义,否则容易把设备私有字段误读成标准字段。

二、校验:几何与采集参数的一致性检查

元数据校验的目标,是确认“影像能被正确摆到空间里”。核心检查项包括:

  • 像素间距 (0028,0030):行间距与列间距,单位 mm,必须为正数且非零;缺失时不能默认 1.0,应标记为不可测量。
  • 图像方向 (0020,0037):前三个值为行方向余弦,后三个值为列方向余弦,二者应近似正交,模长接近 1。
  • 图像位置 (0020,0032):首像素中心在患者坐标系中的 (x, y, z),单位 mm。
  • 层厚与层间距 (0018,0050)、(0018,0088):用于判断体素是否各向同性。
  • 窗宽窗位 (0028,1050)、(0028,1051):影响显示,不影响原始像素值。
  • 重缩放 (0028,1052)、(0028,1053):HU = 像素值 × Slope + Intercept,是 CT 定量分析的前提。

一个常见的校验逻辑是:若 (0028,0030) 缺失或为 0,则像素间距不可信;若方向余弦点积绝对值大于 0.01,则方向矩阵可能被错误写入;若同一序列内层间距与层厚差异超过阈值,则提示可能存在丢层或重复层。校验结果应分级:致命错误阻断流程,警告记录并继续,信息仅记录。

三、匿名化:在去标识与可用性之间取舍

匿名化不是简单删除患者姓名。(0010,0010)、(0010,0020)、(0010,0030)、(0008,0050) 等直接标识符必须处理,但 (0010,0020) 患者 ID 往往被研究流程用作跨序列关联键,因此常用“替换为哈希值”而非直接删除。日期类标签如 (0008,0020)、(0008,0021)、(0008,0030) 可做偏移或截断,但需保持同一患者内的时间顺序一致。

需要特别注意的是,像素数据本身可能包含 burned-in annotation(如超声图像上的姓名、日期)。仅处理标签并不足以完成匿名化,必要时需对像素区域做遮挡或 OCR 检测。此外,私有标签中也可能藏有标识信息,应结合私有字典或直接清除未知私有块。

匿名化策略应写入配置:哪些标签删除、哪些替换、哪些保留、替换算法是什么。建议保留 (0008,0060) 模态、(0018,0015) 身体部位、(0028,0030) 像素间距等对分析必要的字段,避免“过度匿名化”导致影像不可用。

四、一个可执行的校验与匿名化流程

下面给出一个面向工程实现的处理顺序,输入为单个 DICOM 文件,输出为校验报告和匿名化后的数据集:

1. 读取文件,解析 Transfer Syntax UID
2. 按 VR 解析所有元素,保留原始字节
3. 校验必填标签:SOPClassUID、StudyInstanceUID、SeriesInstanceUID
4. 校验几何标签:PixelSpacing、ImageOrientationPatient、ImagePositionPatient
5. 校验像素标签:Rows、Columns、BitsAllocated、PixelRepresentation
6. 校验重缩放:RescaleSlope、RescaleIntercept
7. 匿名化:删除/替换直接标识符,处理日期偏移
8. 检查私有标签,清除未知私有块
9. 输出校验报告:error / warning / info
10. 写出匿名化后的 DICOM 文件

校验报告建议包含:标签名、标签号、期望条件、实际值、级别。例如 PixelSpacing 期望“两个正浮点数”,实际为“0.0\0.0”,级别为 error。这样后续排障时可以直接定位到具体字段,而不是只看到“文件损坏”。

五、标签关系与处理路径可视化

下图把本节涉及的核心标签、校验关注点和匿名化动作组织成一张关系图,帮助理解“哪些标签决定几何、哪些决定显示、哪些必须去标识”。

DICOM 元数据标签:解析 → 校验 → 匿名化 解析层 Transfer Syntax UID (0002,0010) VR / 长度 / 值 显式或隐式解析 SQ 序列递归 子数据集展开 私有标签保留 原始字节不丢弃 校验层 几何一致性 PixelSpacing (0028,0030) Orientation (0020,0037) Position (0020,0032) SliceThickness (0018,0050) 像素与重缩放 Rows / Columns BitsAllocated RescaleSlope (0028,1052) RescaleIntercept (0028,1053) 标识与日期 PatientName (0010,0010) PatientID (0010,0020) StudyDate (0008,0020) AccessionNumber (0008,0050) 校验级别 error 阻断 warning 记录 info 仅记录 匿名化层 删除 PatientName AccessionNumber 替换 / 哈希 PatientID → Hash StudyInstanceUID 重映射 日期偏移 StudyDate / SeriesDate 保持时间顺序一致 像素检查 burned-in 标注 OCR / 遮挡 输出:校验报告(error / warning / info)+ 匿名化 DICOM 数据集

从图中可以看到,解析层解决“能不能读”,校验层解决“读得对不对”,匿名化层解决“能不能合规地用”。三者顺序不能颠倒:如果先匿名化再校验,可能因为关键几何标签被删除而无法判断影像是否可测量;如果先校验再匿名化,则可以在保留完整信息的前提下完成质量判断,再按策略去标识。

六、工程实践中的几个判断点

第一,像素间距缺失时不要用 1.0 兜底。很多测量误差都源于“默认值”被当成真实值。正确做法是标记该序列不可用于定量测量,或从同系列其他切片推断并明确标注推断来源。

第二,方向余弦要检查正交性。计算行方向与列方向的点积,理想值为 0;若绝对值大于 0.01,说明方向矩阵可能被错误写入或存在非标准旋转,应触发 warning。

第三,匿名化后要重新校验。删除或替换标签可能破坏引用关系,例如 (0008,1155) 引用 SOP Instance UID 时,若被引用对象已重映射,必须同步更新,否则会形成断链。

第四,保留审计记录。匿名化前后应记录哪些标签被修改、修改规则版本、操作时间,但审计记录本身不能包含原始标识信息,否则等于把敏感数据换了个地方存放。

不要把匿名化等同于“删除患者姓名”。DICOM 中可能通过 StudyInstanceUID、设备序列号、私有标签、甚至像素中的文字反推到个人。合规的匿名化需要覆盖标签、像素和私有扩展三个层面。

掌握标签的解析、校验与匿名化,是后续重采样、配准和建模能够稳定运行的前提。只有先把元数据这一层做扎实,像素层面的处理才有可靠的空间与语义基础。