概述

Digital Imaging and Communications in Medicine,医学数字成像和通信,简称DICOM,一种用于存储和传输如X光、CT、MRI、超声等医学影像数据的国际标准

主要特点是标准化,确保不同医疗设备和系统间可以相互兼容、共享和解读医学影像。关键特征:

  • 内容丰富:包含图像数据和丰富的元数据。
  • 广泛应用:放射科、心血管科、眼科、牙科等领域。
  • 标准制定:由美国国家电气制造商协会(NEMA)开发。

标准

自从1985年首次发布以来,标准已经历多次修订和扩展,以适应不断发展的医学影像技术和需求。
在这里插入图片描述
当前最新版本为2026a

数据字典

DICOM数据字典,定义DICOM文件中使用的上千个数据元素及其属性,分成四类:

  1. DICOM Data Elements
  2. DICOM File Meta Elements
  3. DICOM Directory Structuring Elements
  4. 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

参考

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