Communitygithub.com

DCMTK命令列參考

涵蓋 DCMTK 工具箱的命令列工具,協助 AI 代理選擇正確的工具並撰寫正確的呼叫。

DCMTK命令列參考 是什麼?

本技能提供 OFFIS DCMTK 工具箱(一套成熟的、BSD 授權的 DICOM 標準參考實作)中命令列工具的完整參考。它專注於約 70 個命令列二進位檔,這些檔案分佈在 12 個模組中(例如 dcmdata、dcmnet、dcmimage 等),用以處理 DICOM 檔案、網路通訊、影像壓縮、結構化報告及數位簽章。該技能解釋了 DCMTK 一致的命名慣例(例如用於編碼工具的 'dcmc*' 前綴、用於解碼工具的 'dcmd*' 前綴,以及用於網路客戶端/伺服器的 '*scu'/'*scp' 後綴),以及其反直覺的 '-x' 與 '+x' 旗標前綴慣例。它包含了一個廣泛的任務工具對應表、實際操作範例(例如使用 echoscu、storescu、dcmsend、findscu 和 movescu 進行 PACS 驗證、儲存、查詢及擷取),以及關於常見陷阱的關鍵見解,例如關聯拒絕、表示上下文不受支援,以及批次操作中 dcmodify 的 .bak 備份行為。此技能在 Cursor、Claude Code、Codex 等 AI 編碼代理上運作良好,其結構化 markdown 格式使其易於被 LLM 解析和推理。

相容平台~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* 二進位檔。 但要注意:這個工具集非常龐大(橫跨 12 個模組,約有 70 個二進位檔),而且其旗標慣例(-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 Plan / Struct / Dose 等)
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(提議 little-endian)和 +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 進行 SR 雙向轉換dsr2xml / xml2dsrdcmsr.md
建立測試用 PACSdcmqrscp + dcmqridxdcmqrdb-wlm.md
建立測試用排程工作清單伺服器wlmscpfsdcmqrdb-wlm.md
簽署/驗證 DICOM 數位簽章dcmsigndcmsign-dcmrt.md
檢查 RT Plan / Struct / Dose 物件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 — 經過實戰考驗,對 TS 協商有完整的 -x* 控制,除 +sd +r 外無內建「掃描資料夾」模式。當你需要精確控制要提議哪些 TS 時使用它。
  • dcmsend — 較新、較簡單。處理目錄掃描、狀態摘要、.done / .bad 重新命名。建議作為批次傳送到已知對端的預設工具。

常見失敗:Association Aborted: presentation context not supported。對端不接受檔案編碼所用的 SOP 類別或 TS。使用 -d 運行以查看協商過程;提供的表示上下文對比接受的表示上下文,問題就很明顯了。

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

僅一個標籤(按名稱或按 group/element):

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 備份。在一個包含 1 萬個檔案的匿名化任務中,這會使磁碟用量翻倍,而且幾乎總是不被希望的——對於批次工作,務必傳遞 -nb。

8. 將 DICOM 渲染為 PNG / JPEG / TIFF / BMP / PNM

dcm2img +on input.dcm out.png      # PNG (8-bit)
dcm2img +on2 input.dcm out.png     # PNG (16-bit — 保持完整位元深度)
dcm2img +oj input.dcm out.jpg      # JPEG (8-bit 有損基準)
dcm2img +ot input.dcm out.tiff     # TIFF
dcm2img +ob input.dcm out.bmp      # BMP
dcm2img +op input.dcm out.pgm      # PNM raw(灰度用 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         # 使用像素的最小/最大值作為窗寬

相關技能