4. DICOM图像解析与元数据管理

DICOM 文件并不是一张单纯的图片,而是一个“像素数据 + 元数据”的复合容器。工作站能否正确显示、检索、测量和归档,几乎全部取决于对元数据的解析是否准确。本节围绕标签解析、VR 类型、传输语法、压缩格式、私有标签以及患者/研究/序列/实例四级层级展开,目标是让读者理解一个 DICOM 文件从字节流到可检索对象的完整解析路径。

一、数据元素:DICOM 的最小解析单元

DICOM 文件由若干数据元素(Data Element)顺序排列组成,每个数据元素包含四个部分:标签(Tag)、VR(Value Representation)、值长度(Value Length)和值域(Value Field)。标签由组号(Group Number)和元素号(Element Number)两个 16 位无符号整数构成,通常写作 (gggg,eeee),例如 (0010,0010) 表示患者姓名,(7FE0,0010) 表示像素数据。

标签按奇偶性分为两类:组号为偶数的为标准标签,由 DICOM 标准统一定义;组号为奇数的为私有标签,由设备厂商自行定义。解析器必须能区分这两类,否则会把厂商私有信息误读为标准字段。

二、VR 类型决定如何读取值域

VR 描述值域的数据类型和编码方式,是解析器选择读取策略的依据。常见 VR 包括:

  • PN(Person Name):患者姓名,采用“姓^名^中间名^前缀^后缀”的分段编码;
  • DA / TM:日期与时间,格式分别为 YYYYMMDD 和 HHMMSS.FFFFFF;
  • UI:唯一标识符,如 SOP Class UID,末尾需补空字节保证偶数长度;
  • US / UL / SS:16 位或 32 位无符号/有符号整数,常用于行数、列数、位深;
  • DS / IS:十进制字符串与整数字符串,如像素间距、窗宽窗位;
  • OB / OW / OF:字节、字、浮点型原始数据,像素数据常用 OW 或 OB;
  • SQ:序列,值域内嵌套一组完整的数据元素,可递归解析。

VR 有两种编码方式:显式 VR 在标签后直接写入两个字符的 VR 编码;隐式 VR 不写 VR,解析器必须查标准字典根据标签推断 VR。这是传输语法要解决的核心问题之一。

三、传输语法:字节序与 VR 编码的组合

传输语法(Transfer Syntax)规定了字节序、VR 编码方式和是否压缩三件事。字节序分为小端(Little Endian)和大端(Big Endian);VR 编码分为显式和隐式;压缩则决定像素数据是否经过封装。常见传输语法 UID 如下:

传输语法 UID字节序VR 编码像素压缩
1.2.840.10008.1.2小端隐式无
1.2.840.10008.1.2.1小端显式无
1.2.840.10008.1.2.2大端显式无
1.2.840.10008.1.2.4.50小端显式JPEG Baseline
1.2.840.10008.1.2.4.70小端显式JPEG Lossless
1.2.840.10008.1.2.4.90小端显式JPEG 2000 无损
1.2.840.10008.1.2.5小端显式RLE 无损

解析器读取文件时,先读取 128 字节前导码和“DICM”魔数,再读取文件元信息组 (0002,xxxx),其中 (0002,0010) 就是传输语法 UID。元信息组本身固定使用显式小端编码,因此可以稳定读出传输语法,再据此切换后续数据集的解析策略。

四、压缩格式与像素数据封装

当传输语法为压缩类型时,像素数据 (7FE0,0010) 的 VR 变为 OB,值域不再是连续的原始像素,而是按帧封装的片段序列。每个片段由“片段标签 + 片段长度 + 压缩码流”组成,片段标签为 (FFFE,E000) 表示普通帧,(FFFE,E0DD) 表示序列分隔符。解析时需要逐片段读取,再交给对应的解码器(JPEG、JPEG 2000、RLE)解压为原始像素矩阵。

