This tutorial uses C# to demonstrate working with the Medical Imaging Server for DICOM.
For the tutorial we will use the DICOM files here: Sample DICOM files. The file name, studyUID, seriesUID and instanceUID of the sample DICOM files is as follows:
File | 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 |
NOTE: Each of these files represent a single instance and are part of the same study. Also green-square and red-triangle are part of the same series, while blue-circle is in a separate series.
In order to use the DICOMWeb™ Standard APIs, you must have an instance of the Medical Imaging Server for DICOM deployed. If you have not already deployed the Medical Imaging Server, Deploy the Medical Imaging Server to Azure.
Once you have deployed an instance of the Medical Imaging Server for DICOM, retrieve the URL for your App Service:
- Sign into the Azure Portal.
- Search for App Services and select your Medical Imaging Server for DICOM App Service.
- Copy the URL of your App Service.
- Note the version of the REST API you would like to use. When creating the
DicomWebClient
below, we recommend to pass the version in to pin the client to a specific version. For more information on versioning visit the Api Versioning Documentation.
In your application install the following nuget packages:
After you have deployed your Medical Imaging Server for DICOM, you will create a 'DicomWebClient'. Run the following code snippet to create DicomWebClient
which we will be using for the rest of the tutorial. Ensure you have both nuget packages mentioned above installed.
string webServerUrl ="{Your DicomWeb Server URL}"
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(webServerUrl);
IDicomWebClient client = new DicomWebClient(httpClient, "v<version>");
With the DicomWebClient
we can now perform Store, Retrieve, Search, and Delete operations.
Using the DicomWebClient
that we have created, we can now store DICOM files.
This demonstrates how to upload a single DICOM file.
Details:
- POST /studies
DicomFile dicomFile = await DicomFile.OpenAsync(@"{Path To blue-circle.dcm}");
DicomWebResponse response = await client.StoreAsync(new[] { dicomFile });
This demonstrates how to upload a DICOM file into a specified study.
Details:
- 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");
Before moving on to the next part also upload the green-square.dcm file using either of the methods above.
The following code snippets will demonstrate how to perform each of the retrieve queries using the DicomWebClient
created earlier.
The following variables will be used throghout the rest of the examples:
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
This retrieves all instances within a single study.
Details:
- GET /studies/{study}
DicomWebResponse response = await client.RetrieveStudyAsync(studyInstanceUid);
All three of the dcm files that we uploaded previously are part of the same study so the response should return all 3 instances. Validate that the response has a status code of OK and that all three instances are returned.
The following code snippet shows how to access the instances that are retrieved, how to access some of the fields of the instances, and how to save it as a .dcm file.
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");
}
This request retrieves the metadata for all instances within a single study.
Details:
- GET /studies/{study}/metadata
DicomWebResponse response = await client.RetrieveStudyMetadataAsync(studyInstanceUid);
All three of the dcm files that we uploaded previously are part of the same study so the response should return the metadata for all 3 instances. Validate that the response has a status code of OK and that all the metadata is returned.
This request retrieves all instances within a single series.
Details:
- GET /studies/{study}/series/{series}
DicomWebResponse response = await client.RetrieveSeriesAsync(studyInstanceUid, seriesInstanceUid);
This series has 2 instances (green-square and red-triangle), so the response should return both instances. Validate that the response has a status code of OK and that both instances are returned.
This request retrieves the metadata for all instances within a single study.
Details:
- GET /studies/{study}/series/{series}/metadata
DicomWebResponse response = await client.RetrieveSeriesMetadataAsync(studyInstanceUid, seriesInstanceUid);
This series has 2 instances (green-square and red-triangle), so the response should return metatdata for both instances. Validate that the response has a status code of OK and that both instances metadata are returned.
This request retrieves a single instances.
Details:
- GET /studies/{study}/series{series}/instances/{instance}
DicomWebResponse response = await client.RetrieveInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
This should only return the instance red-triangle. Validate that the response has a status code of OK and that the instance is returned.
This request retrieves the metadata for a single instances within a single study and series.
Details:
- GET /studies/{study}/series/{series}/instances/{instance}/metadata
DicomWebResponse response = await client.RetrieveInstanceMetadataAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
This should only return the metatdata for the instance red-triangle. Validate that the response has a status code of OK and that the metadata is returned.
This request retrieves one or more frames from a single instance.
Details:
- GET /studies/{study}/series/{series}/instances/{instance}/frames/{frames}
DicomWebResponse response = await client.RetrieveFramesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, frames: new[] { 1 });
This should return the only frame from the red-triangle. Validate that the response has a status code of OK and that the frame is returned.
NOTE: Please see the Conformance Statement file for supported DICOM attributes.
This request searches for one or more studies by DICOM attributes.
Details:
- GET /studies?StudyInstanceUID={study}
string query = $"/studies?StudyInstanceUID={studyInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);
Validate that response includes 1 study and that response code is OK.
This request searches for one or more series by DICOM attributes.
Details:
- GET /series?SeriesInstanceUID={series}
string query = $"/series?SeriesInstanceUID={seriesInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);
Validate that response includes 1 series and that response code is OK.
This request searches for one or more series within a single study by DICOM attributes.
Details:
- GET /studies/{study}/series?SeriesInstanceUID={series}
string query = $"/studies/{studyInstanceUid}/series?SeriesInstanceUID={seriesInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);
Validate that response includes 1 series and that response code is OK.
This request searches for one or more instances by DICOM attributes.
Details:
- GET /instances?SOPInstanceUID={instance}
string query = $"/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);
Validate that response includes 1 instance and that response code is OK.
This request searches for one or more instances within a single study by DICOM attributes.
Details:
- GET /studies/{study}/instances?SOPInstanceUID={instance}
string query = $"/studies/{studyInstanceUid}/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);
Validate that response includes 1 instance and that response code is OK.
This request searches for one or more instances within a single study and single series by DICOM attributes.
Details:
- GET /studies/{study}/series/{series}instances?SOPInstanceUID={instance}
string query = $"/studies/{studyInstanceUid}/series/{seriesInstanceUid}/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryAsync(query);
Validate that response includes 1 instance and that response code is OK.
NOTE: Delete is not part of the DICOM standard, but has been added for convenience.
This request deletes a single instance within a single study and single series.
Details:
- 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);
This deletes the red-triangle instance from the server. If it is successful the response status code contains no content.
This request deletes a single series (and all child instances) within a single study.
Details:
- DELETE /studies/{study}/series/{series}
DicomWebResponse response = await client.DeleteSeriesAsync(studyInstanceUid, seriesInstanceUid);
This deletes the green-square instance (it is the only element left in the series) from the server. If it is successful the response status code contains no content.
This request deletes a single study (and all child series and instances).
Details:
- DELETE /studies/{study}
DicomWebResponse response = await client.DeleteStudyAsync(studyInstanceUid);
This deletes the blue-circle instance (it is the only element left in the series) from the server. If it is successful the response status code contains no content.