Référence des outils en ligne de commande DCMTK
DCMTK est l'OFFIS DICOM Toolkit — une implémentation de référence mature, sous licence BSD, de grandes parties de la norme DICOM. Cette compétence couvre ses outils en ligne de commande (l'API C++ est hors de propos ici).
Si vous pouvez le faire avec DICOM, il y a probablement un binaire dcm* pour cela.
L'inconvénient : la boîte à outils est vaste (~70 binaires répartis sur 12 modules) et les conventions de drapeaux (-x vs +x sont des drapeaux différents) sont surprenantes. Cette compétence existe pour qu'un agent IA puisse choisir le bon outil, écrire une invocation correcte du premier coup, et éviter les pièges classiques de DCMTK.
Modèle mental
DCMTK regroupe les outils en modules selon ce qu'ils manipulent :
dcmdata fichiers DICOM sur disque : analyse, vidage, modification, encodage/décodage (pas de réseau)
dcmnet DIMSE sur TCP : ECHO, STORE, FIND, MOVE, GET
dcmimage rendu des pixels DICOM vers des formats d'image courants (PNG/PNM/BMP/TIFF)
dcmjpeg compression/décompression JPEG (DCT) des pixels DICOM
dcmjpls compression/décompression JPEG-LS des pixels DICOM
dcmsr Comptes rendus structurés : vidage, rendu, échange aller-retour avec XML
dcmqrdb un petit serveur de base de données Q/R autonome (PACS de test) + indexeur
dcmwlm un petit serveur de liste de travail de modalité autonome
dcmsign signatures numériques DICOM (signer / vérifier / supprimer)
dcmrt inspection d'objets de radiothérapie (RT Plan / Struct / Dose / etc.)
dcmpstat États de présentation + SCP/SCU d'impression (avancé; non couvert ici)
dcmtls support TLS (utilisé par les outils dcmnet ; pas un outil en soi)
La dénomination CLI est cohérente une fois que vous l'avez comprise : les outils qui encodent commencent par dcmc* (dcmcjpeg, dcmcjpls, dcmcrle) ; les outils qui décodent commencent par dcmd* (dcmdjpeg, dcmdjpls, dcmdrle) ; les SCU se terminent par *scu (client réseau) et les SCP se terminent par *scp (serveur réseau).
La carte des services DIMSE
Classe de service Opération Outil SCU Outil SCP
─────────────────────────────────────────────────────────────────
Vérification C-ECHO echoscu storescp accepte
Stockage C-STORE storescu, dcmsend storescp, dcmrecv
Interrogation/Récup. C-FIND findscu dcmqrscp
C-MOVE movescu dcmqrscp
C-GET getscu dcmqrscp
Liste de travail C-FIND findscu (avec -W) wlmscpfs
Pour un vrai PACS, vous utiliseriez Orthanc / DCM4CHEE / ConQuest comme SCP. Les propres SCP de DCMTK (dcmqrscp, wlmscpfs) sont destinés aux tests et à l'échafaudage d'intégration.
La convention de préfixe de drapeau
-x TOUJOURS un choix mutuellement exclusif (un mode parmi plusieurs)
+x TOUJOURS active une fonctionnalité ou ajoute quelque chose
--x forme longue de -x ou +x ; même sémantique
Donc -xe (proposer little-endian) et +e1 (encoder JPEG Baseline) ne sont pas liés — préfixe différent, famille d'outils différente, signification différente.
Quel outil pour quelle tâche
| Vous voulez … | Outil | Référence |
|---|---|---|
| Vérifier qu'un PACS est accessible | echoscu | dcmnet.md |
| Envoyer un/des fichier(s) DICOM à un PACS | dcmsend (ou storescu pour un contrôle TS fin) | dcmnet.md |
| Recevoir DICOM dans un dossier | storescp (ou dcmrecv) | dcmnet.md |
| Interroger un PACS (par PatientID / Date / Accession) | findscu | dcmnet.md |
| Récupérer des études d'un PACS | movescu ou getscu | dcmnet.md |
| Afficher toutes les balises d'un fichier DICOM | dcmdump | dcmdata.md |
| Trouver une balise dans un fichier DICOM | dcmdump --search KEY | dcmdata.md |
| Anonymiser / modifier une balise | dcmodify | dcmdata.md |
| Convertir DICOM → JSON | dcm2json | dcmdata.md |
| Convertir DICOM → XML | dcm2xml | dcmdata.md |
| Vérifier qu'un fichier est un DICOM Part-10 valide | dcmftest | dcmdata.md |
| Construire un DICOMDIR pour l'échange multimédia | dcmmkdir (alias legacy : dcmgpdir) | dcmdata.md |
| Changer la syntaxe de transfert (non compressé uniquement) | dcmconv | dcmdata.md |
| Compresser DICOM avec JPEG | dcmcjpeg | image-codecs.md |
| Décompresser DICOM encodé en JPEG | dcmdjpeg | image-codecs.md |
| Compresser / décompresser avec JPEG-LS | dcmcjpls / dcmdjpls | image-codecs.md |
| Compresser / décompresser avec RLE | dcmcrle / dcmdrle | dcmdata.md |
| Rendre DICOM → PNG / JPEG / TIFF / BMP / PNM | dcm2img | image-codecs.md |
| Redimensionner une image DICOM | dcmscale | image-codecs.md |
| Encapsuler JPEG/PNG/BMP/TIFF en DICOM | img2dcm | img-pdf-import.md |
| Encapsuler un PDF (ou CDA/STL/OBJ) en DICOM encapsulé | dcmencap (alias legacy : pdf2dcm) | img-pdf-import.md |
| Extraire un PDF/CDA/STL/OBJ encapsulé d'un DICOM | dcmdecap (alias legacy : dcm2pdf) | img-pdf-import.md |
| Vider l'arbre de contenu d'un Compte Rendu Structuré | dsrdump | dcmsr.md |
| Rendre SR → HTML | dsr2html | dcmsr.md |
| Échange aller-retour SR via XML | dsr2xml / xml2dsr | dcmsr.md |
| Installer un PACS de test | dcmqrscp + dcmqridx | dcmqrdb-wlm.md |
| Installer un serveur de liste de travail de modalité de test | wlmscpfs | dcmqrdb-wlm.md |
| Signer / vérifier les signatures numériques DICOM | dcmsign | dcmsign-dcmrt.md |
| Inspecter les objets RT Plan / Struct / Dose | drtdump | dcmsign-dcmrt.md |
Pour les drapeaux partagés (journalisation, réseau, TLS, négociation de syntaxe de transfert, format de fichier) voir common-options.md. Pour les UID de syntaxe de transfert et les drapeaux -x* / +t* correspondants voir transfer-syntax-uids.md.
Recettes principales
Les exemples ci-dessous utilisent ces espaces réservés — remplacez-les par les valeurs réelles de l'environnement cible :
PACS_HOST nom d'hôte ou IP du PACS pair ex. pacs.hospital.local
PACS_PORT port TCP DICOM du pair ex. 104, 4242, 11112
PACS_AET titre AE appelé — doit correspondre à la config du pair ex. MAIN_PACS
MY_AET notre titre AE appelant ex. ACME_SCU
1. Vérifier qu'un PACS est accessible (C-ECHO)
echoscu -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET
Le succès ressemble à Received Echo Response (Success). Si vous voyez Association Rejected, le pair ne connaît pas votre titre AE -aec ou votre IP n'est pas dans la liste blanche de sa configuration.
2. Envoyer des fichiers DICOM à un PACS (C-STORE)
Fichier unique, contrôle complet de la TS :
storescu -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET input.dcm
Dossier, récursif, avec renommage par fichier en cas de succès :
dcmsend -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET +sd +r /path/to/studies/
Quand utiliser lequel :
storescu— éprouvé, contrôle total via-x*sur la négociation de TS, pas de mode intégré "parcourir un dossier" au-delà de+sd +r. À utiliser quand vous avez besoin d'un contrôle précis sur les TS proposées.dcmsend— plus récent, plus simple. Gère l'analyse des répertoires, le résumé d'état, le renommage.done/.bad. Recommandé par défaut pour les envois par lots à un pair connu.
Échec courant : Association Aborted: presentation context not supported. Le pair n'accepte pas la classe SOP ou la TS dans laquelle le fichier est encodé. Exécutez avec -d pour voir la négociation ; les AC proposées par rapport aux AC acceptées rendent le problème évident.
3. Recevoir DICOM dans un dossier (C-STORE SCP)
storescp -v -aet MY_AET --output-directory /path/to/incoming/ \
--sort-conc-studies study_ PACS_PORT
Les fichiers arrivent dans /path/to/incoming/study_<StudyInstanceUID>/.
Pour un modèle de nom de fichier plus flexible et des hooks de post-traitement par étude, dcmrecv est l'alternative moderne — même idée, configuration plus simple :
dcmrecv -v --output-directory /path/to/incoming/ PACS_PORT
4. Interroger un PACS (C-FIND)
Une requête C-FIND est construite avec des clés -k : chaque -k soit contraint la recherche (-k "(0010,0020)=PATIENT_ID"), soit demande que cet attribut soit retourné (-k "(0010,0010)" avec valeur vide).
Toutes les études pour un patient :
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
Drapeaux à connaître :
-Smodèle racine étude (par défaut et le plus courant) ;-Pracine patient ;-Wliste de travail(0008,0052)QueryRetrieveLevel — doit correspondre au modèle (STUDY/SERIES/IMAGE)- Chaque
-kavec une valeur contraint ; chaque-ksans valeur (juste la balise) demande au SCP de la retourner
5. Récupérer des études (C-MOVE)
C-MOVE demande au SCP de pousser des instances vers un AE de destination — ce qui signifie que la destination doit être un storescp/dcmrecv en cours d'exécution accessible depuis le SCP, et que le titre AE de la destination doit être pré-enregistré sur le SCP.
Terminal A — démarrer l'écouteur local :
storescp -v --output-directory ./retrieved/ -aet MY_AET 11112
Terminal B — émettre le C-MOVE (destination = notre MY_AET sur le port 11112) :
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
Si le PACS n'a pas d'entrée pour MY_AET dans sa configuration, le déplacement échoue avec Move Destination Unknown. movescu peut également agir comme un écouteur subordonné avec --port 11112 --output-directory ./out/ — utile pour les tests où vous ne voulez pas de terminal storescp séparé.
Pour une récupération point à point où le SCP n'a pas besoin de connaître votre écouteur, C-GET (getscu) est plus simple :
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
Mais de nombreux PACS de production ne prennent pas en charge C-GET — C-MOVE est la valeur par défaut la plus sûre.
6. Vider les balises d'un fichier
Fichier entier, chaque balise :
dcmdump input.dcm
Juste une balise (par nom ou par groupe/élément) :
dcmdump --search PatientID input.dcm
dcmdump --search "0010,0010" input.dcm
La sortie est une ligne par attribut :
(0010,0010) PN [DOE^JANE] # 8, 1 PatientName
Colonnes : balise, VR, valeur, longueur, multiplicité de la valeur, nom de l'attribut.
Pour descendre récursivement dans les éléments de séquence (par exemple, lire un arbre de Compte Rendu Structuré), ajoutez +R. Pour sauter le vidage des données de pixels brutes, ajoutez --max-read-length 4. La sortie de dcmdump peut être analysée en DICOM par dump2dcm pour une édition aller-retour.
7. Anonymiser / modifier les balises
dcmodify modifie sur place (crée une sauvegarde .bak sauf si -nb) :
# Remplacer PatientName partout où il apparaît (ensemble principal + chaque élément de séquence)
dcmodify -nb -ma "(0010,0010)=ANON^PATIENT" input.dcm
# Insérer une balise qui n'était pas là
dcmodify -nb -i "(0010,4000)=anonymized 2026-05-25" input.dcm
# Supprimer chaque balise privée (le groupe est impair)
dcmodify -nb -ep input.dcm
# Générer de nouveaux UID pour la hiérarchie étude/série/instance
dcmodify -nb -gst -gse -gsi input.dcm
Drapeaux d'opération (mutuellement exclusifs par balise) :
-iinsérer si absent (erreur si présent)-mmodifier si présent (erreur si absent)-mamodifier-tout (ensemble principal + chaque élément de séquence)-eeffacer /-eaeffacer-tout /-epeffacer-privé-gst-gse-gsirégénérer les UID Study/Series/SOPInstance
Piège : par défaut, dcmodify écrit un .bak de chaque fichier modifié. Sur une anonymisation de 10 000 fichiers, cela double l'utilisation du disque et est presque toujours indésirable — passez toujours -nb pour le travail par lots.
8. Rendre DICOM en PNG / JPEG / TIFF / BMP / PNM
dcm2img +on input.dcm out.png # PNG (8 bits)
dcm2img +on2 input.dcm out.png # PNG (16 bits — conserver la pleine profondeur de bits)
dcm2img +oj input.dcm out.jpg # JPEG (8 bits avec perte de base)
dcm2img +ot input.dcm out.tiff # TIFF
dcm2img +ob input.dcm out.bmp # BMP
dcm2img +op input.dcm out.pgm # PNM brut (PGM pour niveaux de gris, PPM pour couleur)
Convention de lettre de drapeau dcm2img : +o<lettre> choisit le format de sortie (n=PNG, j=JPEG, t=TIFF, b=BMP, p=PNM/PGM/PPM, l=JPEG-LS). +oa (--write-auto) choisit en fonction de l'extension du nom de fichier de sortie.
dcm2img décompresse automatiquement les entrées JPEG / JPEG-LS / RLE — aucune étape dcmdjpeg séparée n'est nécessaire. Pour les données multi-trames, +Fa écrit un fichier de sortie par trame (les noms de fichiers reçoivent un suffixe de numéro de trame).
Si vous avez besoin de contrôler le fenêtrage plutôt que de laisser dcm2img utiliser la VOI LUT du fichier :
dcm2img +on +Wm input.dcm out.png # utiliser min/max des pixels comme fenêtre
dcm2img +on +W 50 350 input.dcm out.png # WindowCenter=50, WindowWidth=350
dcm2pnm, dcmj2pnm, dcml2pnm sont des alias obsolètes pour dcm2img — n'utilisez pas les anciens noms.