关于 pydicom
pydicom 技能为使用 pydicom 读取、检查和处理 DICOM 数据提供指导,面向需要在 Python 中处理医学影像数据的开发者与研究人员。内容特别强调 PHI 防护、受控像素处理及经审核的去标识化流程。
主要功能
- 01读取 DICOM 数据集与元数据
- 02像素和多帧处理指导
- 03传输语法与编解码检查
- 04聚合元数据和技术清单 CLI
- 05去标识化审核流程指导
适用场景
- 01检查授权的本地 DICOM 文件
- 02规划多帧像素处理资源
- 03预检传输语法与编解码能力
- 04制作并审核去标识化衍生数据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill pydicom安装后在 Claude Code 中输入/pydicom确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/common_tags.mdtransfer_syntaxes.mdscripts/__init__.py_common.pyanonymize_dicom.pydeidentification_audit.pydicom_inventory.pydicom_to_image.pyextract_metadata.pypixel_frame_planner.pytransfer_syntax_inspector.pyuid_mapping_validator.py详细介绍
pydicom
使用 pydicom 进行 DICOM 数据集 I/O 和像素处理。此处审阅的当前稳定版本为 3.0.2。该版本修复了 CVE-2026-32711,这是一个由精心构造的 DICOMDIR 引发的路径遍历问题。pydicom 3.0.2 声明要求 Python >=3.10;其内置 DICOM 字典版本为 2024c,而在线 DICOM 标准可能已有更新。
强制安全边界
- 仅处理用户获准访问的本地数据。
- DICOM 元数据、文件名、私有元素、覆盖层、结构化内容和像素都可能包含受保护的健康信息(PHI)。
- 默认情况下,绝不打印
Dataset、导出完整元数据/JSON 或记录元素值。请使用有文档记录的允许列表,并输出汇总信息。 - pydicom 是通用 DICOM 框架,并非诊断查看器。像素输出、验证、转换和插件可用性都不构成诊断结论。
- 去标识化取决于具体配置文件、目的、接收方、司法管辖区和威胁环境,必须由隐私/DICOM 专家进行验证。
- 绝不要声称标签移除脚本符合 DICOM PS3.15、HIPAA、GDPR 或其他合规要求。保留原件并审计衍生输出。
- 将确定性假名化密钥和 UID 映射视为可重新识别身份的机密:遵循最小权限原则,并使用加密的/受管理的机密存储;绝不将其提交、同步、记录日志或与衍生数据共享,并制定备份、轮换、撤销和销毁流程。密钥泄露会使预期的隔离失效;轮换也会改变确定性映射。
- 在解析不可信或异常大的数据集之前,设置明确的输入文件、文件数量、帧数、解码字节数和输出限制。
安装
创建或激活隔离环境,然后安装经过审阅的确切版本:
uv pip install "pydicom==3.0.2"
未压缩像素数组和图像渲染:
uv pip install "pydicom==3.0.2" "numpy==2.5.1" "Pillow==12.3.0"
仅安装部署所需的传输语法插件:
# JPEG/JPEG-LS, JPEG 2000/HTJ2K, and faster RLE through pylibjpeg
uv pip install "numpy==2.5.1" "pylibjpeg==2.1.0" \
"pylibjpeg-libjpeg==2.4.0" "pylibjpeg-openjpeg==2.5.0" \
"pylibjpeg-rle==2.2.0"
# JPEG-LS encoder/decoder
uv pip install "numpy==2.5.1" "pyjpegls==1.5.1"
# Alternative decoder with platform-specific wheels
uv pip install "python-gdcm==3.2.6"
不同软件包/平台的插件许可证和 wheel 各不相同;部署前请先审阅。Pillow 存在有文档记录的解码限制,且 pydicom 提醒必须独立检查插件输出。
原生编解码器 wheel 会扩大供应链和内存安全边界。对于受控部署,请在可信构建主机上解析这些确切的固定版本,锁定并验证 wheel 的哈希/来源,在内部镜像获准的构件,对其进行扫描,并通过哈希校验强制安装,而不是在运行时从公共索引解析。
选择工作流
- 需要汇总概览:运行
scripts/extract_metadata.py。 - 需要有限范围的技术检查:运行
scripts/dicom_inventory.py。 - 需要编解码器部署预检:运行
scripts/transfer_syntax_inspector.py。 - 需要规划帧数/内存:运行
scripts/pixel_frame_planner.py。 - 需要渲染一个非诊断用途的帧:运行
scripts/dicom_to_image.py。 - 需要假名化衍生数据:阅读去标识化部分,创建经站点审阅的操作配置文件,然后运行
scripts/anonymize_dicom.py和scripts/deidentification_audit.py。 - 需要检查敏感 UID 映射:运行
scripts/uid_mapping_validator.py。
安全读取数据集
dcmread() 会返回一个 FileDataset,它是 Dataset 的子类,包含 file_meta、前导码和原始编码等文件格式状态。
from pathlib import Path
import pydicom
path = Path("authorized/input.dcm")
ds = pydicom.dcmread(
path,
stop_before_pixels=True,
specific_tags=[
"SOPClassUID",
"Modality",
"Rows",
"Columns",
"NumberOfFrames",
],
)
technical = {
"sop_class": ds.get("SOPClassUID"),
"modality": ds.get("Modality"),
"rows": ds.get("Rows"),
"columns": ds.get("Columns"),
}
请使用:
- 仅处理元数据时使用
stop_before_pixels=True。 - 使用
specific_tags=[...]指定最小允许列表。 - 后续写入必须保留大值时使用
defer_size="1 MiB"。 - 使用
force=False(默认值)。force=True只会跳过文件格式标头检查,并不能证明字节内容是有效的 DICOM。
处理临床数据时,不要调用 print(ds)、repr(ds),也不要将遍历得到的值写入日志。
Dataset、DataElement 和序列
通过关键字访问标准元素并检查元素是否缺失:
modality = ds.get("Modality", "UNSPECIFIED")
if "ReferencedImageSequence" in ds:
for item in ds.ReferencedImageSequence:
referenced_class = item.get("ReferencedSOPClassUID")
通过标签访问(例如 ds[0x0010, 0x0010])会返回一个 DataElement;其 .value
是单独的值。Sequence 的行为类似于嵌套 Dataset 项组成的列表。隐私
处理必须递归遍历每个序列项,而不能只处理顶层。
创建文件时,请使用 FileMetaDataset 存放组 0002,确保数据集和
文件元信息中的 SOP UID 一致,设置 Transfer Syntax UID,并以强制
文件格式写入:
from pydicom import dcmwrite
from pydicom.dataset import FileDataset, FileMetaDataset
from pydicom.uid import CTImageStorage, ExplicitVRLittleEndian, generate_uid
meta = FileMetaDataset()
meta.MediaStorageSOPClassUID = CTImageStorage
meta.MediaStorageSOPInstanceUID = generate_uid()
meta.TransferSyntaxUID = ExplicitVRLittleEndian
ds = FileDataset(None, {}, file_meta=meta, preamble=b"\0" * 128)
ds.SOPClassUID = meta.MediaStorageSOPClassUID
ds.SOPInstanceUID = meta.MediaStorageSOPInstanceUID
# Add all attributes required by the selected IOD before writing.
dcmwrite("new.dcm", ds, enforce_file_format=True, overwrite=False)
write_like_original 已在 pydicom 3.0 中弃用;请使用
enforce_file_format。写入成功并不代表符合完整的 PS3.3 IOD。
UID 和传输语法
文件元信息中的 Transfer Syntax UID 控制数据集编码和 像素压缩:
ts = ds.file_meta.TransferSyntaxUID
summary = {
"uid": str(ts),
"name": ts.name,
"compressed": ts.is_compressed,
"implicit_vr": ts.is_implicit_VR,
"little_endian": ts.is_little_endian,
}
在 pydicom 3.0 中,写入编码会优先根据 Transfer Syntax UID 选择,然后才考虑旧版 数据集标志。伪名化时不要替换结构性 UID(Transfer Syntax、SOP Class 或 编码方案 UID)。实例/引用 UID 的替换必须一一对应,并在完整的声明范围内保持一致。
在压缩、解压缩或封装前,请阅读 references/transfer_syntaxes.md。
像素数据和帧
稳定的 pydicom.pixels API 支持基于路径、指定帧的解码:
from pydicom.pixels import pixel_array
# Reads only the selected frame where the source permits it.
frame = pixel_array("authorized/image.dcm", index=0, raw=False)
形状语义:
- 单帧灰度:
(rows, columns) - 多帧灰度:
(frames, rows, columns) - 单帧彩色:
(rows, columns, samples) - 多帧彩色:
(frames, rows, columns, samples)
raw=False 会在可能的情况下将 YCbCr 像素数据转换为 RGB;raw=True 会保留
强制最小处理后的解码色彩空间。对于有界多帧迭代,请使用
iter_pixels(path, indices=[...])。
对于灰度显示,请按以下顺序应用变换:
from pydicom.pixels import apply_modality_lut, apply_voi_lut
modality_values = apply_modality_lut(frame, ds)
display_values = apply_voi_lut(modality_values, ds, index=0)
Modality LUT/重缩放和 VOI/窗宽窗位会改变显示和值的语义。
MONOCHROME1 可能需要反转显示。Palette Color 需要使用
apply_color_lut()。呈现状态和 ICC 行为可能需要经过验证的查看器。
定量分析中切勿使用逐帧最小值/最大值归一化。
压缩、解压缩和封装
- 访问
pixel_array会按需解码,但不会更改数据集。 Dataset.decompress()会原地更改 Pixel Data,设置为 Explicit VR Little Endian,更新图像元数据,并默认生成新的 SOP Instance UID。Dataset.compress(uid)会原地更改 Pixel Data 和 Transfer Syntax,并 默认生成新的 SOP Instance UID。- pydicom 3.0 内置/可发现的编码器支持稳定版插件矩阵中记录的 RLE Lossless、JPEG-LS 和 JPEG 2000 组合。
- 每个压缩帧都会单独编码,然后进行封装。对于外部编码的帧,请使用
encapsulate()或encapsulate_extended()。 - 使用当前的
pydicom.encaps.generate_frames()或get_frame()读取帧; 旧版封装生成器名称已在 pydicom 4 中弃用。
务必先检查功能支持情况,限制解码字节数/帧数,并独立验证像素正确性。有损压缩是否可接受不属于 pydicom 和 DICOM 编码规范的范畴。
DICOM JSON 和私有元素
Dataset.to_json()、to_json_dict() 和 Dataset.from_json() 实现了
DICOM JSON Model,但 pydicom 将 JSON 支持标记为 beta。完整 JSON 可能会内嵌
二进制数据,并暴露所有标识符和像素负载。不要将其作为元数据报告输出。BulkDataURI 处理器会带来额外的存储、授权和检索义务。
私有元素并未标准化,且可能包含 PHI:
# Recursive removal, but not sufficient de-identification by itself.
ds.remove_private_tags()
只有在明确审查过的安全私有元素策略下,才保留私有元素。 有关标签访问、隐私类别和标准参考,请阅读 references/common_tags.md。
去标识化工作流
DICOM PS3.15 附录 E 明确指出,保密配置文件无法保证移除所有身份识别信息,也不能替代完整的去标识化流程。
- 明确目的、接收方、关联需求、法规、威胁模型和可接受的重新识别风险。
- 选择基本应用级别保密配置文件以及所需选项(像素、可识别的视觉特征、图形、结构化内容、描述符、时间信息、患者特征、设备、机构、UID 和安全的私有数据)。
- 将源对象原样保存在受控存储中。
- 递归应用每项操作,包括嵌套序列。
- 在完整范围内一致地替换实例 UID/引用 UID;保留结构性 UID。
- 明确决定日期/时间的处理方式。固定偏移可以保留时间间隔,但不完整日期、时区、独立时间、闰日、纵向关联和外部事件都需要经过审核的策略。
- 检查像素、叠加层、图形、结构化内容和可识别的视觉特征。不能因缺少元数据就推断像素内容干净,也不能在未经验证的情况下将
BurnedInAnnotation=NO。 - 重建文件元信息和前导码,以防信息泄露。
- 执行技术验证和去标识化审计,然后进行专家验证和有记录的风险审查。
捆绑脚本会有意将 PatientIdentityRemoved 设为 NO,因为它无法确认去标识化已成功。
辅助 CLI
所有 --help 操作都不需要依赖项。这些工具不会访问网络,且除范围狭窄的技术白名单外,不会输出任何 DICOM 值。
捆绑内容包括两个链接的参考资料、有文档说明的辅助脚本和合成测试。pydicom 运行时依赖项从固定版本的 PyPI 发行版安装。
# Redacted aggregate metadata
python scripts/extract_metadata.py authorized/ --recursive
# Metadata-only technical inventory
python scripts/dicom_inventory.py authorized/ --recursive
# Installed codec/plugin capabilities
python scripts/transfer_syntax_inspector.py --input authorized/image.dcm
# Frame shape, byte, and transform plan
python scripts/pixel_frame_planner.py authorized/image.dcm --frames 0,2-4
# One non-diagnostic frame
python scripts/dicom_to_image.py authorized/image.dcm frame.png \
--acknowledge-pixel-phi
# Create a secret key, then a scoped pseudonymized derivative plus audit
python scripts/anonymize_dicom.py --generate-uid-key project.key
python scripts/anonymize_dicom.py authorized/in.dcm derived/out.dcm \
--uid-key-file project.key --uid-scope export-v1 \
--audit-report derived/out.audit.json
# Audit candidate metadata; no pixel decompression
python scripts/deidentification_audit.py derived/out.dcm
# Validate an explicitly requested sensitive UID mapping
python scripts/uid_mapping_validator.py derived/uid-map.json \
--uid-key-file project.key --uid-scope export-v1
生成的原始密钥文件仅为受控的本地便利措施,并且仅授予所有者权限。对于生产环境,请从经批准的密钥管理器中取出密钥字节并写入受限的临时文件,限制去标识化服务的访问权限,并在使用后安全删除。任何可选的 UID 映射都应与衍生文件分开存储;它会直接关联原始标识符和替换标识符。
pydicom 3.0 迁移说明
read_file()和write_file()已移除;请使用dcmread()和dcmwrite()。write_like_original已弃用;请使用enforce_file_format。pydicom.pixel_data_handlers已弃用,并计划在 v4 中移除;请使用pydicom.pixels。- 默认情况下,
Dataset.pixel_array使用新的像素后端,并会在可能时将 YCbCr 转换为 RGB。 JPEGLossless现在表示 UID1.2.840.10008.1.2.4.57;JPEGLosslessSV1为.70。Dataset.is_little_endian和is_implicit_VR已弃用,并计划在 v4 中移除。
来源(已于 2026-07-23 验证)
- PyPI 上的 pydicom 3.0.2 — 发布于
2026-03-19;Python
>=3.10。 - pydicom 发布版本 — 3.0.2 和 CVE-2026-32711 的详情。
- 稳定版发布说明
- 稳定版安装指南
- 数据集基础知识
- 稳定版像素教程
- 稳定版像素插件
- 稳定版压缩教程
- 稳定版 DICOM JSON 教程
- 稳定版私有元素指南
- 当前 DICOM 标准
- DICOM PS3.3、 PS3.5、 PS3.6 和 PS3.15
Agent 操作流程
- 检查环境。 确认数据访问权限、去标识化状态,以及适用的法规或规程。
- 明确输入。 根据数据或用户提供的信息确认格式、标识符和参数。任何会改变结果的值都应询问,不要猜测。
- 先运行小规模版本。 先使用去标识化样本或合成数据。
- 使用上述说明和参考资料执行完整任务。
- 验证结果。 根据临床指南和报告标准检查输出;临床内容须由具备资质的人员审核。
- 报告。 说明运行了什么(版本、命令、参数)、检查了什么,以及仍有哪些不确定之处。
| 如果发生以下情况 | 请执行以下操作 |
|---|---|
| 数据似乎包含可识别患者身份的信息 | 停止处理,并在继续处理前询问用户。 |
| 这些说明中的函数、标志或端点在已安装版本中不存在 | 查看已安装版本自己的文档(help()、--help、官方文档),进行调整并告知用户。切勿虚构 API。 |
| 必需的输入、标识符或参数含义不明确 | 询问用户,或在运行前明确说明所采用的假设。 |
诚信规则
- 切勿捏造结果、参数、标识符、引文或统计数据。如果无法运行或验证某项内容,请直言说明。
- 输出用于支持具备资质的专业人员作出决策,不构成医疗建议;切勿将其作为诊断或医嘱呈现。
- 此处与特定版本相关的详情可能已经过时:请根据已安装版本的官方文档进行确认。
- 对于会产生费用、占用共享 GPU 或云配额、涉及个人或患者数据,或无法撤销的操作,须事先征求同意。