Main Content

DICOM データ用のカスタム データストアの開発

この例では、書き込み操作をサポートするカスタム データストアの開発方法を説明します。このデータストアは、医療画像処理情報の国際規格である DICOM ® (Digital Imaging and Communications in Medicine) のデータをサポートしているため、DICOMDatastore という名前が付けられています。

カスタム データストアの開発

トピックカスタム データストアの開発では、カスタム データストアを作成するための一般的な手順と、各種機能を追加するための個別の要件について説明しています。必要な機能 (並列評価、書き込み操作、シャッフリングなど) に応じて、さまざまなスーパークラスからのサブクラス化が可能です。特に、matlab.io.datastore.FileWritable からのサブクラス化により、書き込み操作のサポートを追加できます。ただし、書き込み機能を最も幅広くサポートするには、matlab.io.datastore.FoldersPropertyProvider からもサブクラス化しなければなりません。これにより、データストアに Folders プロパティが追加されます。書き込みサポートをカスタム データストアに追加するためのすべての要件はデータ書き込みのサポートの追加で説明しています。

クラス定義

次の表に、DICOMDatastore クラスのコードとその説明を示します。

classdef DICOMDatastore < matlab.io.Datastore & ...
                          matlab.io.datastore.FileWritable & ...
                          matlab.io.datastore.FoldersPropertyProvider 
                          

クラスのヘッダー

DICOMDatastore は基本的な機能を Datastore から継承し、また FileWritable および FoldersPropertyProvider からの継承によりファイル書き込み機能を有効にします。

    properties
        Files matlab.io.datastore.FileSet
    end

パブリック プロパティ

DICOMDatastore は、FileSet オブジェクトであるパブリック プロパティ Files を定義します。DICOMDatastoreFolders プロパティを FoldersPropertyProvider から継承するため、このプロパティを初期化する必要はありません。

    properties (Constant)
        SupportedOutputFormats = ...
          [matlab.io.datastore.ImageDatastore.SupportedOutputFormats, "dcm"];
        DefaultOutputFormat = "dcm";
    end

DICOMDatastore は、SupportedOutputFormatsDefaultOutputFormat を、既定値をもつ定数プロパティとして定義します。"dcm" は DICOM データのカスタム形式です。

    methods(Access = public)
        function myds = DICOMDatastore(location)
            % The class constructor to set properties of the datastore. 
            myds.Files = matlab.io.datastore.FileSet(location, ...
                "IncludeSubfolders", true);
            populateFoldersFromLocation(myds,location);
            reset(myds);
        end

パブリック メソッド

パブリック メソッド セクションでは、クラスがデータ操作に使用する一般的なデータストア メソッドを定義します。パブリック メソッドは外部からアクセス可能なため、DICOMDatastore のクラス ユーザーはこれらのメソッドを (スーパークラスから継承した他のパブリック メソッドに加えて) 呼び出すことができます。

コンストラクター DICOMDatastore は、Files プロパティおよび Folders プロパティの値を設定することにより、新しい DICOMDatastore オブジェクトを作成します。

  • FileSet を使用して Files プロパティの値を設定します。

  • FoldersPropertyProviderpopulateFoldersFromLocation メソッドを使用して、Folders プロパティの値を設定します。

        function tf = hasdata(myds)
            %HASDATA   Returns true if more data is available.
            %   Return logical scalar indicating availability of data.
            %   This method should be called before calling read. This
            %   is an abstract method and must be implemented by the
            %   subclasses. hasdata is used in conjunction with read to
            %   read all the data within the datastore.
            tf = hasNextFile(myds.Files);
        end

