DICOM介绍与实战:文件解析
概述、标准、数据字典、文件、库、dcm4che、DCMTK、PyDicom、AI、Medlmagelnsight、参考、
概述
Digital Imaging and Communications in Medicine,医学数字成像和通信,简称DICOM,一种用于存储和传输如X光、CT、MRI、超声等医学影像数据的国际标准。
主要特点是标准化,确保不同医疗设备和系统间可以相互兼容、共享和解读医学影像。关键特征:
- 内容丰富:包含图像数据和丰富的元数据。
- 广泛应用:放射科、心血管科、眼科、牙科等领域。
- 标准制定:由美国国家电气制造商协会(NEMA)开发。
标准
自从1985年首次发布以来,标准已经历多次修订和扩展,以适应不断发展的医学影像技术和需求。
当前最新版本为2026a。
数据字典
DICOM数据字典,定义DICOM文件中使用的上千个数据元素及其属性,分成四类:
- DICOM Data Elements
- DICOM File Meta Elements
- DICOM Directory Structuring Elements
- DICOM Dynamic RTP Payload Elements
数据字典格式:
- Tag:标签,相当于唯一ID,由两个十六进制数字组成,分别表示组号和元素号,标准数据元素的组号为偶数,私有数据元素组号为奇数。
- Name:名称,描述该元素的含义。
- Keyword:关键字,通常是名称的简写形式。
- VR:Value Representation,值表示,定义该元素的数据类型,如:UL(Unsigned Long)、CS(Code String)、PN(Person Name)等。
- VM:Value Multiplicity,值多重性,表示该元素可以包含多少个值(如单值、多值等)。
- 说明,Description
部分常见数据元素
| 标签(Tag) | 名称 | 关键字 | VR | VM | 说明(Description) |
|---|---|---|---|---|---|
| (0010,0010) | Patient’s Name | PN | 1 | 患者姓名 | |
| (0010,0020) | Patient ID | LO | 1 | 患者标识 | |
| (0008,0060) | Modality | CS | 1 | 检查模态(如CT、MR、US等) | |
| (0028,0010) | Rows | US | 1 | 图像的行数 | |
| (0028,0011) | Columns | US | 1 | 图像的列数 | |
| (0028,0030) | Pixel Spacing | DS | 2 | 像素间距(行间距和列间距,单位为毫米) | |
| (0028,1050) | Window Center | DS | 1-n | 窗口中心值 | |
| (0028,1051) | Window Width | DS | 1-n | 窗口宽度值 | |
| (0028,0008) | Number of Frames | IS | 1 | 图像的帧数(对于多帧图像) |
文件
普通图像查看器通常打不开它,需要使用专业的DICOM查看软件,如MicroDicom、RadiAnt或GIMP等,来打开、查看和转换成JPG等格式。
如何打开DCM文件:
- 专用软件:如RadiAnt DICOM Viewer、MicroDicom或3DICOM Viewer免费或付费DICOM浏览器。
- 图像处理软件:GIMP(支持多平台)也能打开部分DCM文件。
- 在线工具:一些在线服务也提供DCM转JPG等功能,但可能受文件大小或数量限制。
转换DCM文件:使用上述专用软件,在File菜单下找到Export或Save As选项,将其转换为JPEG、PNG等常用格式。
库
简单汇总介绍几个Java和Python库:
- dcm4che
- DCMTK
- PyDicom
dcm4che
广泛使用的开源Java库,GitHub,专为处理DICOM文件而设计,提供丰富的API,支持读取、解析、修改、显示、存储、传输DICOM文件。
Maven项目引入依赖:
<dependency>
<groupId>org.dcm4che</groupId>
<artifactId>dcm4che-core</artifactId>
<version>5.34.1</version>
<scope>compile</scope>
</dependency>
示例程序:
private static final Set<String> ALLOWED_FILE_EXT = Sets.newHashSet("dcm", "dicom");
public static String parseDcm(MultipartFile img) {
String suffix = FileUtil.getSuffix(img.getOriginalFilename());
if (ALLOWED_FILE_EXT.contains(suffix)) {
try (DicomInputStream dis = new DicomInputStream(img.getInputStream())) {
Attributes attr = dis.readDataset(-1, -1);
String patientId = attr.getString(Tag.PatientID);
String patientName = attr.getString(Tag.PatientName);
// logging
}
}
}
DCMTK
开源的医学影像处理Java库,提供丰富的功能,包括解析、读写和处理DICOM文件。
Gradle项目引入依赖:implementation 'org.dcmtk:dcmtk:3.6.5'
示例:
import org.dcmtk.dcmdata.DcmFileFormat;
import org.dcmtk.dcmdata.DcmObject;
import org.dcmtk.dcmdata.Tag;
import org.dcmtk.dcmdata.TagPath;
import org.dcmtk.dcmdata.VR;
public class DicomParser {
public static void main(String[] args) {
String filePath = "/path/to/dicom/file.dcm";
DcmFileFormat dcmFileFormat = new DcmFileFormat();
if (dcmFileFormat.loadFile(filePath).good()) {
// 获取数据集对象
DcmObject dcmObject = dcmFileFormat.getDataset();
String patientName = dcmObject.getString(Tag.PatientName);
String patientID = dcmObject.getString(Tag.PatientID);
// 获取图像宽度、高度
int width = dcmObject.getInt(Tag.Columns, 0);
int height = dcmObject.getInt(Tag.Rows, 0);
// 获取像素数据类型
VR pixelDataType = dcmObject.getVR(Tag.PixelData);
} else {
log.error("Failed to load DICOM file:{}.", filePath);
}
}
}
PyDicom
用于处理DICOM文件的开源(GitHub,)Python库。允许用户读取、修改和创建DICOM文件,支持大部分DICOM标准的数据元素和功能。
PyDicom使用内置的数据字典来解释DICOM文件中的数据元素,包含DICOM标准中定义的(除Dynamic RTP Payload Elements外)所有数据元素及其属性,可在_dicom_dict.py文件中对照标准查看。
安装:pip install pydicom matplotlib
示例:
import matplotlib.pyplot as plt
import pydicom
file_name = '/P202601010001_肝穿刺_HE染色_20250923_001.dcm'
ds = pydicom.dcmread(file_name)
print(f"{len(ds.file_meta.keys())} + {len(ds.keys())} Tags:")
for key in ds.file_meta.keys():
print(f"{key}: {ds.file_meta.get(key)}")
for key in ds.keys():
print(f"{key}: {ds.get(key)}")
print('\n---\n')
print(f"SOP类..........: {ds.SOPClassUID} ({ds.SOPClassUID.name})")
print(f"患者姓名........: {ds.PatientName.family_comma_given()}")
print(f"检查模态........: {ds.Modality}")
print(f"图像尺寸........: {ds.get(0x00280010).value} x {ds[0x0028, 0x0011].value}")
print(f"像素数组维度.....: {ds.pixel_array.ndim}")
print(f"像素数组形状.....: {ds.pixel_array.shape}")
print(f"图像帧数........: {ds.NumberOfFrames}")
print(f"协议名称........: {ds.get('ProtocolName', '(缺失)')}")
print(f"检查部位........: {ds.get('BodyPartExamined', '(缺失)')}")
print(f"切片位置........: {ds.get('SliceLocation', '(缺失)')}")
if ds.pixel_array.ndim == 2:
plt.imsave('./test.jpg', ds.pixel_array, cmap='gray')
else:
for i in range(ds.pixel_array.shape[0]):
png_file = f'./test/test_{i:03d}.jpg'
plt.imsave(png_file, ds.pixel_array[i, :, :], cmap='gray')
AI
MedImageInsight
论文,微软团队提出用于医学图像的开源嵌入模型MedImageInsight,采用类似CLIP的双塔架构:图像编码器+文本编码器。
在未经微调的情况下,即可在分类、图像检索、报告生成等多种医学图像任务中表现出色。
Thelion.ai组织在HF开源模型权重,GitHub在HF基础上通过GitHub Actions 构建Docker镜像:
- CPU版本:
alphahinex/medimageinsights:cpu - GPU版本:
alphahinex/medimageinsights:gpu
一行命令启动:docker run --privileged --name mi2 -p 8000:8000 alphahinex/medimageinsights:cpu
浏览器打开http://localhost:8000/docs即可看到FastAPI自动生成的接口文档:
主要是预测分类接口/predict。
使用示例
分类预测:
img1=$(base64 -i ultrasound.jpg | tr -d '\n')
img2=$(base64 -i computed-tomography.jpg | tr -d '\n')
img3=$(base64 -i x-ray.jpg | tr -d '\n')
curl -X POST -H "Content-Type: application/json" \
-d "{\"images\": [\"$img1\",\"$img2\",\"$img3\"], \"labels\":[\"X-Ray\",\"Magnetic Resonance Imaging\",\"Computed Tomography\",\"Ultrasound\",\"Dermoscopy\",\"Clinical Photography\",\"Optical Coherence Tomography\"]}" http://localhost:8000/predict
输出略,注意事项:
- 训练数据均为英文标签,推理时也使用英文标签效果更好;
- 输入的图像不能包含
alpha通道,否则会报错:The size of tensor a (4) must match the size of tensor b (3) at non-singleton dimension 0
/encode接口用于生成(1024 维)嵌入向量,适用于文本和图片:
curl -X POST -H "Content-Type: application/json" \
-d "{\"images\": [\"$img1\"], \"texts\":[\"Ultrasound\"]}" http://localhost:8000/encode
curl -X POST -H "Content-Type: application/json" \
-d "{\"texts\":[\"Ultrasound\"]}" http://localhost:8000/encode
参考
更多推荐



所有评论(0)