¿Qué hace Referencia de línea de comandos de DCMTK?
DCMTK es el OFFIS DICOM Toolkit — una implementación de referencia madura, con licencia BSD, de grandes partes del estándar DICOM. Esta skill cubre sus herramientas de línea de comandos (la API de C++ está fuera del alcance aquí).
Si puedes hacerlo con DICOM, probablemente exista un binario dcm* para ello. La desventaja: el conjunto de herramientas es grande (~70 binarios en 12 módulos) y las convenciones de banderas (-x vs +x son banderas diferentes) son sorprendentes. Esta skill existe para que un agente de IA pueda elegir la herramienta correcta, escribir una invocación correcta en el primer intento y evitar los clásicos escollos de DCMTK.
Modelo mental
DCMTK agrupa herramientas en módulos según lo que tocan:
dcmdata archivos DICOM en disco: analizar, volcar, modificar, codificar/descodificar (sin red)
dcmnet DIMSE sobre TCP: ECHO, STORE, FIND, MOVE, GET
dcmimage renderizar datos de píxeles DICOM a formatos de imagen comunes (PNG/PNM/BMP/TIFF)
dcmjpeg compresión/descompresión JPEG (DCT) de datos de píxeles DICOM
dcmjpls compresión/descompresión JPEG-LS de datos de píxeles DICOM
dcmsr Informes Estructurados: volcar, renderizar, intercambio con XML
dcmqrdb un pequeño servidor de base de datos Q/R independiente (PACS de prueba) + indexador
dcmwlm un pequeño servidor independiente de Lista de Trabajo de Modalidad
dcmsign firmas digitales DICOM (firmar/verificar/eliminar)
dcmrt inspección de objetos de Radioterapia (RT Plan/Struct/Dose/etc.)
dcmpstat Estados de presentación + print SCP/SCU (avanzado; no cubierto aquí)
dcmtls soporte TLS (usado por herramientas dcmnet; no es una herramienta en sí)
La nomenclatura CLI es consistente una vez que la ves: las herramientas que codifican comienzan con dcmc* (dcmcjpeg, dcmcjpls, dcmcrle); las herramientas que descodifican comienzan con dcmd* (dcmdjpeg, dcmdjpls, dcmdrle); los SCU terminan en *scu (cliente de red) y los SCP terminan en *scp (servidor de red).
El mapa de servicios DIMSE
Clase de servicio Operación Herramienta SCU Herramienta SCP
─────────────────────────────────────────────────────────────────
Verificación C-ECHO echoscu storescp acepta
Almacenamiento C-STORE storescu, dcmsend storescp, dcmrecv
Consulta/Recuperación C-FIND findscu dcmqrscp
C-MOVE movescu dcmqrscp
C-GET getscu dcmqrscp
Lista de trabajo C-FIND findscu (con -W) wlmscpfs
Para un PACS real usarías Orthanc / DCM4CHEE / ConQuest como SCP. Los SCP propios de DCMTK (dcmqrscp, wlmscpfs) son para pruebas y andamiaje de integración.
La convención del prefijo de banderas
-x SIEMPRE una elección mutuamente excluyente (un modo entre varios)
+x SIEMPRE activa una característica o añade algo
--x forma larga de -x o +x; misma semántica
Así que -xe (proponer little-endian) y +e1 (codificar JPEG Baseline) no están relacionadas — prefijo diferente, familia de herramientas diferente, significado diferente.
Qué herramienta para cada tarea
| Quieres… | Herramienta | Referencia |
|---|---|---|
| Verificar que un PACS es accesible | echoscu | dcmnet.md |
| Enviar archivo(s) DICOM a un PACS | dcmsend (o storescu para control fino de TS) | dcmnet.md |
| Recibir DICOM en una carpeta | storescp (o dcmrecv) | dcmnet.md |
| Consultar un PACS (por PatientID / Date / Accession) | findscu | dcmnet.md |
| Obtener estudios de un PACS | movescu o getscu | dcmnet.md |
| Mostrar todas las etiquetas en un archivo DICOM | dcmdump | dcmdata.md |
| Encontrar una etiqueta en un archivo DICOM | dcmdump --search KEY | dcmdata.md |
| Anonimizar / modificar una etiqueta | dcmodify | dcmdata.md |
| Convertir DICOM → JSON | dcm2json | dcmdata.md |
| Convertir DICOM → XML | dcm2xml | dcmdata.md |
| Verificar que un archivo es DICOM Part-10 válido | dcmftest | dcmdata.md |
| Construir un DICOMDIR para intercambio en medios | dcmmkdir (alias heredado: dcmgpdir) | dcmdata.md |
| Cambiar sintaxis de transferencia (solo sin compresión) | dcmconv | dcmdata.md |
| Comprimir DICOM con JPEG | dcmcjpeg | image-codecs.md |
| Descomprimir DICOM codificado en JPEG | dcmdjpeg | image-codecs.md |
| Comprimir/descomprimir con JPEG-LS | dcmcjpls / dcmdjpls | image-codecs.md |
| Comprimir/descomprimir con RLE | dcmcrle / dcmdrle | dcmdata.md |
| Renderizar DICOM → PNG / JPEG / TIFF / BMP / PNM | dcm2img | image-codecs.md |
| Redimensionar una imagen DICOM | dcmscale | image-codecs.md |
| Convertir JPEG/PNG/BMP/TIFF a DICOM | img2dcm | img-pdf-import.md |
| Convertir un PDF (o CDA/STL/OBJ) a DICOM encapsulado | dcmencap (alias heredado: pdf2dcm) | img-pdf-import.md |
| Extraer PDF/CDA/STL/OBJ incrustado de un DICOM | dcmdecap (alias heredado: dcm2pdf) | img-pdf-import.md |
| Volcar el árbol de contenido de un Informe Estructurado | dsrdump | dcmsr.md |
| Renderizar SR → HTML | dsr2html | dcmsr.md |
| Intercambiar SR a través de XML | dsr2xml / xml2dsr | dcmsr.md |
| Levantar un PACS de prueba | dcmqrscp + dcmqridx | dcmqrdb-wlm.md |
| Levantar un servidor de Lista de Trabajo de prueba | wlmscpfs | dcmqrdb-wlm.md |
| Firmar/verificar firmas digitales DICOM | dcmsign | dcmsign-dcmrt.md |
| Inspeccionar objetos RT Plan/Struct/Dose | drtdump | dcmsign-dcmrt.md |
Para banderas compartidas (logging, red, TLS, negociación de sintaxis de transferencia, formato de archivo) consulta common-options.md. Para UIDs de sintaxis de transferencia y las banderas -x* / +t* correspondientes, consulta transfer-syntax-uids.md.
Recetas principales
Los ejemplos a continuación utilizan estos marcadores de posición — reemplázalos con los valores reales del entorno objetivo:
PACS_HOST nombre de host o IP del PACS remoto ej. pacs.hospital.local
PACS_PORT puerto TCP DICOM del PACS remoto ej. 104, 4242, 11112
PACS_AET título AE llamado — debe coincidir con la configuración del remoto ej. MAIN_PACS
MY_AET nuestro título AE llamante ej. ACME_SCU
1. Verificar que un PACS es accesible (C-ECHO)
echoscu -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET
El éxito se ve como Received Echo Response (Success). Si ves Association Rejected, el remoto no reconoce tu título AE -aec o tu IP no está en la lista blanca de su configuración.
2. Enviar archivos DICOM a un PACS (C-STORE)
Archivo único, control total de TS:
storescu -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET input.dcm
Carpeta, recursivamente, con renombrado por archivo en éxito:
dcmsend -v PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET +sd +r /ruta/a/estudios/
Cuándo usar cuál:
storescu— probado, control total con-x*sobre la negociación de TS, sin modo "escaneo de carpeta" incorporado más allá de+sd +r. Úsalo cuando necesites control exacto sobre qué TS se proponen.dcmsend— más nuevo, más simple. Maneja escaneo de directorios, resumen de estado, renombrado.done/.bad. Recomendado por defecto para envíos por lotes a un remoto conocido.
Fallo común: Association Aborted: presentation context not supported. El remoto no acepta la clase SOP o la TS en la que está codificado el archivo. Ejecuta con -d para ver la negociación; los contextos de presentación ofrecidos vs aceptados hacen evidente el problema.
3. Recibir DICOM en una carpeta (C-STORE SCP)
storescp -v -aet MY_AET --output-directory /ruta/a/entrantes/ \
--sort-conc-studies study_ PACS_PORT
Los archivos llegan a /ruta/a/entrantes/study_<StudyInstanceUID>/.
Para plantillas de nombres de archivo más flexibles y ganchos de posprocesamiento por estudio, dcmrecv es la alternativa moderna — misma idea, configuración más simple:
dcmrecv -v --output-directory /ruta/a/entrantes/ PACS_PORT
4. Consultar un PACS (C-FIND)
Una consulta C-FIND se construye con claves -k: cada -k o restringe la búsqueda (-k "(0010,0020)=PATIENT_ID") o solicita que se devuelva ese atributo (-k "(0010,0010)" con valor vacío).
Todos los estudios de un paciente:
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
Banderas a conocer:
-Smodelo raíz de estudio (predeterminado y más común);-Praíz de paciente;-Wlista de trabajo(0008,0052)QueryRetrieveLevel — debe coincidir con el modelo (STUDY/SERIES/IMAGE)- Cada
-kcon un valor restringe; cada-ksin valor (solo la etiqueta) solicita al SCP que lo devuelva
5. Recuperar estudios (C-MOVE)
C-MOVE pide al SCP que envíe instancias a un AE de destino — lo que significa que el destino debe ser un storescp/dcmrecv en ejecución accesible desde el SCP, y el título AE del destino debe estar pre-registrado en el SCP.
Terminal A — inicia el listener local:
storescp -v --output-directory ./recuperados/ -aet MY_AET 11112
Terminal B — emite el C-MOVE (destino = nuestro MY_AET en el puerto 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 el PACS no tiene una entrada para MY_AET en su configuración, el movimiento falla con Move Destination Unknown. El propio movescu también puede actuar como un listener subordinado con --port 11112 --output-directory ./out/ — útil para pruebas donde no quieres un terminal storescp separado.
Para recuperación punto a punto donde el SCP no necesita conocer tu listener en absoluto, C-GET (getscu) es más simple:
getscu -v -S -k "(0008,0052)=STUDY" -k "(0020,000D)=1.2.3.4.5.STUDY.UID" \
--output-directory ./recuperados/ \
PACS_HOST PACS_PORT -aec PACS_AET -aet MY_AET
Pero muchos PACS de producción no soportan C-GET — C-MOVE es la opción predeterminada más segura.
6. Volcar etiquetas de un archivo
Archivo completo, cada etiqueta:
dcmdump input.dcm
Solo una etiqueta (por nombre o por grupo/elemento):
dcmdump --search PatientID input.dcm
dcmdump --search "0010,0010" input.dcm
La salida es una línea por atributo:
(0010,0010) PN [DOE^JANE] # 8, 1 PatientName
Columnas: etiqueta, VR, valor, longitud, multiplicidad de valor, nombre del atributo.
Para recurrir en elementos de secuencia (ej., leer un árbol de Informe Estructurado) añade +R. Para omitir el volcado de datos de píxeles sin procesar añade --max-read-length 4. La salida de dcmdump puede ser analizada de vuelta a DICOM por dump2dcm para edición de ida y vuelta.
7. Anonimizar / modificar etiquetas
dcmodify modifica en el lugar (crea una copia de seguridad .bak a menos que se use -nb):
# Reemplaza PatientName en todas partes donde aparezca (conjunto principal + cada elemento de secuencia)
dcmodify -nb -ma "(0010,0010)=ANON^PATIENT" input.dcm
# Inserta una etiqueta que no estaba
dcmodify -nb -i "(0010,4000)=anonimizado 2026-05-25" input.dcm
# Elimina cada etiqueta privada (el grupo es impar)
dcmodify -nb -ep input.dcm
# Genera nuevos UIDs para la jerarquía estudio/serie/instancia
dcmodify -nb -gst -gse -gsi input.dcm
Banderas de operación (mutuamente excluyentes por etiqueta):
-iinsertar si está ausente (error si presente)-mmodificar si está presente (error si ausente)-mamodificar todo (conjunto principal + cada elemento de secuencia)-eborrar /-eaborrar todo /-epborrar privadas-gst-gse-gsiregenerar UIDs de Estudio/Serie/Instancia SOP
Truco: por defecto dcmodify escribe un .bak de cada archivo modificado. En una anonimización de 10,000 archivos eso duplica el uso de disco y casi siempre es no deseado — pasa -nb siempre para trabajo por lotes.
8. Renderizar DICOM a PNG / JPEG / TIFF / BMP / PNM
dcm2img +on input.dcm out.png # PNG (8 bits)
dcm2img +on2 input.dcm out.png # PNG (16 bits — mantiene profundidad completa)
dcm2img +oj input.dcm out.jpg # JPEG (8 bits con pérdida)
dcm2img +ot input.dcm out.tiff # TIFF
dcm2img +ob input.dcm out.bmp # BMP
dcm2img +op input.dcm out.pgm # PNM sin procesar (PGM para escala de grises, PPM para color)
Convención de letras de banderas de dcm2img: +o<letra> selecciona el formato de salida (n=PNG, j=JPEG, t=TIFF, b=BMP, p=PNM/PGM/PPM, l=JPEG-LS). +oa (--write-auto) elige basándose en la extensión del nombre de archivo de salida.
dcm2img descomprime automáticamente entradas JPEG / JPEG-LS / RLE — no se necesita un paso separado de dcmdjpeg. Para datos multiframe, +Fa escribe un archivo de salida por frame (los nombres de archivo reciben un sufijo de número de frame).
Si necesitas controlar el ventaneo en lugar de dejar que dcm2img use la VOI LUT del archivo:
dcm2img +on +Wm input.dcm out.png # usa el min/máx de píxeles como ventana
dcm2img +on +W 50 350 input.dcm out.png # WindowCenter=50, WindowWidth=350
dcm2pnm, dcmj2pnm, dcml2pnm son alias obsoletos para dcm2img.
9. Convertir una imagen a DICOM secundario
Imagen única:
img2dcm input.png output.dcm
img2dcm detecta el formato de entrada por extensión o contenido. Añade +st para generar una captura de pantalla secundaria sin pérdidas (SOP Class 1.2.840.10008.5.1.4.1.1.7).
10. Convertir un PDF a DICOM encapsulado
dcmencap input.pdf output.dcm
Para extraerlo de vuelta:
dcmdecap input.dcm output.pdf
dcmencap puede envolver cualquier archivo (CDA, STL, OBJ, texto plano) — no solo PDF. dcmdecap extrae los datos encapsulados, que pueden no ser PDF, así que inspecciona la salida o usa dcmdump primero para confirmar el tipo MIME.
11. Volcar un Informe Estructurado
dsrdump input.dcm
Esto produce un árbol de contenido textual detallado, no un diseño de página. Para ver el SR como HTML legible:
dsr2html input.dcm output.html
12. Levantar un PACS de prueba (Q/R SCP)
# 1. Inicializa el índice de la base de datos
dcmqridx /ruta/a/pacs_test/
# 2. Inicia el SCP (escuchando en el puerto 11112 por defecto)
dcmqrscp -v -c /ruta/a/pacs_test/
dcmqrscp es para pruebas — no para producción. No tiene control de acceso, no escala y no persiste metadatos más allá de su simple índice de archivos.
13. Firmar/verificar firmas digitales
# Firmar usando una clave privada y un certificadodcmsign -v -f input.dcm \
--profile X509 \
--key private.key \
--certificate certificate.crt
# Verificar una firmadcmsign --verify input.dcm
La verificación falla si el certificado de firma no está en la cadena de confianza del sistema o si el documento fue modificado después de la firma. Añade +V para una salida detallada de verificación.
Errores comunes y cómo solucionarlos
| Síntoma | Causa probable | Qué hacer |
|---|---|---|
Association Rejected | El SCP no conoce nuestro AE título o nuestra IP no está en lista blanca. | Verifica -aec y la configuración de la lista de control de acceso del SCP. |
Presentation context not supported | El SCP no acepta la clase SOP o la sintaxis de transferencia. | Usa -d para ver la negociación; prueba con -xe (little-endian explícito) o reduce el conjunto de TS propuestas. |
Move Destination Unknown | El SCP no tiene registrado el AE de destino (-aem). | Registra MY_AET como destino en la configuración del SCP (archivo de destinos o dcmqrscp). |
No such object en C-FIND/C-MOVE | El UID proporcionado no existe en el índice del SCP. | Verifica el UID con findscu primero. |
dcmdump sale sin salida | El archivo no es un archivo DICOM Part-10 válido. | Ejecuta dcmftest input.dcm primero; para archivos raw usa --read-file de dcmdump. |
dcmodify no cambia nada | La etiqueta no existe (necesitas -i en lugar de -m), o está protegida (grupo 0002, grupo 0004, o etiquetas de metadatos del archivo). -ma puede modificar en secuencias, pero no en metadatos del archivo. | Usa -i si la etiqueta no existe; dcmodify no puede cambiar etiquetas de metadatos (para eso usa dcmconv --replace). |
| La imagen renderizada se ve plana o negra | dcm2img usó la VOI LUT del archivo, pero esa LUT está mal o no es relevante para la presentación. | Añade +Wm (min/máx) o +W center width para anular manualmente. |
Referencias
Los enlaces a continuación apuntan a archivos markdown detallados en el directorio references/. Cada uno contiene: sintaxis completa, banderas, ejemplos y notas de implementación.
| Archivo de referencia | Cubre |
|---|---|
| dcmdata.md | dcmdump, dcmodify, dcmconv, dcm2json, dcm2xml, dcmftest, dcmmkdir, dcmgpdir, dump2dcm, xml2dcm, json2dcm, dcmcrle, dcmdrle, dcmcheck |
| dcmnet.md | echoscu, storescu, storescp, dcmsend, dcmrecv, findscu, movescu, getscu |
| image-codecs.md | dcmcjpeg, dcmdjpeg, dcmcjpls, dcmdjpls, dcm2img, dcmscale, dcm2pnm (obsoleto) |
| img-pdf-import.md | img2dcm, dcmencap, dcmdecap, pdf2dcm (heredado), dcm2pdf (heredado) |
| dcmsr.md | dsrdump, dsr2html, dsr2xml, xml2dsr |
| dcmqrdb-wlm.md | dcmqrscp, dcmqridx, wlmscpfs |
| dcmsign-dcmrt.md | dcmsign, drtdump |
| common-options.md | Opciones de logging (-v, -d, --log-level), configuración de red (tiempos de espera, buffers), opciones de TLS, parámetros de formato de archivo (+F, --write-xfer, --group-length). |
| transfer-syntax-uids.md | Tabla de UIDs de sintaxis de transferencia → su bandera de negociación (-xe, -xi, +e1…). |