hasdatareadresetprogress の各メソッドは、データストアが一度に小さなデータのチャンクを複数処理するようにインフラストラクチャを定義します。これらはサブクラスによって実装しなければならない抽象メソッドです。

        function [data, info] = read(myds)
            %READ   Read data and information about the extracted data.
            %   Return the data extracted from the datastore in the
            %   appropriate form for this datastore. Also return
            %   information about where the data was extracted from in
            %   the datastore. Both the outputs are required to be
            %   returned from the read method and can be of any type.
            %   info is recommended to be a struct with information
            %   about the chunk of data read. data represents the
            %   underlying class of tall, if tall is created on top of
            %   this datastore. This is an abstract method and must be
            %   implemented by the subclasses.
            
            % In this example, the read method reads data from the
            % datastore using a custom reader function, MyFileReader,
            % which takes the resolved filenames as input.
            if ~hasdata(myds)
                error("No more data to read.\nUse reset method to " ...
                    + "reset the datastore to the start of the data. Before " ...
                    + "calling the read method, check if data is available " ...
                    + "to read by using the hasdata method.");
            end

            file = nextfile(myds.Files);
            try
                data = dicomread(file.Filename);
            catch ME
                error("%s has failed", file.FileName);
            end

            info.FileSize = size(data);
            info.Filename = file.Filename;
        end
        function reset(myds)
            %RESET   Reset to the start of the data.
            %   Reset the datastore to the state where no data has been
            %   read from it. This is an abstract method and must be
            %   implemented by the subclasses.
            
            % In this example, the datastore is reset to point to the
            % first file (and first partition) in the datastore.
            reset(myds.Files);
        end
        function frac = progress(myds)
            %PROGRESS   Percentage of consumed data between 0.0 and 1.0.
            %   Return fraction between 0.0 and 1.0 indicating progress as a
            %   double. The provided example implementation returns the
            %   ratio of the index of the current file from FileSet
            %   to the number of files in FileSet. A simpler
            %   implementation can be used here that returns a 1.0 when all
            %   the data has been read from the datastore, and 0.0
            %   otherwise.
            %
            %   See also matlab.io.Datastore, read, hasdata, reset, readall,
            %   preview.
            frac = progress(myds.Files);
        end
    end
methods(Access = protected)
        function dsCopy = copyElement(myds)
            %COPYELEMENT   Create a deep copy of the datastore
            %   Create a deep copy of the datastore. We need to call
            %   copy on the datastore's property FileSet because it is
            %   a handle object. Creating a deep copy allows methods
            %   such as readall and preview, which call the copy method,
            %   to remain stateless.
            dsCopy = copyElement@matlab.mixin.Copyable(myds);
            dsCopy.Files = copy(myds.Files);
        end

保護されたメソッド

保護されたメソッドは、クラスにより継承されたメソッドを再定義します。これらのメソッドには DICOMDatastore のみがアクセスできます。詳細については、継承メソッドの変更を参照してください。

FileSet を使用してプロパティを定義する場合は常に、保護された copyElement メソッドが必要です。copyElement メソッドを使用すると、readallpreview などのメソッドの状態をないままにしておくことができます。

        function tf = write(myds, data, writeInfo, outFmt, varargin)
            if outFmt == "dcm"
                dicomwrite(data, writeInfo.SuggestedOutputName, varargin{:});
            else
                write@matlab.io.datastore.FileWritable(myds, data, ...
                    writeInfo, outFmt, varargin{:});
            end
            tf = true;
        end

保護された write メソッドは、データのチャンクを書き出します。DICOMDatastoreImageDatastore 形式とカスタム形式 "dcm" をサポートしているため、write メソッドは出力形式に応じて異なる関数を使用してデータを書き込みます。

        function files = getFiles(myds)
            files = myds.Files.FileInfo.Filename;
        end
    end

DICOMDatastoreFiles プロパティに FileSet オブジェクトを使用するため、保護された getFiles メソッドが必要です。Files プロパティは通常 cellstr を返す必要があるため、getFiles メソッドは FileSet オブジェクトを使用してファイル パスの cellstr を生成します。

end

classdef セクションを終了します。

 クラス コードの拡張

DICOMDatastore クラスの使用

DICOMDatastore クラスを実装した後、コンストラクターを使用して、DICOM ファイルのセットの場所を参照する新しい DICOMDatastore オブジェクトを作成します。たとえば、DICOM ファイルが C:\Data\DICOM\series-000001\ フォルダーにある場合、次のようになります。

ds = DICOMDatastore("C:\Data\DICOM\series-000001")
ds = 

  DICOMDatastore with properties:

                     Files: [1×1 matlab.io.datastore.FileSet]
    SupportedOutputFormats: ["png"    "jpg"    "jpeg"    "tif"    "tiff"    "dcm"]
       DefaultOutputFormat: "dcm"
                   Folders: {'C:\Data\DICOM\series-000001'}

DICOMDatastore のクラス ユーザーはこれらのパブリック メソッドにアクセスできます。

methods(ds)
Methods for class DICOMDatastore:

DICOMDatastore   copy      isPartitionable  preview    read     reset      writeall         
combine          hasdata   isShuffleable    progress   readall  transform        

Methods of DICOMDatastore inherited from handle.

特に、writeall がサポートされているため、ファイルを新しい場所に書き込むことができます。

writeall(ds,"C:\Data2\DICOM\")
このコマンドにより、データストア ファイルのコピーがフォルダー C:\Data2\DICOM\series-000001 に作成されます。

MATLAB® でのクラスの作成に関する一般的な情報については、クラス参照してください。

参考

| |

関連するトピック