Usar APIs padrão C# e DICOMweb

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

Use estes arquivos de exemplo:

  • azul-círculo.dcm
  • dicom-metadados.csv
  • verde-quadrado.dcm
  • vermelho-triângulo.dcm

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

Ficheiro EstudoUID SérieUID InstânciaUID
verde-quadrado.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
vermelho-triângulo.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
azul-círculo.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 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. Inicie sessão no portal do Azure.
  2. Pesquise recursos recentes e selecione sua instância de serviço DICOM.
  3. Copie a URL do serviço DICOM. Certifique-se de especificar a versão como parte da url ao fazer solicitações. Para obter mais informações, consulte Controle de versão de 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 trecho de código para criar DicomWebClient, que você usa para o resto deste tutorial. Certifique-se de ter ambos os pacotes NuGet instalados. Para obter mais informações, consulte Obter 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.

Armazenar instância única

Armazenar instância única demonstra como carregar um único arquivo DICOM.

Detalhes:

  • POST /estudos
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

Armazenar instâncias para um estudo específico demonstrar como carregar um arquivo DICOM em um estudo especificado.

Detalhes:

  • POST /estudos/{estudo}
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 green-square.dcm arquivo usando um dos métodos anteriores.

Recuperar instância DICOM (WADO)

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

As variáveis são usadas ao longo do resto dos 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 dentro de um estudo

Detalhes:

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

Todos os três arquivos dcm que você carregou 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 OK e se todas as três instâncias são retornadas.

Use as instâncias recuperadas

O trecho 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 em 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 dcm 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 dentro de uma série

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

Detalhes:

  • GET /estudos/{estudo}/série/{série}
DicomWebResponse response = await client.RetrieveSeriesAsync(studyInstanceUid, seriesInstanceUid);

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

Recuperar uma única instância dentro de 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 OK e se a instância é retornada.

Recuperar metadados de uma única instância dentro de 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 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 OK e se o quadro é retornado.

Consulta DICOM (QIDO)

Nota

Consulte a Declaração de Conformidade DICOM para obter os atributos DICOM suportados.

Pesquisa de estudos

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

Detalhes:

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

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

Pesquisa de séries

Esta solicitação procura uma ou mais séries por atributos DICOM.

Detalhes:

  • GET /série? SeriesInstanceUID={série}
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.

Pesquisa de séries dentro de um estudo

Esta solicitação procura uma ou mais séries dentro de um único estudo por atributos DICOM.

Detalhes:

  • GET /studies/{study}/series? SeriesInstanceUID={série}
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

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

Detalhes:

  • GET /instances? SOPInstanceUID={instância}
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 dentro de um estudo

Esta solicitação procura uma ou mais instâncias dentro de um único estudo por atributos DICOM.

Detalhes:

  • GET /studies/{study}/instances? SOPInstanceUID={instância}
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 dentro de um estudo e série

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

Detalhes:

  • GET /studies/{study}/series/{series}instances? SOPInstanceUID={instância}
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

Nota

Delete não faz parte do padrão DICOM, mas foi adicionado por conveniência.

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

Esta solicitação exclui uma única instância dentro de 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 repouso exclui a instância do triângulo vermelho do servidor. Se for bem-sucedido, o código de status da resposta não conterá conteúdo.

Excluir uma série específica dentro de um estudo

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

Detalhes:

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

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

Eliminar um estudo específico

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

Detalhes:

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

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

Nota

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