Main Content

単一ファイルおよび複数ファイルの DICOM シリーズを含むイメージ データストアの作成

データストアは、特に深層学習ワークフローにおいて、大きすぎて一度にメモリに収まらないデータの集合を処理および表現する便利な方法です。DICOM (Digital Imaging and Communications in Medicine) は標準化された医用画像ファイル形式で、ボリュームや画像シリーズを単一ファイルまたは複数ファイルとしてフォルダーに保存できます。この例では、単一ファイルと複数ファイルの混合として保存された DICOM データを格納するイメージ データストアを作成する方法を示します。

Medical Imaging Toolbox™ は、このワークフローを簡素化するオブジェクトと関数を提供します。開始するには、Create Training Data for 3-D Medical Image Semantic Segmentation (Medical Imaging Toolbox)を参照してください。

データのダウンロード

MathWorks® の Web サイトからファイル MedicalVolumeDICOMData.zip をダウンロードし、この例の現在のディレクトリに解凍します。このファイルには、DICOM ファイル形式で保存された 3 つの胸部 CT ボリュームが格納されており、各ボリュームは複数のファイルから成るディレクトリとして保存されています。

zipFile = matlab.internal.examples.downloadSupportFile("medical","MedicalVolumeDICOMData.zip");
unzip(zipFile,pwd)

DICOM 情報の収集

DICOM ファイル形式において、"シリーズ" は 1 つの MRI ボリュームや CT ボリュームなどの 1 回のスキャンに対応します。関数dicomCollectionは、フォルダー内のすべての DICOM ファイルのメタデータを解析し、各行が 1 つのシリーズを表す table を返します。複数ファイルの DICOM ボリュームの場合、関数はファイルを単一のシリーズに集約します。

この例の現在のディレクトリにある DICOM シリーズの詳細を収集します。これには、単一の DICOM ファイルとして保存されている複数のファイルの胸部 CT ボリュームとマルチフレームの超音波シリーズが含まれます。

dicomDir = pwd;
collection = dicomCollection(dicomDir,IncludeSubfolders=true)
collection=4×14 table
             StudyDateTime             SeriesDateTime         PatientName     PatientSex    Modality    Rows    Columns    Channels    Frames          StudyDescription          SeriesDescription                            StudyInstanceUID                                                    SeriesInstanceUID                                       Filenames           
          ____________________    ________________________    ____________    __________    ________    ____    _______    ________    ______    ____________________________    _________________    ________________________________________________________________    __________________________________________________________________    ______________________________

    s1    14-Dec-2018 08:10:05    {[14-Dec-2018 08:14:20]}    ""                 "M"          "CT"      512       512         1         176      "CT CARDIAC CALCIUM SCORING"    "LUNG 30%"           "1.3.6.1.4.1.9590.100.1.2.1168571428410023523212533210897210257"    "1.3.6.1.4.1.9590.100.1.2.238036032333239687321629621091791352864"    {176×1 string                }
    s2    14-Dec-2018 08:10:05    {[14-Dec-2018 08:14:20]}    ""                 "M"          "CT"      512       512         1          88      "CT CARDIAC CALCIUM SCORING"    "LUNG 2.5 30%"       "1.3.6.1.4.1.9590.100.1.2.1168571428410023523212533210897210257"    "1.3.6.1.4.1.9590.100.1.2.270370554009590424527057468890139369500"    { 88×1 string                }
    s3    14-Dec-2018 08:10:05    {[14-Dec-2018 08:14:20]}    ""                 "M"          "CT"      512       512         1          88      "CT CARDIAC CALCIUM SCORING"    "STANDARD 30%"       "1.3.6.1.4.1.9590.100.1.2.1168571428410023523212533210897210257"    "1.3.6.1.4.1.9590.100.1.2.322859592438691631224656102213691253752"    { 88×1 string                }
    s4    30-Jan-1994 11:25:01    {0×0 double            }    "Anonymized"       ""           "US"      430       600         1          10      "Echocardiogram"                "PS LAX MR & AI"     "999.999.3859744"                                                   "999.999.94827453"                                                    {["C:\US-PAL-8-10x-echo.dcm"]}

