DICOM入门系列——DICOMweb实战:用RESTful API访问医学影像

在前面的文章中,我们学习了DICOM文件的结构、本地解析(pydicom)、以及传统DICOM网络传输协议(如C-STORE、C-FIND、WADO)。但传统DICOM网络协议(基于TCP/IP的二进制通信)存在一个关键局限:对Web和现代开发环境(如前端JavaScript、移动端APP、云原生服务)不够友好------它需要专门的DICOM库支持,且协议本身复杂度高(例如需要处理关联建立、消息封装等)。

为了解决这一问题,DICOM标准委员会在原有基础上推出了DICOMweb ------一套基于HTTP/RESTful API的标准化接口,用开发者熟悉的"请求-响应"模式(类似调用普通Web API)实现医学影像的查询、存储和访问。DICOMweb不仅保留了DICOM的核心功能,还让医学影像数据能无缝融入Web应用、AI平台和云服务,成为现代医学影像信息化的"新基建"。

本文将通过实战代码与详细步骤,带你入门DICOMweb的核心接口(QIDO-RS、WADO-RS、STOW-RS),并用Python和浏览器直接调用这些API,实现"像访问普通Web服务一样操作医学影像"。

一、什么是DICOMweb?------传统DICOM的"Web化升级"

DICOMweb是DICOM标准中专门为Web和RESTful交互 设计的一系列扩展规范(主要包含在DICOM Part 18、Part 15和Part 16中),它的核心是将传统的DICOM服务(如C-STORE、C-FIND)转化为基于HTTP协议的RESTful接口 ,并使用JSON/XML作为数据交换格式(替代原有的二进制DICOM消息)。

DICOMweb的三大核心接口

接口名称 全称 功能 对应传统DICOM服务 HTTP方法 数据格式
QIDO-RS Query based on ID for DICOM Objects 按条件查询患者、检查、序列或图像的元数据 C-FIND GET/POST JSON/XML
WADO-RS Web Access to DICOM Persistent Objects **获取DICOM元数据或像素数据(图像本身)**​ C-MOVE/C-GET GET JSON/XML/DICOM二进制/JPEG等
STOW-RS Store Over the Web 上传DICOM文件(图像/报告)到服务器 C-STORE POST DICOM二进制/JSON封装

📌 通俗理解

  • QIDO-RS​ 像"搜索引擎":输入条件(如患者姓名、检查日期),返回匹配的DICOM对象列表(不返回图像本身,只返回元数据);

  • WADO-RS​ 像"图库":根据ID直接获取DICOM文件的详细信息或图像像素数据(可显示为图片);

  • STOW-RS​ 像"上传工具":把本地的DICOM文件(或生成的AI分析结果)推送到服务器存储。

二、DICOMweb的典型应用场景

  • Web医学影像查看器:前端通过QIDO-RS查询患者列表,再用WADO-RS获取图像并显示(无需安装DICOM查看器);

  • AI辅助诊断平台:AI模型通过STOW-RS上传分析结果(如结节标注),或通过WADO-RS获取待分析的DICOM图像;

  • 云PACS系统:支持多院区、多终端通过HTTP协议安全访问影像数据;

  • 移动端APP:医生用手机通过DICOMweb调阅患者历史影像(如急诊科查看CT报告)。

三、实战准备:搭建支持DICOMweb的服务器

要实操DICOMweb接口,首先需要一个支持DICOMweb的PACS服务器。推荐使用以下工具(免费且开源):

1. Orthanc + DICOMweb插件

Orthanc是最流行的轻量级开源PACS服务器,其最新版本默认支持DICOMweb(无需额外配置)。安装后:

  • 默认HTTP地址:http://localhost:8042(Web管理界面);

  • DICOMweb接口地址:http://localhost:8042/dicom-web(所有DICOMweb API均挂载在此路径下)。

快速启动Orthanc

  1. 下载Orthanc Windows/macOS/Linux版本(官网下载页);

  2. 解压后直接运行(默认监听HTTP端口8042和DICOM端口4242);

  3. 打开浏览器访问 http://localhost:8042,确认服务正常运行。

2. 上传测试DICOM文件到Orthanc

通过Orthanc的Web界面("Upload"按钮)上传一个CT/MRI的DICOM文件(如test.dcm),或使用DICOM发送工具(如Radiant的"Send"功能)将文件发送到Orthanc的DICOM端口(默认4242)。上传成功后,在Orthanc的Web界面"Studies"中可看到该检查记录(包含患者信息、序列和图像)。