解压后还需结合 (0028,0002) 采样数、(0028,0004) 光度解释、(0028,0010/0011) 行列数、(0028,0100) 位深、(0028,1052/1053) 截距与斜率,才能把存储值转换为有临床意义的 CT 值或信号强度。例如 CT 图像中,HU = 存储值 × RescaleSlope + RescaleIntercept,典型 RescaleSlope 为 1、RescaleIntercept 为 -1024。

五、私有标签的处理原则

私有标签位于奇数组,常见于 (0009,xxxx)、(0019,xxxx)、(0029,xxxx) 等组。它们通常承载厂商私有的采集参数、后处理信息或注释。处理原则是:不依赖私有标签做核心业务判断;解析时保留原始字节,不做强制解释;如需读取,必须结合厂商私有字典(Private Dictionary)和 (0028,0100) 附近的私有创建者 UID 进行匹配。工作站应把私有标签原样保留并在转发时一并写出,避免破坏设备间的兼容性。

六、四级层级模型:患者—研究—序列—实例

DICOM 信息模型把影像组织为四级:患者(Patient)→ 研究(Study)→ 序列(Series)→ 实例(Instance)。每一级都有对应的唯一标识 UID:

  • PatientID (0010,0020):患者唯一编号;
  • StudyInstanceUID (0020,000D):一次检查的唯一标识;
  • SeriesInstanceUID (0020,000E):同一序列的唯一标识;
  • SOPInstanceUID (0008,0018):单个实例(一张图像或一个对象)的唯一标识。

工作站建立本地索引时,通常以 StudyInstanceUID 为主键聚合序列,以 SeriesInstanceUID 聚合实例,再按 InstanceNumber (0020,0013) 排序。这样就能实现“按患者查研究、按研究列序列、按序列翻图像”的阅片流程。

DICOM 文件解析路径与四级层级模型 字节流解析链 128B 前导码 + "DICM" 文件格式识别 (0002,0010) 传输语法 固定显式小端读取 切换字节序 / VR 编码 显式或隐式解析 逐元素读 Tag/VR/Len 标准与私有标签分流 (7FE0,0010) 像素数据 原始或片段封装 解码 + 截距斜率换算 得到 HU / 信号强度 患者—研究—序列—实例 层级 患者 Patient PatientID (0010,0020) · PatientName (0010,0010) · BirthDate (0010,0030) 研究 Study StudyInstanceUID (0020,000D) · StudyDate (0008,0020) · AccessionNumber (0008,0050) 序列 Series SeriesInstanceUID (0020,000E) · Modality (0008,0060) · SeriesNumber (0020,0011) 实例 Instance SOPInstanceUID (0008,0018) · InstanceNumber (0020,0013) · Rows/Columns 索引主键:StudyInstanceUID → SeriesInstanceUID → SOPInstanceUID 元数据

七、解析实现要点与常见问题

实现一个稳健的 DICOM 解析器,建议按以下顺序处理:先读文件元信息组确定传输语法;再按传输语法切换字节序和 VR 读取模式;遇到 SQ 序列时递归解析;遇到私有标签时保留原始字节;遇到压缩像素时按片段封装读取并调用解码器。常见问题包括:隐式 VR 下把私有标签误判为标准标签、大端文件未做字节交换导致行列数错乱、压缩片段长度未按偶数对齐导致后续元素偏移、以及多帧图像未按帧数循环读取。

实践建议:在解析器中维护一份标准标签字典(如 DICOM PS3.6),对未知标签只做“保留 + 记录”,不要抛出异常中断整个文件解析。这样即使遇到厂商私有扩展,也能保证核心影像正常显示。

元数据管理的最终目标,是让工作站能够以患者、研究、序列、实例四级结构稳定地组织影像,并支持按 UID 检索、按 InstanceNumber 排序、按传输语法正确解码。只有把标签、VR、传输语法、压缩格式和私有标签这几件事处理清楚,后续的阅片、测量、归档和传输才有可靠基础。