C# と DICOMweb Standard API を使う
この記事では、C# とサンプルの .dcm DICOM® ファイルを使って DICOMweb サービスを操作する方法について説明します。
次のサンプル ファイルを使います。
- blue-circle.dcm
- dicom-metadata.csv
- green-square.dcm
- red-triangle.dcm
サンプル DICOM ファイルのファイル名、studyUID、seriesUID、および instanceUID は次のとおりです。
ファイル | 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
これらの各ファイルは 1 つのインスタンスを表し、同じ検査の一部です。 また、green-square と red-triangle は同じシリーズの一部であり、blue-circle は別のシリーズに含まれます。
前提条件
DICOMweb Standard API を使うには、DICOM サービスのインスタンスをデプロイしておく必要があります。 詳細については、Azure portal を使用した DICOM サービスのデプロイに関する記事を参照してください。
DICOM サービスのインスタンスをデプロイした後、アプリ サービスの URL を取得します。
- Azure portal にサインインします。
- [最近のリソース] を検索し、DICOM サービス インスタンスを選択します。
- DICOM サービスのサービス URL をコピーします。 要求を行う際は、URL の一部としてバージョンを必ず指定してください。 詳細については、「DICOM サービスの API バージョン管理」を参照してください。
アプリケーションで、次の NuGet パッケージをインストールします。
DicomWebClient を作成する
DICOM サービスをデプロイしたら、DicomWebClient を作成します。 このコード スニペットを実行して DicomWebClient を作成します。これは、このチュートリアルの残りの部分で使います。 両方の NuGet パッケージがインストールされていることを確認します。 詳細については、Azure CLI を使用して、DICOM サービスのアクセス トークンを取得する方法に関する記事を参照してください。
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 ファイルを保存できるようになりました。
1 つのインスタンスを保存する
「1 つのインスタンスを保存する」では、1 つの 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);
前にアップロードした 3 つの dcm ファイルはすべて同じ検査の一部であるため、応答は 3 つのインスタンスをすべて返すはずです。 応答の状態コードが OK であり、3 つのインスタンスがすべて返されることを検証します。
取得したインスタンスを使う
次のコード スニペットは、取得されたインスタンスにアクセスする方法を示しています。 また、インスタンスの一部のフィールドにアクセスする方法と、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");
}
検査に含まれるすべてのインスタンスのメタデータを取得する
この応答では、1 つの検査に含まれるすべてのインスタンスのメタデータを取得します。
詳細:
- GET /studies/{study}/metadata
DicomWebResponse response = await client.RetrieveStudyMetadataAsync(studyInstanceUid);
前にアップロードした 3 つの dcm ファイルはすべて同じ検査の一部であるため、応答は 3 つのインスタンスすべてのメタデータを返すはずです。 応答の状態コードが OK であり、すべてのメタデータが返されることを検証します。
シリーズ内のすべてのインスタンスを取得する
この応答は、1 つのシリーズ内のすべてのインスタンスを取得します。
詳細:
- GET /studies/{study}/series/{series}
DicomWebResponse response = await client.RetrieveSeriesAsync(studyInstanceUid, seriesInstanceUid);
このシリーズには 2 つのインスタンス (緑の四角形と赤い三角形) があるため、応答は両方のインスタンスを返すはずです。 応答の状態コードが OK であり、両方のインスタンスが返されることを検証します。
シリーズに含まれるすべてのインスタンスのメタデータを取得する
この応答では、1 つの検査に含まれるすべてのインスタンスのメタデータを取得します。
詳細:
- GET /studies/{study}/series/{series}/metadata
DicomWebResponse response = await client.RetrieveSeriesMetadataAsync(studyInstanceUid, seriesInstanceUid);
このシリーズには 2 つのインスタンス (green-square と red-triangle) があるため、応答では両方のインスタンスのメタデータが返されるはずです。 応答の状態コードが OK であり、メタデータの両方のインスタンスが返されることを検証します。
検査のシリーズに含まれる 1 つのインスタンスを取得する
この要求は 1 つのインスタンスを取得します。
詳細:
- GET /studies/{study}/series{series}/instances/{instance}
DicomWebResponse response = await client.RetrieveInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
この応答では、インスタンス red-triangle のみが返されるはずです。 応答の状態コードが OK であり、そのインスタンスが返されることを検証します。
検査のシリーズ内の 1 つのインスタンスのメタデータを取得する
この要求は、1 つの検査とシリーズに含まれる 1 つのインスタンスのメタデータを取得します。
詳細:
- GET /studies/{study}/series/{series}/instances/{instance}/metadata
DicomWebResponse response = await client.RetrieveInstanceMetadataAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
この応答では、インスタンス red-triangle のメタデータのみが返されるはずです。 応答の状態コードが OK であり、そのメタデータが返されることを検証します。
1 つのインスタンスから 1 つ以上のフレームを取得する
この要求は、1 つのインスタンスから 1 つ以上のフレームを取得します。
詳細:
- GET /studies/{study}/series/{series}/instances/{instance}/frames/{frames}
DicomWebResponse response = await client.RetrieveFramesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, frames: new[] { 1 });
この応答では、red-triangle からのフレームのみが返されるはずです。 応答の状態コードが OK であり、そのフレームが返されることを検証します。
クエリ DICOM (QIDO)
Note
サポートされている DICOM 属性については、DICOM 適合性宣言書のページを参照してください。
検査を検索する
この要求は、DICOM 属性によって 1 つ以上の検査を検索します。
詳細:
- GET /studies?StudyInstanceUID={study}
string query = $"/studies?StudyInstanceUID={studyInstanceUid}";
DicomWebResponse response = await client.QueryStudyAsync(query);
応答に 1 つの検査が含まれていることと、応答コードが OK であることを検証してください。
シリーズを検索する
この要求は、DICOM 属性によって 1 つ以上のシリーズを検索します。
詳細:
- GET /series?SeriesInstanceUID={series}
string query = $"/series?SeriesInstanceUID={seriesInstanceUid}";
DicomWebResponse response = await client.QuerySeriesAsync(query);
応答に 1 つのシリーズが含まれていることと、応答コードが OK であることを検証してください。
1 つの検査内のシリーズを検索する
この要求は、DICOM 属性によって 1 つの検査内の 1 つ以上のシリーズを検索します。
詳細:
- GET /studies/{study}/series?SeriesInstanceUID={series}
string query = $"/studies/{studyInstanceUid}/series?SeriesInstanceUID={seriesInstanceUid}";
DicomWebResponse response = await client.QueryStudySeriesAsync(studyInstanceUid, query);
応答に 1 つのシリーズが含まれていることと、応答コードが OK であることを検証してください。
インスタンスを検索する
この要求は、DICOM 属性によって 1 つ以上のインスタンスを検索します。
詳細:
- GET /instances?SOPInstanceUID={instance}
string query = $"/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryInstancesAsync(query);
応答に 1 つのインスタンスが含まれていることと、応答コードが OK であることを検証してください。
1 つの検査内のインスタンスを検索する
この要求は、DICOM 属性によって 1 つの検査内の 1 つ以上のインスタンスを検索します。
詳細:
- GET /studies/{study}/instances?SOPInstanceUID={instance}
string query = $"/studies/{studyInstanceUid}/instances?SOPInstanceUID={sopInstanceUid}";
DicomWebResponse response = await client.QueryStudyInstanceAsync(studyInstanceUid, query);
応答に 1 つのインスタンスが含まれていることと、応答コードが OK であることを検証してください。
1 つの検査とシリーズ内のインスタンスを検索する
この要求は、DICOM 属性によって 1 つの検査および 1 つのシリーズ内の 1 つ以上のインスタンスを検索します。
詳細:
- 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);
応答に 1 つのインスタンスが含まれていることと、応答コードが OK であることを検証してください。
DICOM を削除する
Note
削除は DICOM 標準の一部ではありませんが、便宜上追加されています。
検査およびシリーズ内の特定のインスタンスを削除する
この要求は、1 つの検査および 1 つのシリーズ内の 1 つのインスタンスを削除します。
詳細:
- 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);
この応答によって red-triangle インスタンスがサーバーから削除されます。 成功した場合、応答状態コードにはコンテンツが含まれません。
1 つの検査内の特定のシリーズを削除する
この要求は、1 つの検査内の 1 つのシリーズ (およびすべての子インスタンス) を削除します。
詳細:
- DELETE /studies/{study}/series/{series}
DicomWebResponse response = await client.DeleteSeriesAsync(studyInstanceUid, seriesInstanceUid);
この応答によって green-square インスタンスがサーバーから削除されます (シリーズ内に残っていた唯一の要素です)。 成功した場合、応答状態コードには何も含まれなくなります。
特定の検査を削除する
この要求は、1 つの検査 (およびすべての子シリーズとインスタンス) を削除します。
詳細:
- DELETE /studies/{study}
DicomWebResponse response = await client.DeleteStudyAsync(studyInstanceUid);
この応答によって blue-circle インスタンスがサーバーから削除されます (シリーズ内に残っていた唯一の要素です)。 成功した場合、応答状態コードには何も含まれなくなります。
Note
DICOM® は、医療情報のデジタル通信に関する標準出版物に関する米国電機工業会 (National Electrical Manufacturers Association) の登録商標です。