Usar APIs padrão C# e DICOMweb

Este artigo mostra como trabalhar com o serviço DICOMweb usando C# e arquivos .dcm DICOM® de exemplo.

Use esses arquivos de exemplo:

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

O nome do arquivo, studyUID, seriesUID e instanceUID dos arquivos DICOM de exemplo são:

Arquivo 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

Observação

Cada um desses arquivos representa uma única instância e faz parte do mesmo estudo. Além disso, o quadrado verde e o triângulo vermelho fazem parte da mesma série, enquanto o círculo azul está em uma série separada.

Pré-requisitos

Para usar as APIs Padrão DICOMweb, você precisa de uma instância do serviço DICOM implantado. Para obter mais informações, consulte Implantar o serviço DICOM usando o portal do Azure.

Depois de implantar uma instância do serviço DICOM, recupere a URL do serviço de aplicativo:

  1. Entre no portal do Azure.
  2. Pesquise Recursos recentes e selecione sua instância de serviço DICOM.
  3. Copie a URL de Serviço do serviço DICOM. Especifique a versão como parte da URL ao fazer solicitações. Para obter mais informações, consulte Versão da API para o serviço DICOM.

Em seu aplicativo, instale os seguintes pacotes NuGet:

Criar um DicomWebClient

Depois de implantar seu serviço DICOM, você cria um DicomWebClient. Execute o snippet de código para criar DicomWebClient, que você usa para o restante deste tutorial. Verifique se você tem os dois pacotes NuGet instalados. Para obter mais informações, consulte Obter o token de acesso para o serviço DICOM usando a CLI do 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}”); 

Com o DicomWebClient, agora podemos executar as operações Store, Retrieve, Search e Delete.

Armazenar instâncias DICOM (STOW)

Usando o DicomWebClient, agora podemos armazenar arquivos DICOM.

Armazenamento de instância única

O armazenamento de instância única demonstra como fazer upload de um único arquivo DICOM.

Detalhes:

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

Armazenar instâncias para um estudo específico

As instâncias de armazenamento de um estudo específico demonstram como carregar um arquivo DICOM em um estudo especificado.

Detalhes:

  • POST /studies/{study}
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 passar para a próxima parte do tutorial, carregue o arquivo green-square.dcm usando qualquer um dos métodos anteriores.

Recuperar a instância do DICOM (WADO)

Os snippets de código mostram como executar cada uma das consultas de recuperação usando o DicomWebClient criado anteriormente.

As variáveis são usadas em todos os outros exemplos:

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

Recuperar todas as instâncias em um estudo

Detalhes:

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

Todos os três arquivos dcm carregados anteriormente fazem parte do mesmo estudo, portanto, a resposta deve retornar todas as três instâncias. Valide se a resposta tem um código de status de OK e se todas as três instâncias são retornadas.

Usar as instâncias recuperadas

O snippet de código a seguir mostra como acessar as instâncias recuperadas. Ele também mostra como acessar alguns dos campos das instâncias e como salvá-lo como um arquivo 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");
}

Recuperar metadados de todas as instâncias no estudo

Essa resposta recupera os metadados de todas as instâncias em um único estudo.

Detalhes:

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

Todos os três arquivos tcm que carregamos anteriormente fazem parte do mesmo estudo, portanto, a resposta deve retornar os metadados para todas as três instâncias. Valide se a resposta tem um código de status OK e se todos os metadados são retornados.

Recuperar todas as instâncias em uma série

Essa resposta recupera todas as instâncias em uma única série.

Detalhes:

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

Essa série tem duas instâncias (triângulo verde-quadrado e vermelho), portanto, a resposta deve retornar a duas instâncias. Valide se a resposta tem um código de status de OK e se ambas as instâncias são retornadas.

Recuperar metadados de todas as instâncias em uma série

Essa resposta recupera os metadados de todas as instâncias em um único estudo.

Detalhes:

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

Esta série tem duas instâncias (triângulo verde-quadrado e vermelho), portanto, a resposta deve retornar metadados para ambas as instâncias. Valide se a resposta tem um código de status de OK e se ambas as instâncias dos metadados são retornadas.

Recuperar uma única instância em uma série de um estudo

Essa solicitação recupera uma única instância.

Detalhes:

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

Essa resposta só deve retornar o triângulo vermelho da instância. Valide se a resposta tem um código de status de OK e se a instância é retornada.

Recuperar metadados de uma única instância em uma série de um estudo

Essa solicitação recupera os metadados de uma única instância em um único estudo e série.

Detalhes:

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

Essa resposta só deve retornar os metadados para o triângulo vermelho da instância. Valide se a resposta tem um código de status de OK e se os metadados são retornados.

Recuperar um ou mais quadros de uma única instância

Essa solicitação recupera um ou mais quadros de uma única instância.

Detalhes:

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

Essa resposta deve retornar o único quadro do triângulo vermelho. Valide se a resposta tem um código de status de OK e se o quadro é retornado.

Consulta DICOM (QIDO)

Observação

Consulte a Instrução de Conformidade DICOM para atributos DICOM com suporte.

Pesquisar estudos

Essa solicitação procura por um ou mais estudos por atributos DICOM.

Detalhes:

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

Valida se a resposta inclui um estudo e se o código de resposta está OK.

Pesquisar séries

Essa solicitação pesquisa uma ou mais séries por atributos DICOM.

Detalhes:

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

Valida se a resposta inclui uma série e se o código de resposta está OK.

Pesquisar séries em um estudo

Essa solicitação procura uma ou mais séries em um único estudo por atributos DICOM.

Detalhes:

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

Valida se a resposta inclui uma série e se o código de resposta está OK.

Pesquisar instâncias

Essa solicitação procura uma ou mais instâncias por atributos DICOM.

Detalhes:

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

Valida se a resposta inclui uma instância e se o código de resposta está OK.

Pesquisar instâncias em um estudo

Essa solicitação procura uma ou mais instâncias em um único estudo por atributos DICOM.

Detalhes:

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

Valida se a resposta inclui uma instância e se o código de resposta está OK.

Pesquisar instâncias em um estudo e série

Essa solicitação procura uma ou mais instâncias em um único estudo e uma única série por atributos DICOM.

Detalhes:

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

Valida se a resposta inclui uma instância e se o código de resposta está OK.

Excluir DICOM

Observação

A exclusão não faz parte do padrão DICOM, mas foi adicionada para conveniência.

Excluir uma instância específica em um estudo e uma série

Essa solicitação exclui uma única instância em um único estudo e uma única série.

Detalhes:

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

Esse repositório exclui a instância de triângulo vermelho do servidor. Se for bem-sucedido, o código de status de resposta não irá conter conteúdo.

Excluir uma série específica em um estudo

Essa solicitação exclui uma única série (e todas as instâncias filho) em um único estudo.

Detalhes:

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

Essa resposta exclui a instância verde-quadrada (é o único elemento restante na série) do servidor. Se for bem-sucedido, o código de status de resposta não irá conter conteúdo.

Excluir um estudo específico

Essa solicitação exclui um único estudo (e todas as séries e instâncias filho).

Detalhes:

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

Essa resposta exclui a instância do círculo azul (é o único elemento restante na série) do servidor. Se for bem-sucedido, o código de status de resposta não irá conter conteúdo.

Observação

DICOM® é a marca registrada da National Electrical Manufacturers Association para suas publicações de padrões relacionados às comunicações digitais de informações médicas.