Uso de las API estándar de C# y DICOMweb

En este artículo se muestra cómo trabajar con el servicio DICOMweb mediante C# y archivos de ejemplo .dcm de DICOM®.

Use estos archivos de ejemplo:

  • blue-circle.dcm
  • dicom-metadata.csv
  • green-square.dcm
  • red-triangle.dcm

El nombre de archivo, studyUID, seriesUID e instanceUID de los archivos DICOM de ejemplo son:

Archivo StudyUID SeriesUID InstanceUID
green-square.dcm 1.2.826.0.1.3680043.8.498.13230779778012324449356534479549187420 1.2.826.0.1.3680043.8.498.45787841905473114233124723359129632652 1.2.826.0.1.3680043.8.498.12714725698140337137334606354172323212
red-triangle.dcm 1.2.826.0.1.3680043.8.498.13230779778012324449356534479549187420 1.2.826.0.1.3680043.8.498.45787841905473114233124723359129632652 1.2.826.0.1.3680043.8.498.47359123102728459884412887463296905395
blue-circle.dcm 1.2.826.0.1.3680043.8.498.13230779778012324449356534479549187420 1.2.826.0.1.3680043.8.498.77033797676425927098669402985243398207 1.2.826.0.1.3680043.8.498.13273713909719068980354078852867170114

Nota:

Cada uno de estos archivos representa una sola instancia y forma parte del mismo estudio. Además, el cuadrado verde y el triángulo rojo forman parte de la misma serie, mientras que el círculo azul está en una serie independiente.

Requisitos previos

Para usar las API estándar de DICOMweb, necesita una instancia del servicio DICOM implementada. Para más información, consulte Implementación del servicio DICOM mediante Azure Portal.

Después de implementar una instancia del servicio DICOM, recupere la dirección URL del servicio de aplicaciones:

  1. Inicie sesión en Azure Portal.
  2. Busque Recursos recientes y seleccione la instancia del servicio DICOM.
  3. Copie la dirección URL de servicio de servicio DICOM. Asegúrese de especificar la versión como parte de la dirección URL al realizar solicitudes. Para más información, consulte Control de versiones de API para el servicio DICOM.

En la aplicación, instale los siguientes paquetes NuGet:

Creación de un DicomWebClient

Después de implementar el servicio DICOM, cree un DicomWebClient. Ejecute el fragmento de código para crear el DicomWebClient que usará durante el resto de este tutorial. Asegúrese de que tiene instalados ambos paquetes NuGet. Para más información, consulte Obtención del token de acceso para el servicio DICOM mediante la CLI de Azure.

string webServerUrl ="{Your DicomWeb Server URL}"
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(webServerUrl);
IDicomWebClient client = new DicomWebClient(httpClient);
client.HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", “{Your token value}”); 

Con DicomWebClient, ahora podemos realizar las operaciones de almacenamiento, recuperación, búsqueda y eliminación.

Almacenamiento de instancias DICOM (STOW)

Mediante el uso de DicomWebClient, ahora podemos almacenar archivos DICOM.

Almacenamiento de instancia única

El almacenamiento de una instancia única muestra cómo cargar un único archivo DICOM.

Detalles:

  • POST /studies
DicomFile dicomFile = await DicomFile.OpenAsync(@"{Path To blue-circle.dcm}");
DicomWebResponse response = await client.StoreAsync(new[] { dicomFile });

Almacenamiento de instancias para un estudio específico

El almacenamiento de instancias para un estudio específico muestra cómo cargar un archivo DICOM en un estudio especificado.

Detalles:

  • POST /studies/{estudio}
DicomFile dicomFile = await DicomFile.OpenAsync(@"{Path To red-triangle.dcm}");
DicomWebResponse response = await client.StoreAsync(new[] { dicomFile }, "1.2.826.0.1.3680043.8.498.13230779778012324449356534479549187420");

Antes de pasar a la siguiente parte del tutorial, cargue el archivo green-square.dcm mediante cualquiera de los métodos anteriores.

Recuperación de la instancia DICOM (WADO)

Los fragmentos de código muestran cómo realizar cada una de las consultas de recuperación mediante el DicomWebClient creado anteriormente.

Las variables se usan en el resto de los ejemplos:

string studyInstanceUid = "1.2.826.0.1.3680043.8.498.13230779778012324449356534479549187420"; //StudyInstanceUID for all 3 examples
string seriesInstanceUid = "1.2.826.0.1.3680043.8.498.45787841905473114233124723359129632652"; //SeriesInstanceUID for green-square and red-triangle
string sopInstanceUid = "1.2.826.0.1.3680043.8.498.47359123102728459884412887463296905395"; //SOPInstanceUID for red-triangle

Recuperación de todas las instancias de un estudio.

Detalles:

  • GET /studies/{estudio}
DicomWebResponse response = await client.RetrieveStudyAsync(studyInstanceUid);

Los tres archivos dcm que cargó anteriormente forman parte del mismo estudio, por lo que la respuesta debe devolver las tres instancias. Valida que la respuesta tenga un código de estado OK y que se devuelvan las tres instancias.

Uso de las instancias recuperadas

En el fragmento de código siguiente se muestra cómo acceder a las instancias que se recuperan. También muestra cómo acceder a algunos de los campos de las instancias y cómo guardarlos como un archivo dcm.

DicomWebAsyncEnumerableResponse<DicomFile> response = await client.RetrieveStudyAsync(studyInstanceUid);
await foreach (DicomFile file in response)
{
    string patientName = file.Dataset.GetString(DicomTag.PatientName);
    string studyId = file.Dataset.GetString(DicomTag.StudyID);
    string seriesNumber = file.Dataset.GetString(DicomTag.SeriesNumber);
    string instanceNumber = file.Dataset.GetString(DicomTag.InstanceNumber);

    file.Save($"<path_to_save>\\{patientName}{studyId}{seriesNumber}{instanceNumber}.dcm");
}

Recuperación de metadatos de todas las instancias del estudio

Esta respuesta recupera los metadatos de todas las instancias de un único estudio.

Detalles:

  • GET /studies/{estudio}/metadata
DicomWebResponse response = await client.RetrieveStudyMetadataAsync(studyInstanceUid);

Los tres archivos dcm cargados anteriormente forman parte del mismo estudio, por lo que la respuesta debe devolver los metadatos de las tres instancias. Valida que la respuesta tenga un código de estado OK y que se devuelvan todos los metadatos.

Recuperación de todas las instancias de una serie

Esta respuesta recupera todas las instancias de una sola serie.

Detalles:

  • GET /studies/{estudio}/series/{serie}
DicomWebResponse response = await client.RetrieveSeriesAsync(studyInstanceUid, seriesInstanceUid);

Esta serie tiene dos instancias (green-square y red-triangle), por lo que la respuesta debe devolver ambas instancias. Valida que la respuesta tenga un código de estado OK y que se devuelvan ambas instancias.

Recuperación de los metadatos de todas las instancias de una serie

Esta respuesta recupera los metadatos de todas las instancias de un único estudio.

Detalles:

  • GET /studies/{estudio}/series/{serie}/metadata
DicomWebResponse response = await client.RetrieveSeriesMetadataAsync(studyInstanceUid, seriesInstanceUid);

Esta serie tiene dos instancias (green-square y red-triangle), por lo que la respuesta debe devolver metadatos para ambas instancias. Valida que la respuesta tiene un código de estado OK y que se devuelvan ambas instancias de los metadatos.

Recuperación de una sola instancia dentro de una serie de un estudio

Recupera una única instancia.

Detalles:

  • GET /studies/{estudio}/series{serie}/instances/{instancia}
DicomWebResponse response = await client.RetrieveInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);

Esta respuesta solo debe devolver la instancia "red-triangle". Valida que la respuesta tenga un código de estado OK y que se devuelva la instancia.

Recuperación de metadatos de una sola instancia dentro de una serie de un estudio

Esta solicitud recupera los metadatos de una sola instancia dentro de un único estudio y serie.

Detalles:

  • GET /studies/{estudio}/series/{serie}/instances/{instancia}/metadata
DicomWebResponse response = await client.RetrieveInstanceMetadataAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);

Esta respuesta solo debe devolver los metadatos de la instancia "red-triangle". Valida que la respuesta tenga un código de estado OK y que se devuelvan los metadatos.

Recuperación de uno o varios marcos de una sola instancia

Recupera uno o varios marcos de una única instancia.

Detalles:

  • GET /studies/{estudio}/series/{serie}/instances/{instancia}/frames/{marcos}
DicomWebResponse response = await client.RetrieveFramesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, frames: new[] { 1 });

Esta respuesta debe devolver el único marco de "red-triangle". Valida que la respuesta tenga un código de estado OK y que se devuelve el marco.

Consulta de DICOM (QIDO)

Nota:

Consulte la instrucción de conformidad DICOM para conocer los atributos DICOM admitidos.

Búsqueda de estudios

Esta solicitud busca uno o varios estudios por atributos DICOM.

Detalles:

  • GET /studies?StudyInstanceUID={estudio}
string query = $"/studies?StudyInstanceUID={studyInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);

Valida que la respuesta incluya un estudio y que el código de respuesta sea OK.

Búsqueda de series

Esta solicitud busca una o varias series por atributos DICOM.

Detalles:

  • GET /series?SeriesInstanceUID={serie}
string query = $"/series?SeriesInstanceUID={seriesInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);

Valida que la respuesta incluya una serie y que el código de respuesta sea OK.

Búsqueda de series en un estudio

Esta solicitud busca una o varias series dentro de un único estudio mediante atributos DICOM.

Detalles:

  • GET /studies/{estudio}/series?SeriesInstanceUID={serie}
string query = $"/studies/{studyInstanceUid}/series?SeriesInstanceUID={seriesInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);

Valida que la respuesta incluya una serie y que el código de respuesta sea OK.

Búsqueda de instancias

Esta solicitud busca una o varias instancias por atributos DICOM.

Detalles:

  • GET /instances?SOPInstanceUID={instancia}
string query = $"/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);

Valida que la respuesta incluya una instancia y que el código de respuesta sea OK.

Búsqueda de instancias en un estudio

Esta solicitud busca una o varias instancias dentro de un único estudio por atributos DICOM.

Detalles:

  • GET /studies/{estudio}/instances?SOPInstanceUID={instancia}
string query = $"/studies/{studyInstanceUid}/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);

Valida que la respuesta incluya una instancia y que el código de respuesta sea OK.

Búsqueda de instancias dentro de un estudio y serie

Esta solicitud busca una o varias instancias dentro de un único estudio y serie por atributos DICOM.

Detalles:

  • GET /studies/{estudio}/series/{serie}instances?SOPInstanceUID={instancia}
string query = $"/studies/{studyInstanceUid}/series/{seriesInstanceUid}/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);

Valida que la respuesta incluya una instancia y que el código de respuesta sea OK.

Eliminación de DICOM

Nota:

La eliminación no forma parte del estándar DICOM, pero se ha agregado para mayor comodidad.

Eliminación de una instancia específica de un estudio y una serie

Esta solicitud elimina una única instancia de un único estudio y una sola serie.

Detalles:

  • DELETE /studies/{estudio}/series/{serie}/instances/{instancia}
string sopInstanceUidRed = "1.2.826.0.1.3680043.8.498.47359123102728459884412887463296905395";
DicomWebResponse response = await client.DeleteInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUidRed);

Este repositorio elimina la instancia de "red-triangle" del servidor. Si se realiza correctamente, el código de estado de respuesta no incluye contenido.

Eliminación de una serie específica de un estudio

Esta solicitud elimina una única serie (y todas las instancias secundarias) de un único estudio.

Detalles:

  • DELETE /studies/{estudio}/series/{serie}
DicomWebResponse response = await client.DeleteSeriesAsync(studyInstanceUid, seriesInstanceUid);

Esta respuesta elimina la instancia de "green-square" (es el único elemento que queda en la serie) del servidor. Si se realiza correctamente, el código de estado de respuesta no incluye contenido.

Eliminación de un estudio específico

Esta solicitud elimina un único estudio (y todas las series e instancias secundarias).

Detalles:

  • DELETE /studies/{estudio}
DicomWebResponse response = await client.DeleteStudyAsync(studyInstanceUid);

Esta respuesta elimina la instancia "blue-circle" (es el único elemento que queda en la serie) del servidor. Si se realiza correctamente, el código de estado de respuesta no incluye contenido.

Nota:

DICOM® es la marca registrada de la Asociación Nacional de Fabricantes Eléctricos para sus publicaciones de normas relacionadas con las comunicaciones digitales de información médica.