四、DICOMweb三大接口实战(Python + 浏览器)

1. **QIDO-RS:查询DICOM对象元数据(GET/POST)**​

功能:通过条件(如患者姓名、Study UID)查询符合条件的DICOM对象(患者、检查、序列、图像),返回JSON格式的元数据列表(不包含图像像素数据)。

Orthanc的QIDO-RS接口地址

复制代码
http://localhost:8042/dicom-web/qido/search

**示例1:查询所有患者(Patient)**​

用浏览器直接访问(或通过Python requests库):

复制代码
GET http://localhost:8042/dicom-web/qido/search?limit=10

参数说明:

  • limit:返回结果的最大数量(避免数据过多);

  • 其他可选参数:PatientName(患者姓名)、StudyDate(检查日期)、Modality(模态,如CT/MR)。

Python代码示例(获取所有患者列表)

python 复制代码
import requests

# Orthanc的QIDO-RS接口地址
qido_url = "http://localhost:8042/dicom-web/qido/search"

# 发送GET请求(查询所有患者,限制返回10条)
response = requests.get(qido_url, params={"limit": 10})

if response.status_code == 200:
    patients = response.json()  # 返回的是DICOM对象的元数据列表(JSON格式)
    print("查询到的患者列表(前10条):")
    for patient in patients:
        print(f"患者ID: {patient.get('PatientID', 'N/A')}, 姓名: {patient.get('PatientName', 'N/A')}")
else:
    print(f"查询失败,状态码: {response.status_code}, 错误: {response.text}")

输出示例

python 复制代码
查询到的患者列表(前10条):
患者ID: 123456, 姓名: 张三^三
患者ID: 789012, 姓名: 李四^四
...

**示例2:查询特定患者的检查(Study)**​

通过患者ID(PatientID)筛选检查记录:

python 复制代码
GET http://localhost:8042/dicom-web/qido/search?PatientID=123456&limit=5

或用Python:

python 复制代码
params = {"PatientID": "123456", "limit": 5}
response = requests.get(qido_url, params=params)

📌 关键参数

  • PatientIDPatientName(格式如"张三^三")、StudyDate(YYYYMMDD)、Modality(CT/MR/XA等);

  • 返回的JSON数据包含DICOM对象的唯一标识符(如StudyInstanceUIDSeriesInstanceUIDSOPInstanceUID),这些是后续WADO-RS和STOW-RS的必填参数。

2. **WADO-RS:获取DICOM元数据或图像(GET)**​

功能 :根据DICOM对象的唯一标识符(如StudyInstanceUID、SeriesInstanceUID、SOPInstanceUID),获取该对象的元数据(JSON/XML)或像素数据(图像本身,支持JPEG、PNG等格式)

Orthanc的WADO-RS接口地址

python 复制代码
http://localhost:8042/dicom-web/wado

**示例1:获取某个DICOM图像的像素数据(直接显示为图片)**​

假设通过QIDO-RS查询到了某个SOP Instance UID(如1.2.840.113619.2.55.3.2831164382.145.1643824682.83),可通过以下URL获取图像:

python 复制代码
GET http://localhost:8042/dicom-web/wado?requestType=WADO&studyUID=<StudyInstanceUID>&seriesUID=<SeriesInstanceUID>&objectUID=<SOPInstanceUID>&contentType=image/jpeg

参数说明:

  • studyUIDseriesUIDobjectUID:通过QIDO-RS查询得到的唯一标识符;

  • contentType:指定返回格式(image/jpeg为JPEG图像,application/dicom为原始DICOM文件)。

Python代码示例(获取图像并保存为JPEG)

python 复制代码
# 假设通过QIDO-RS查询到了以下UID(替换为实际值)
study_uid = "1.2.840.113619.2.55.3.2831164382.145.1643824682.81"
series_uid = "1.2.840.113619.2.55.3.2831164382.145.1643824682.82"
object_uid = "1.2.840.113619.2.55.3.2831164382.145.1643824682.83"

# WADO-RS请求URL(获取JPEG格式的图像)
wado_url = f"http://localhost:8042/dicom-web/wado?requestType=WADO&studyUID={study_uid}&seriesUID={series_uid}&objectUID={object_uid}&contentType=image/jpeg"

response = requests.get(wado_url)
if response.status_code == 200:
    with open("dicom_image.jpg", "wb") as f:
        f.write(response.content)
    print("DICOM图像已保存为JPEG文件: dicom_image.jpg")
else:
    print(f"获取图像失败,状态码: {response.status_code}")

用图片查看器打开dicom_image.jpg,即可看到CT/MRI的灰度图像(Orthanc会自动处理窗宽窗位)。

**示例2:获取DICOM元数据(JSON格式)**​

若想获取该图像的详细元数据(如层厚、扫描参数),可将contentType改为application/dicom+json

python 复制代码
GET http://localhost:8042/dicom-web/wado?requestType=WADO&studyUID=<StudyUID>&seriesUID=<SeriesUID>&objectUID=<ObjectUID>&contentType=application/dicom+json

返回的是该DICOM文件的所有标签(Tag)的JSON表示(如PatientName、Modality、PixelSpacing等)。

3. **STOW-RS:上传DICOM文件到服务器(POST)**​

功能:将本地的DICOM文件(或生成的DICOM数据)通过HTTP POST上传到PACS服务器存储(相当于传统C-STORE服务)。

Orthanc的STOW-RS接口地址

python 复制代码
http://localhost:8042/dicom-web/stow

示例:上传本地DICOM文件

使用Python的requests库发送POST请求,将文件以multipart/form-data格式上传:

python 复制代码
import requests

# STOW-RS接口地址
stow_url = "http://localhost:8042/dicom-web/stow"

# 本地DICOM文件路径
dcm_file_path = "test.dcm"  # 替换为你的DICOM文件

# 构造multipart/form-data请求(文件字段名为"file")
files = {"file": open(dcm_file_path, "rb")}
headers = {"Accept": "application/dicom+json"}  # 可选:请求返回存储结果

response = requests.post(stow_url, files=files, headers=headers)

if response.status_code == 200:
    print("DICOM文件上传成功!服务器响应:", response.json())
else:
    print(f"上传失败,状态码: {response.status_code}, 错误: {response.text}")

上传成功后,文件会存储在Orthanc服务器中,可通过QIDO-RS查询到新添加的检查记录。

五、总结:DICOMweb------医学影像的"Web通行证"

DICOMweb通过RESTful API将传统的DICOM服务"翻译"成了开发者友好的HTTP请求,其核心价值在于:

标准化:遵循DICOM官方规范,确保不同厂商的PACS和Web应用兼容;

易集成:与现代Web技术(前端JavaScript、Python Flask/Django、移动端APP)无缝对接;

功能全:覆盖查询(QIDO)、获取(WADO)、存储(STOW)三大核心场景;

扩展性强:支持JSON/XML/DICOM二进制等多种数据格式,适应AI、云存储等新需求。

对于开发者而言,掌握DICOMweb意味着可以:

  • 快速构建Web医学影像查看器(如结合React/Vue前端调用WADO-RS获取图像);

  • 开发AI辅助诊断平台(通过STOW-RS上传分析结果,用QIDO-RS筛选待处理的病例);

  • 实现跨机构影像共享(通过WADO-RS安全访问其他医院的PACS数据)。

相关推荐
裤裤兔16 天前
变换nii图像的左右,将nifti影像左右翻转
dicom·医学影像·医学图像·脑科学·影像·nifti
西哥写代码1 个月前
基于dcmtk的dicom工具 第十三章 dicom文件导出bmp、jpg、png、tiff、mp4
c++·mfc·dicom·dcmtk·tiffopen·dipngplugin·dijpegplugin
西哥写代码1 个月前
基于dcmtk的dicom工具 第十二章 响应鼠标消息实现图像的调窗、缩放、移动
c++·mfc·dicom·dcmtk·vs2017
西哥写代码1 个月前
基于dcmtk的dicom工具 第十一章 加载dicom文件多帧图数据
c++·dicom·dcmtk·vs2017·多帧图
右弦GISer4 个月前
【UE5医学影像可视化】读取本地Dicom生成VolumeTexture,实现2D显示和自动翻页
ue5·dicom·医学图像
漫步企鹅4 个月前
【worklist】worklist的hl7、dicom是什么关系
hl7·dicom·worklist
不老刘4 个月前
如何将DICOM文件制作成在线云胶片
dicom·云影像·云胶片
右弦GISer4 个月前
【UE5医学影像可视化】读取dicom数据生成2D纹理并显示
ue5·dicom
西哥写代码4 个月前
基于dcmtk的dicom工具 第四章 图像接受StoreSCP(2)
mfc·dicom·dcmtk·vs2017