¿Qué es DICOM?
DICOM — Digital Imaging and Communications in Medicine — es el estándar internacional para almacenar, transmitir y mostrar imágenes médicas e información asociada. Desarrollado conjuntamente por el American College of Radiology (ACR) y la National Electrical Manufacturers Association (NEMA), DICOM 3.0 fue publicado en 1993 y sigue siendo el estándar dominante en la actualidad, utilizado por prácticamente todos los hospitales, departamentos de radiología y fabricantes de dispositivos médicos del mundo.
DICOM es dos cosas en una: un formato de archivo para almacenar datos de imagen con ricos metadatos de paciente y adquisición, y un protocolo de red (basado en TCP/IP) para transmitir imágenes entre PACS (Sistemas de Archivado y Comunicación de Imágenes), modalidades (escáneres) y estaciones de trabajo de visualización. Cada escáner TC, máquina de RM, sistema de radiografía digital, unidad de ultrasonidos y escáner PET produce archivos DICOM.
La Estructura del Archivo DICOM
Un archivo DICOM tiene una estructura fija:
┌─────────────────────────────────────────────────┐
│ Preámbulo de 128 bytes (generalmente ceros) │
├─────────────────────────────────────────────────┤
│ Prefijo DICM de 4 bytes ("DICM" en ASCII) │
├─────────────────────────────────────────────────┤
│ Grupo de Metainformación de Archivo (0002,xxxx) │
│ (0002,0010) TransferSyntaxUID │
├─────────────────────────────────────────────────┤
│ Conjunto de Datos (todos los elementos restantes)│
│ (0008,0060) Modalidad = "CT" │
│ (0010,0010) NombrePaciente │
│ (0010,0020) IDPaciente │
│ (0028,0010) Filas │
│ (0028,0011) Columnas │
│ (0028,1050) CentroVentana │
│ (0028,1051) AnchoVentana │
│ (7FE0,0010) DatosPíxel │
└─────────────────────────────────────────────────┘
Elementos de Datos y Etiquetas
Cada pieza de información en DICOM es un elemento de datos identificado por una etiqueta — un par hexadecimal (grupo, elemento):
| Etiqueta | Palabra clave | Valor de ejemplo |
|---|---|---|
| (0008,0060) | Modalidad | CT, MR, CR, DX, PT, US, NM |
| (0008,103E) | DescripciónSerie | "TC CABEZA SIN CONTRASTE" |
| (0010,0010) | NombrePaciente | García^Juan^A |
| (0010,0020) | IDPaciente | 12345678 |
| (0010,0030) | FechaNacimientoPaciente | 19650312 |
| (0018,0050) | EspesorCorte | 2,5 (mm) |
| (0020,0013) | NúmeroInstancia | 47 (número de corte) |
| (0020,0032) | PosiciónImagenPaciente | -245,7, -151,3, 112,0 |
| (0028,0010) | Filas | 512 |
| (0028,0011) | Columnas | 512 |
| (0028,0030) | EspaciadoPíxel | 0,625, 0,625 (mm) |
| (0028,1050) | CentroVentana | 40 (unidades Hounsfield) |
| (0028,1051) | AnchoVentana | 400 (UH) |
| (0028,1052) | InterceptoReescalado | -1024 |
| (0028,1053) | PendienteReescalada | 1 |
| (7FE0,0010) | DatosPíxel | [array de píxeles binario] |
Datos de Imagen y Unidades Hounsfield (TC)
Las imágenes de TC usan Unidades Hounsfield (UH) — una escala calibrada donde:
- −1000 UH = aire
- −100 UH = grasa
- 0 UH = agua
- 700–3000 UH = hueso cortical
- 4000+ UH = implantes metálicos
El valor UH real se calcula:
UH = (valor_píxel_almacenado × PendienteReescalada) + InterceptoReescalado
El ventaneo controla qué parte del rango de UH se muestra como escala de grises visible. Presets comunes:
- Pulmón: CV = −600, AV = 1500
- Cerebro: CV = 40, AV = 80
- Hueso: CV = 400, AV = 1800
- Abdomen/tejidos blandos: CV = 40, AV = 400
Lectura de DICOM con Python (pydicom)
pydicom es la biblioteca Python estándar para DICOM:
import pydicom
import numpy as np
import matplotlib.pyplot as plt
# Cargar un archivo DICOM
ds = pydicom.dcmread("TC_corte_047.dcm")
# Acceder a metadatos
print(f"Paciente: {ds.PatientName}")
print(f"ID Paciente: {ds.PatientID}")
print(f"Modalidad: {ds.Modality}")
print(f"Tamaño de imagen: {ds.Rows} × {ds.Columns}")
print(f"Espaciado de píxel: {ds.PixelSpacing} mm")
print(f"Espesor de corte: {ds.SliceThickness} mm")
# Obtener el array de píxeles
pixeles = ds.pixel_array # forma (512, 512), dtype uint16
# Convertir a Unidades Hounsfield
uh = pixeles * float(ds.RescaleSlope) + float(ds.RescaleIntercept)
print(f"Rango de UH: {uh.min():.0f} a {uh.max():.0f}")
# Aplicar ventaneo para visualización
cv = float(ds.WindowCenter)
av = float(ds.WindowWidth)
img_min = cv - av / 2
img_max = cv + av / 2
ventaneado = np.clip(uh, img_min, img_max)
ventaneado = ((ventaneado - img_min) / av * 255).astype(np.uint8)
plt.imshow(ventaneado, cmap="gray")
plt.title(f"Corte TC {ds.InstanceNumber}")
plt.axis("off")
plt.savefig("corte_tc.png", dpi=150, bbox_inches="tight")
# Cargar una serie completa (múltiples cortes) y apilarlos en un volumen 3D
import os
archivos_dicom = sorted(
[os.path.join("serie_tc/", f) for f in os.listdir("serie_tc/") if f.endswith(".dcm")],
key=lambda f: pydicom.dcmread(f).InstanceNumber
)
cortes = [pydicom.dcmread(f).pixel_array for f in archivos_dicom]
volumen = np.stack(cortes, axis=0) # forma (N_cortes, 512, 512)
print(f"Forma del volumen 3D: {volumen.shape}")
Anonimización DICOM
Los archivos DICOM contienen información de identificación del paciente que debe eliminarse antes de compartirlos para investigación:
import pydicom
def anonimizar_dicom(ruta_entrada, ruta_salida):
ds = pydicom.dcmread(ruta_entrada)
etiquetas_a_limpiar = [
(0x0010, 0x0010), # NombrePaciente
(0x0010, 0x0020), # IDPaciente
(0x0010, 0x0030), # FechaNacimientoPaciente
(0x0008, 0x0020), # FechaEstudio
(0x0008, 0x0090), # NombreMédicoRemitente
(0x0008, 0x1030), # DescripciónEstudio
]
for etiqueta in etiquetas_a_limpiar:
if etiqueta in ds:
ds[etiqueta].value = "ANONIMO"
ds.save_as(ruta_salida)
anonimizar_dicom("original.dcm", "anonimizado.dcm")
Conversión de DICOM a NIfTI para Neuroimagen
NIfTI es el formato estándar usado por el software de análisis de neuroimagen (FSL, FreeSurfer, SPM, ANTs, nilearn):
# dcm2niix — el convertidor DICOM → NIfTI de referencia
dcm2niix -o ./salida/ -f "%p_%t_%s" -z y ./serie_dicom/
# Produce:
# salida/TCCabeza_20240315_001.nii.gz (NIfTI comprimido)
# salida/TCCabeza_20240315_001.json (archivo lateral BIDS con parámetros de adquisición)
Visualización DICOM y PACS
- 3D Slicer: plataforma gratuita de código abierto para análisis de imagen médica — carga series DICOM, renderiza volúmenes 3D, realiza segmentación
- OsiriX / Horos (macOS): estación de trabajo PACS con MPR curvo y renderizado 3D
- OHIF Viewer: visor DICOM basado en web vía API REST DICOMweb (WADO-RS/STOW-RS)
- Orthanc: servidor DICOM de código abierto para construir PACS locales
Sintaxis de Transferencia DICOM (Compresión)
La UID de Sintaxis de Transferencia determina cómo se comprimen los datos de píxeles:
| UID | Nombre | Notas |
|---|---|---|
| 1.2.840.10008.1.2.1 | VR Explícito Little Endian | Sin compresión, más común |
| 1.2.840.10008.1.2.4.70 | JPEG Sin Pérdida (proceso 14) | Sin pérdida, ampliamente compatible |
| 1.2.840.10008.1.2.4.90 | JPEG 2000 Sin Pérdida | Mejor compresión sin pérdida |
| 1.2.840.10008.1.2.4.91 | JPEG 2000 Con Pérdida | Archivos más pequeños, puede no ser aceptable para diagnóstico |
Conversiones relacionadas
Lo más habitual al trabajar con imágenes son estas direcciones de conversión: