Communitygithub.com

DCMTK 命令行参考

DCMTK 命令行工具的全面参考指南,帮助 AI 代理和开发者正确使用这个庞大的 DICOM 工具包。

DCMTK 命令行参考 是什么?

DCMTK 命令行参考技能为 AI 代理提供了 OFFIS DICOM 工具包中命令行工具的详细指南。该技能涵盖了大约 70 个跨 12 个模块的二进制文件,包括 dcmdata、dcmnet、dcmimage、dcmjpeg、dcmsr 等模块。它解释了 DCMTK 中 'x' 和 '+' 标志前缀的独特约定,这些前缀表示互斥选择或功能启用。技能内容包括用于网络操作的工具选择指南(如 echoscu、storescu、findscu、movescu)、文件操作(如 dcmdump、dcmodify、dcm2json)、图像压缩/解压缩以及结构化报告处理。它提供了常见任务的实战配方,例如验证 PACS 可达性、发送/接收 DICOM 文件、查询/检索研究、转储标签、匿名化数据和渲染图像。该技能支持多种 AI 代理平台,包括 Claude Code、Cursor 和 Codex,并包含避免常见陷阱的提示,例如演示上下文不支持和传输语法协商问题。通过按模块组织的心理模型和一致的工具命名约定,该技能使用户能够首次尝试就写出正确的 DCMTK 调用。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add Lightbridge-KS/agent-skills

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

DCMTK 命令行参考 是做什么的?

DCMTK 是 OFFIS DICOM 工具包——一个成熟的、BSD 许可的参考实现,涵盖了 DICOM 标准的大部分内容。本技能涵盖其命令行工具(C++ API 不在讨论范围内)。

如果你能用 DICOM 做某事,那么很可能存在一个对应的 dcm* 二进制文件。 难点在于:该工具集非常庞大(约 70 个二进制文件,分布在 12 个模块中),并且标志约定(-x 与 +x 是不同的标志)令人惊讶。本技能的存在是为了让 AI 代理能够选择正确的工具,在第一次尝试时写出正确的调用,并避开经典的 DCMTK 陷阱。

心智模型

DCMTK 根据工具所涉及的内容将工具分组到模块中:

dcmdata    磁盘上的 DICOM 文件:解析、转储、修改、编码/解码(无网络)
dcmnet     TCP 上的 DIMSE:ECHO、STORE、FIND、MOVE、GET
dcmimage   将 DICOM 像素数据渲染为常见图像格式(PNG/PNM/BMP/TIFF)
dcmjpeg    DICOM 像素数据的 JPEG(DCT)压缩/解压缩
dcmjpls    DICOM 像素数据的 JPEG-LS 压缩/解压缩
dcmsr      结构化报告:转储、渲染、与 XML 进行往返转换
dcmqrdb    一个小型的独立查询/检索数据库服务器(测试 PACS)+ 索引器
dcmwlm     一个小型的独立模态工作列表服务器
dcmsign    DICOM 数字签名(签名/验证/移除)
dcmrt      放射治疗对象检查(RT 计划/结构/剂量等)
dcmpstat   呈现状态 + 打印 SCP/SCU(高级;此处不讨论)
dcmtls     TLS 支持(由 dcmnet 工具使用;本身不是工具)

一旦你看到 CLI 命名,它是一致的:编码工具以 dcmc* 开头(dcmcjpeg、dcmcjpls、dcmcrle);解码工具以 dcmd* 开头(dcmdjpeg、dcmdjpls、dcmdrle);SCU 以 *scu 结尾(网络客户端),SCP 以 *scp 结尾(网络服务器)。

DIMSE 服务映射

   服务类          操作           SCU 工具             SCP 工具
   ─────────────────────────────────────────────────────────────────
   验证            C-ECHO           echoscu              storescp 接受
   存储            C-STORE           storescu, dcmsend    storescp, dcmrecv
   查询/检索       C-FIND           findscu              dcmqrscp
                      C-MOVE           movescu              dcmqrscp
                      C-GET            getscu               dcmqrscp
   工作列表        C-FIND           findscu (使用 -W)    wlmscpfs

对于真正的 PACS,你会使用 Orthanc / DCM4CHEE / ConQuest 作为 SCP。DCMTK 自己的 SCP(dcmqrscp、wlmscpfs)用于测试和集成脚手架。

标志前缀约定

  -x   始终是一个互斥选择(多种模式中的一种)
  +x   始终打开某个功能或添加某些内容
  --x  -x 或 +x 的长格式;语义相同

所以 -xe(提议小端)和 +e1(编码 JPEG Baseline)不相关——不同的前缀,不同的工具族,不同的含义。

为任务选择合适的工具