処理された DICOM ボリュームを格納する一時ディレクトリを作成します。

matFileDir = fullfile(pwd,"MATFiles");
if ~exist(matFileDir,"dir")
    mkdir(matFileDir)
end

DICOM ボリュームから MAT ファイルへの変換

dicomCollection table 内のすべてのイメージ ボリュームを検索し、各ボリュームを MAT ファイルとして保存します。

まず、コレクション内の各シリーズをループ処理します。

for idx = 1:size(collection,1)

現在のシリーズについて、table から DICOM ファイル名を抽出します。シリーズに複数ファイルの DICOM ボリュームが含まれている場合、ファイル名は string 配列としてリストされています。

    dicomFileName = collection.Filenames{idx};

DICOM ファイル名を調整して、新しい MAT ファイル用に単一のファイル名を指定します。

    if length(dicomFileName) > 1
        matFileName = fileparts(dicomFileName(1));
        matFileName = split(matFileName,filesep);
        matFileName = replace(strtrim(matFileName(end))," ","_");
    else
        [~,matFileName] = fileparts(dicomFileName);
    end
    matFileName = fullfile(matFileDir,matFileName);

現在のシリーズのイメージ データを読み取ります。複数ファイルおよび単一ファイルの DICOM ボリュームを処理するさまざまな読み取り関数を試します。

1) 関数dicomreadVolumeを使用して、データの読み取りを試します。

  • データが複数ファイルのボリュームの場合、dicomreadVolume は正常に実行され、単一の 4 次元配列で完全なボリュームを返します。4 つの次元は [<行>,<列>,<サンプル>,<スライス>] に対応します。ここで、サンプルはボクセルあたりのチャネル数です。このデータをデータストアに追加して、手順 2 をスキップすることができます。

  • データが単一のファイルに含まれる場合、dicomreadVolume は正常に実行されません。手順 2 に進みます。

2) 関数dicomreadを使用して、データの読み取りを試します。

  • データが完全なボリュームの場合、dicomread は 4 次元配列を返します。このデータはデータストアに追加できます。

  • データが単一の 2 次元イメージの場合、dicomread は 2 次元行列または 3 次元配列を返します。このシリーズをスキップし、コレクションの次のシリーズに進みます。

    try
        data = dicomreadVolume(collection,collection.Row{idx});
    catch ME
        data = dicomread(dicomFileName);
        if ndims(data)<4
            % Skip files that are not volumes
            continue;
        end
    end

現在のシリーズがボリュームの場合、データおよび対応する DICOM ファイル名を MAT ファイルに書き込みます。

    save(matFileName,"data","dicomFileName");

コレクションのスタディのループ処理を終了します。

end

イメージ データストアの作成

DICOM ボリューム データを含む MAT ファイルから imageDatastore を作成します。この例の最後で定義されている補助関数 matRead として ReadFcn プロパティを指定します。

imdsdicom = imageDatastore(matFileDir,FileExtensions=".mat", ...
    ReadFcn=@matRead);

結果の視覚的チェック

イメージ データストアから最初の DICOM ボリュームを読み取ります。

[V,Vinfo] = read(imdsdicom);
[~,VFileName] = fileparts(Vinfo.Filename);

関数 squeeze を使用して大きさが 1 のチャネル次元を削除してから、関数 volshow を使用してボリュームを表示します。

V = squeeze(V);
volshow(V);

サポート関数

関数 matRead は、ファイル名 filename の MAT ファイルの最初の変数からデータを読み込みます。

function data = matRead(filename)
    inp = load(filename);
    f = fields(inp);
    data = inp.(f{1});
end

参考

| | | | |

関連するトピック