Использование API C# и DICOMweb Standard
В этой статье показано, как работать со службой DICOMweb с помощью C# и примера .dcm файлов DICOM®.
Используйте следующие примеры файлов:
- blue-circle.dcm
- dicom-metadata.csv
- green-square.dcm
- red-triangle.dcm
Имя файла, studyUID, seriesUID и instanceUID примера файлов DICOM:
Файлы | 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 |
Примечание.
Каждый из этих файлов представляет один экземпляр и является частью одного исследования. Кроме того, зеленый квадрат и красный треугольник являются частью одной серии, в то время как синий круг находится в отдельной серии.
Необходимые компоненты
Чтобы использовать API DICOMweb Standard, вам потребуется экземпляр развернутой службы DICOM. Дополнительные сведения см. в статье "Развертывание службы DICOM с помощью портал Azure".
После развертывания экземпляра службы DICOM получите URL-адрес для службы приложений:
- Войдите на портал Azure.
- Выполните поиск последних ресурсов и выберите экземпляр службы DICOM.
- Скопируйте URL-адрес службы DICOM. Обязательно укажите версию в качестве части URL-адреса при выполнении запросов. Дополнительные сведения см. в разделе "Управление версиями API" для службы DICOM.
В приложении установите следующие пакеты NuGet:
Создание DicomWebClient
После развертывания службы DICOM создайте DicomWebClient. Запустите фрагмент кода, чтобы создать DicomWebClient, который используется для остальной части этого руководства. Убедитесь, что установлены оба пакета NuGet. Дополнительные сведения см. в статье "Получение маркера доступа для службы DICOM" с помощью Azure CLI.
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}”);
С помощью DicomWebClient теперь можно выполнять операции Хранилища, извлечения, поиска и удаления.
Хранение экземпляров DICOM (STOW)
С помощью DicomWebClient теперь можно хранить файлы DICOM.
Хранение одного экземпляра
В хранилище одного экземпляра показано, как отправить один файл DICOM.
Сведения:
- POST /studies
DicomFile dicomFile = await DicomFile.OpenAsync(@"{Path To blue-circle.dcm}");
DicomWebResponse response = await client.StoreAsync(new[] { dicomFile });
Хранение экземпляров для конкретного исследования
Экземпляры хранилища для определенного исследования демонстрируют, как передать файл DICOM в указанное исследование.
Сведения:
- 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");
Прежде чем перейти к следующей части руководства, отправьте green-square.dcm
файл с помощью любого из предыдущих методов.
Получение экземпляра DICOM (WADO)
Фрагменты кода показывают, как выполнять каждый из запросов извлечения с помощью созданного ранее DicomWebClient.
Переменные используются во всех остальных примерах.
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
Получение всех экземпляров в исследовании
Сведения:
- GET /studies/{study}
DicomWebResponse response = await client.RetrieveStudyAsync(studyInstanceUid);
Все три отправленных ранее файла dcm являются частью одного исследования, поэтому ответ должен возвращать все три экземпляра. Убедитесь, что ответ имеет код состояния "ОК" и возвращается ли все три экземпляра.
Использование извлеченных экземпляров
В следующем фрагменте кода показано, как получить доступ к извлеченным экземплярам. В нем также показано, как получить доступ к некоторым полям экземпляров и как сохранить его в виде 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");
}
Получение метаданных всех экземпляров в исследовании
Этот ответ извлекает метаданные для всех экземпляров в одном исследовании.
Сведения:
- GET /studies/{study}/метаданные
DicomWebResponse response = await client.RetrieveStudyMetadataAsync(studyInstanceUid);
Все три загруженных ранее файла dcm являются частью одного исследования, поэтому ответ должен возвращать метаданные для всех трех экземпляров. Убедитесь, что ответ имеет код состояния ОК и возвращается все метаданные.
Получение всех экземпляров в серии
Этот ответ извлекает все экземпляры в одной серии.
Сведения:
- GET /studies/{study}/series/{series}
DicomWebResponse response = await client.RetrieveSeriesAsync(studyInstanceUid, seriesInstanceUid);
В этой серии есть два экземпляра (зеленый квадрат и красный треугольник), поэтому ответ должен возвращать оба экземпляра. Убедитесь, что ответ имеет код состояния "ОК", а оба экземпляра возвращаются.
Получение метаданных всех экземпляров в серии
Этот ответ извлекает метаданные для всех экземпляров в одном исследовании.
Сведения:
- GET /studies/{study}/series/{series}/metadata
DicomWebResponse response = await client.RetrieveSeriesMetadataAsync(studyInstanceUid, seriesInstanceUid);
Ряд содержит два экземпляра (зеленый квадрат и красный треугольник), поэтому ответ должен возвращать метаданные для обоих экземпляров. Убедитесь, что ответ имеет код состояния ОК, и возвращаются оба экземпляра метаданных.
Получение одного экземпляра в серии исследования
Этот запрос извлекает один экземпляр.
Сведения:
- GET /studies/{study}/series{series}/instances/{instance}
DicomWebResponse response = await client.RetrieveInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
Ответ должен возвращать только красный треугольник экземпляра. Убедитесь, что ответ имеет код состояния "ОК" и возвращается ли экземпляр.
Получение метаданных одного экземпляра в серии исследований
Этот запрос извлекает метаданные для одного экземпляра в рамках одного исследования и ряда.
Сведения:
- GET /studies/{study}/series/{series}/instances/{instance}/metadata
DicomWebResponse response = await client.RetrieveInstanceMetadataAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
Ответ должен возвращать только метаданные для красного треугольника экземпляра. Убедитесь, что ответ имеет код состояния "ОК" и возвращается ли метаданные.
Получение одного или нескольких кадров из одного экземпляра
Этот запрос извлекает один или несколько кадров из одного экземпляра.
Сведения:
- GET /studies/{study}/series/{series}/instances/{instance}/frames/{frames}
DicomWebResponse response = await client.RetrieveFramesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, frames: new[] { 1 });
Ответ должен возвращать единственный кадр из красного треугольника. Убедитесь, что ответ имеет код состояния "ОК" и возвращается кадр.
Query DICOM (QIDO)
Поиск исследований
Этот запрос выполняет поиск одного или нескольких исследований по атрибутам DICOM.
Сведения:
- GET /studies? StudyInstanceUID={study}
string query = $"/studies?StudyInstanceUID={studyInstanceUid}";
DicomWebResponse response = await client.QueryStudyAsync(query);
Убедитесь, что ответ содержит одно исследование, и что код ответа ОК.
Поиск рядов
Этот запрос выполняет поиск одной или нескольких рядов по атрибутам DICOM.
Сведения:
- GET /series? SeriesInstanceUID={series}
string query = $"/series?SeriesInstanceUID={seriesInstanceUid}";
DicomWebResponse response = await client.QuerySeriesAsync(query);
Убедитесь, что ответ содержит одну серию и что код ответа ОК.
Поиск ряда в исследовании
Этот запрос выполняет поиск одной или нескольких рядов в рамках одного исследования атрибутами DICOM.
Сведения:
- GET /studies/{study}/series? SeriesInstanceUID={series}
string query = $"/studies/{studyInstanceUid}/series?SeriesInstanceUID={seriesInstanceUid}";
DicomWebResponse response = await client.QueryStudySeriesAsync(studyInstanceUid, query);
Убедитесь, что ответ содержит одну серию и что код ответа ОК.
Поиск экземпляров
Этот запрос выполняет поиск одного или нескольких экземпляров по атрибутам DICOM.
Сведения:
- GET /instances? SOPInstanceUID={instance}
string query = $"/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryInstancesAsync(query);
Убедитесь, что ответ содержит один экземпляр и что код ответа ОК.
Поиск экземпляров в исследовании
Этот запрос выполняет поиск одного или нескольких экземпляров в рамках одного исследования атрибутами DICOM.
Сведения:
- GET /studies/{study}/instances? SOPInstanceUID={instance}
string query = $"/studies/{studyInstanceUid}/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryStudyInstanceAsync(studyInstanceUid, query);
Убедитесь, что ответ содержит один экземпляр и что код ответа ОК.
Поиск экземпляров в рамках исследования и ряда
Этот запрос выполняет поиск одного или нескольких экземпляров в рамках одного исследования и одного ряда по атрибутам DICOM.
Сведения:
- GET /studies/{study}/series/{series}/instances? SOPInstanceUID={instance}
string query = $"/studies/{studyInstanceUid}/series/{seriesInstanceUid}/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryStudySeriesInstanceAsync(studyInstanceUid, seriesInstanceUid, query);
Убедитесь, что ответ содержит один экземпляр и что код ответа ОК.
Удаление DICOM
Примечание.
Удаление не является частью стандарта DICOM, но было добавлено для удобства.
Удаление конкретного экземпляра в рамках исследования и ряда
Этот запрос удаляет один экземпляр в рамках одного исследования и одной серии.
Сведения:
- 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);
Этот ответ удаляет экземпляр красного треугольника с сервера. Если это успешно, код состояния ответа не содержит содержимого.
Удаление определенной серии в исследовании
Этот запрос удаляет один ряд (и все дочерние экземпляры) в рамках одного исследования.
Сведения:
- DELETE /studies/{study}/series/{series}
DicomWebResponse response = await client.DeleteSeriesAsync(studyInstanceUid, seriesInstanceUid);
Ответ удаляет экземпляр зеленого квадрата с сервера (это единственный элемент, оставшийся в серии). Если это успешно, код состояния ответа не содержит содержимого.
Удаление конкретного исследования
Этот запрос удаляет одно исследование (и все дочерние ряды и экземпляры).
Сведения:
- DELETE /studies/{study}
DicomWebResponse response = await client.DeleteStudyAsync(studyInstanceUid);
Ответ удаляет экземпляр синего круга с сервера (это единственный элемент, оставшийся в серии). Если это успешно, код состояния ответа не содержит содержимого.
Примечание.
DICOM® является зарегистрированным товарным знаком Национальной ассоциации производителей электрических технологий для публикаций по стандартам, касающихся цифровых коммуникаций медицинской информации.