你想要…工具参考
验证 PACS 是否可达echoscudcmnet.md
将 DICOM 文件发送到 PACSdcmsend(或使用 storescu 进行精细 TS 控制)dcmnet.md
将 DICOM 接收到文件夹storescp(或 dcmrecv)dcmnet.md
查询 PACS(按 PatientID / Date / Accession)findscudcmnet.md
从 PACS 拉取研究movescu 或 getscudcmnet.md
显示 DICOM 文件中的所有标签dcmdumpdcmdata.md
在 DICOM 文件中查找一个标签dcmdump --search KEYdcmdata.md
匿名化/修改标签dcmodifydcmdata.md
将 DICOM 转换为 JSONdcm2jsondcmdata.md
将 DICOM 转换为 XMLdcm2xmldcmdata.md
验证文件是否为有效的 DICOM Part-10dcmftestdcmdata.md
为媒体交换构建 DICOMDIRdcmmkdir(旧别名:dcmgpdir)dcmdata.md
更改传输语法(仅限未压缩)dcmconvdcmdata.md
使用 JPEG 压缩 DICOMdcmcjpegimage-codecs.md
解压缩 JPEG 编码的 DICOMdcmdjpegimage-codecs.md
使用 JPEG-LS 压缩/解压缩dcmcjpls / dcmdjplsimage-codecs.md
使用 RLE 压缩/解压缩dcmcrle / dcmdrledcmdata.md
将 DICOM 渲染为 PNG / JPEG / TIFF / BMP / PNMdcm2imgimage-codecs.md
调整 DICOM 图像大小dcmscaleimage-codecs.md
将 JPEG/PNG/BMP/TIFF 封装为 DICOMimg2dcmimg-pdf-import.md
将 PDF(或 CDA/STL/OBJ)封装为封装的 DICOMdcmencap(旧别名:pdf2dcm)img-pdf-import.md
从 DICOM 中提取嵌入的 PDF/CDA/STL/OBJdcmdecap(旧别名:dcm2pdf)img-pdf-import.md
转储结构化报告的内容树dsrdumpdcmsr.md
将 SR 渲染为 HTMLdsr2htmldcmsr.md
通过 XML 往返 SRdsr2xml / xml2dsrdcmsr.md
搭建测试 PACSdcmqrscp + dcmqridxdcmqrdb-wlm.md
搭建测试模态工作列表服务器wlmscpfsdcmqrdb-wlm.md
签名/验证 DICOM 数字签名dcmsigndcmsign-dcmrt.md
检查 RT 计划/结构/剂量对象drtdumpdcmsign-dcmrt.md

有关共享标志(日志记录、网络、TLS、传输语法协商、文件格式),请参阅 common-options.md。有关传输语法 UID 和匹配的 -x* / +t* 标志,请参阅 transfer-syntax-uids.md。

顶级配方

下面的示例使用这些占位符——将它们替换为目标环境的实际值:

PACS_HOST       对端 PACS 的主机名或 IP                  例如 pacs.hospital.local
PACS_PORT       对端的 DICOM TCP 端口                       例如 104、4242、11112
PACS_AET        被调用的 AE 标题 — 必须与对端的配置匹配    例如 MAIN_PACS
MY_AET          我们自己的调用 AE 标题                     例如 ACME_SCU

1. 验证 PACS 是否可达(C-ECHO)

echoscu -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET

成功时显示 Received Echo Response (Success)。如果你看到 Association Rejected,说明对端不识别你的 -aec AE 标题,或者你的 IP 未在其配置的白名单中。

2. 将 DICOM 文件发送到 PACS(C-STORE)

单个文件,完全 TS 控制:

storescu -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET input.dcm

文件夹,递归,成功时按文件重命名:

dcmsend -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET +sd +r /path/to/studies/

何时使用哪个:

  • storescu — 经过实战检验,完全通过 -x* 控制 TS 协商,没有内置的“扫描文件夹”模式(除了 +sd +r)。当你需要精确控制提议哪些 TS 时使用它。
  • dcmsend — 更新、更简单。处理目录扫描、状态摘要、.done / .bad 重命名。建议用于向已知对端批量发送的默认选项。

常见失败:Association Aborted: presentation context not supported。对端不接受文件编码所用的 SOP 类或 TS。使用 -d 运行以查看协商过程;提供的 AC 与接受的 AC 会让问题显而易见。

3. 将 DICOM 接收到文件夹(C-STORE SCP)

storescp -v -aet MY_AET --output-directory /path/to/incoming/ \
         --sort-conc-studies study_ PACS_PORT

文件到达 /path/to/incoming/study_<StudyInstanceUID>/ 下。

对于更灵活的文件名模板和基于研究的事后处理钩子,dcmrecv 是更现代的替代方案——同样的理念,更简单的配置:

dcmrecv -v --output-directory /path/to/incoming/ PACS_PORT

4. 查询 PACS(C-FIND)

C-FIND 查询由 -k 键构建:每个 -k 要么约束搜索(-k "(0010,0020)=PATIENT_ID"),要么请求返回该属性(-k "(0010,0010)" 且值为空)。

某个患者的所有研究:

findscu -v -S \
  -k "(0008,0052)=STUDY" \
  -k "(0010,0020)=PATIENT_ID" \
  -k "(0010,0010)" \
  -k "(0020,000D)" \
  -k "(0008,0020)" \
  PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET

需要了解的标志:

  • -S 研究根模型(默认且最常见);-P 患者根;-W 工作列表
  • (0008,0052) QueryRetrieveLevel——必须与模型匹配(STUDY/SERIES/IMAGE)
  • 每个带值的 -k 进行约束;每个不带值(只有标签)的 -k 请求 SCP 返回它

5. 检索研究(C-MOVE)

C-MOVE 请求 SCP 将实例推送到目标 AE——这意味着目标必须是 SCP 可达的正在运行的 storescp/dcmrecv,并且目标的 AE 标题必须在 SCP 上预先注册。

终端 A — 启动本地监听器:

storescp -v --output-directory ./retrieved/ -aet MY_AET 11112

终端 B — 发出 C-MOVE(目标 = 我们在端口 11112 上的 MY_AET):

movescu -v -S \
  -k "(0008,0052)=STUDY" \
  -k "(0020,000D)=1.2.3.4.5.STUDY.UID" \
  -aem MY_AET \
  PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET

如果 PACS 在其配置中没有 MY_AET 的条目,则移动失败并显示 Move Destination Unknown。movescu 本身也可以作为从属监听器运行,使用 --port 11112 --output-directory ./out/——对于你不想单独启动 storescp 终端的测试很有用。

对于 SCP 根本不需要知道你的监听器的点对点检索,C-GET(getscu)更简单:

getscu -v -S -k "(0008,0052)=STUDY" -k "(0020,000D)=1.2.3.4.5.STUDY.UID" \
       --output-directory ./retrieved/ \
       PACS_HOST PACS_PORT -aec PACS_AET

但许多生产 PACS 不支持 C-GET——C-MOVE 是更安全的默认选择。

6. 转储文件中的标签

整个文件,每个标签:

dcmdump input.dcm

仅一个标签(按名称或按组/元素):

dcmdump --search PatientID input.dcm
dcmdump --search "0010,0010" input.dcm

输出是每行一个属性:

(0010,0010) PN [DOE^JANE]                                #   8, 1 PatientName

列:标签、VR、值、长度、值多重性、属性名称。

要递归进入序列项(例如,读取结构化报告树),添加 +R。要跳过原始像素数据转储,添加 --max-read-length 4。dcmdump 的输出可以被 dump2dcm 解析回 DICOM,以进行往返编辑。

7. 匿名化/修改标签

dcmodify 原地修改(除非使用 -nb,否则会创建 .bak 备份):

# 在所有出现的地方替换 PatientName(主集合 + 每个序列项)
dcmodify -nb -ma "(0010,0010)=ANON^PATIENT" input.dcm

# 插入一个不存在的标签
dcmodify -nb -i "(0010,4000)=anonymized 2026-05-25" input.dcm

# 删除所有私有标签(组号为奇数)
dcmodify -nb -ep input.dcm

# 为研究/序列/实例层次结构生成新的 UID
dcmodify -nb -gst -gse -gsi input.dcm

操作标志(每个标签互斥):

  • -i 如果不存在则插入(如果存在则报错)
  • -m 如果存在则修改(如果不存在则报错)
  • -ma 全部修改(主集合 + 每个序列项)
  • -e 擦除 / -ea 全部擦除 / -ep 擦除私有标签
  • -gst -gse -gsi 重新生成 Study/Series/SOPInstance UID

陷阱: 默认情况下,dcmodify 会为每个修改的文件写入一个 .bak。在 10k 文件匿名化时,这会使磁盘使用量翻倍,并且在批处理中几乎总是不需要的——始终为批处理传递 -nb。

8. 将 DICOM 渲染为 PNG / JPEG / TIFF / BMP / PNM

dcm2img +on input.dcm out.png      # PNG(8 位)
dcm2img +on2 input.dcm out.png     # PNG(16 位——保持完整位深)
dcm2img +oj input.dcm out.jpg      # JPEG(8 位有损基线)
dcm2img +ot input.dcm out.tiff     # TIFF
dcm2img +ob input.dcm out.bmp      # BMP
dcm2img +op input.dcm out.pgm      # PNM 原始格式(灰度用 PGM,彩色用 PPM)

dcm2img 标志字母约定:+o<字母> 选择输出格式(n=PNG、j=JPEG、t=TIFF、b=BMP、p=PNM/PGM/PPM、l=JPEG-LS)。+oa(--write-auto)根据输出文件扩展名选择。

dcm2img 会自动解压缩 JPEG / JPEG-LS / RLE 输入——无需单独的 dcmdjpeg 步骤。对于多帧数据,+Fa 为每帧写入一个输出文件(文件名会附加帧号后缀)。

如果你需要控制窗宽窗位,而不是让 dcm2img 使用文件的 VOI LUT:

dcm2img +on +Wm input.dcm out.png         # 使用像素的最小/最大值作为窗宽窗位
dcm2img +on +W 50 350 input.dcm out.png   # WindowCenter=50, WindowWidth=350

dcm2pnm、dcmj2pnm、dcml2pnm 是 dcm2img 的已弃用别名。

相关技能