13

C#でDICOMファイルを読みたいのですが。特別なことは何もしたくありません。今のところ、要素を読み取る方法を知りたいのですが、最初に、ヘッダーを読み取って有効なDICOMファイルであるかどうかを確認する方法を知りたいと思います。

バイナリデータ要素で構成されています。最初の128バイトは未使用(ゼロに設定)で、その後に文字列「DICM」が続きます。この後に、グループに編成されたヘッダー情報が続きます。

サンプルDICOMヘッダー

最初の128バイト:未使用のDICOM形式。
続いて文字「D」、「I」、「C」、「M」
次のような追加のヘッダー情報が続きます。

0002,0000、ファイルメタ要素グループ長さ:132
0002,0001、ファイルメタ情報バージョン:256
0002,0010、転送構文UID:1.2.840.10008.1.2.1。
0008,0000、グループの長さの識別:152
0008,0060、モダリティ:MR
0008,0070、メーカー:MRIcro

上記の例では、ヘッダーはグループに編成されています。グループ0002hexは、3つの要素を含むファイルメタ情報グループです。1つはグループの長さを定義し、もう1つはファイルのバージョンを格納し、それらは転送構文を格納します。

質問

  • 128バイトのプリアンブルの後に「D」、「I」、「C」、「M」の文字をチェックして、ヘッダーファイルを読み取り、それがDICOMファイルであるかどうかを確認するにはどうすればよいですか?
  • データの他の部分を読み取ってファイルを解析し続けるにはどうすればよいですか?
4

4 に答える 4

12

このようなものはファイルを読み取る必要があり、その基本的なものであり、すべてのケースを処理するわけではありませんが、それが出発点になります。


public void ReadFile(string filename)
{
    using (FileStream fs = File.OpenRead(filename))
    {
        fs.Seek(128, SeekOrigin.Begin);
        if ((fs.ReadByte() != (byte)'D' ||
             fs.ReadByte() != (byte)'I' ||
             fs.ReadByte() != (byte)'C' ||
             fs.ReadByte() != (byte)'M'))
        {
            Console.WriteLine("Not a DCM");
            return;
        }
        BinaryReader reader = new BinaryReader(fs);

        ushort g;
        ushort e;
        do
        {
            g = reader.ReadUInt16();
            e = reader.ReadUInt16();

            string vr = new string(reader.ReadChars(2));
            long length;
            if (vr.Equals("AE") || vr.Equals("AS") || vr.Equals("AT")
                || vr.Equals("CS") || vr.Equals("DA") || vr.Equals("DS")
                || vr.Equals("DT") || vr.Equals("FL") || vr.Equals("FD")
                || vr.Equals("IS") || vr.Equals("LO") || vr.Equals("PN")
                || vr.Equals("SH") || vr.Equals("SL") || vr.Equals("SS")
                || vr.Equals("ST") || vr.Equals("TM") || vr.Equals("UI")
                || vr.Equals("UL") || vr.Equals("US"))
               length = reader.ReadUInt16();
            else
            {
                // Read the reserved byte
                reader.ReadUInt16();
                length = reader.ReadUInt32();
            }

            byte[] val = reader.ReadBytes((int) length);

        } while (g == 2);

        fs.Close();
    }

    return ;
}

コードは、エンコードされたデータの転送構文がグループ2の要素の後で変更される可能性があることを実際に考慮しようとはしません。また、読み込まれた実際の値を使用して何もしようとはしません。

于 2010-03-05T04:19:00.837 に答える
1

いくつかの疑似論理

128バイトのプリアンブルの後に「D」、「I」、「C」、「M」の文字をチェックして、ヘッダーファイルを読み取り、それがDICOMファイルであるかどうかを確認するにはどうすればよいですか?

  • File.OpenReadを使用して、バイナリファイルとして開きます
  • 128の位置を探し、配列に4バイトを読み込んで、DICMのbyte[]値と比較します。そのためにASCIIEncoding.GetBytes()を使用できます

データの他の部分を読み取ってファイルを解析し続けるにはどうすればよいですか?

  • 以前に使用したFileStreamオブジェクトハンドルを使用してReadまたはReadByteを使用してファイルの読み取りを続行します
  • 上記と同じ方法を使用して比較を行います。

ファイルを閉じて破棄することを忘れないでください。

于 2010-03-05T04:28:16.583 に答える
0

このように使用することもできます。

FileStream fs = File.OpenRead(path);

byte[] data = new byte[132];
fs.Read(data, 0, data.Length);

int b0 = data[0] & 255, b1 = data[1] & 255, b2 = data[2] & 255, b3 = data[3] & 255;

if (data[128] == 68 && data[129] == 73 && data[130] == 67 && data[131] == 77)
        {
           //dicom file
        }
        else if ((b0 == 8 || b0 == 2) && b1 == 0 && b3 == 0)
        {
            //dicom file
        }
于 2010-04-21T07:11:45.443 に答える
0

Evil DicomライブラリのEvilDicom.Helper.DicomReaderから取得:

 public static bool IsValidDicom(BinaryReader r)
    {
        try
        {
            //128 null bytes
            byte[] nullBytes = new byte[128];
            r.Read(nullBytes, 0, 128);
            foreach (byte b in nullBytes)
            {
                if (b != 0x00)
                {
                    //Not valid
                    Console.WriteLine("Missing 128 null bit preamble. Not a valid DICOM file!");
                    return false;
                }
            }
        }
        catch (Exception)
        {

            Console.WriteLine("Could not read 128 null bit preamble. Perhaps file is too short");
            return false;
        }

        try
        {
            //4 DICM characters
            char[] dicm = new char[4];
            r.Read(dicm, 0, 4);
            if (dicm[0] != 'D' || dicm[1] != 'I' || dicm[2] != 'C' || dicm[3] != 'M')
            {
                //Not valid
                Console.WriteLine("Missing characters D I C M in bits 128-131. Not a valid DICOM file!");
                return false;
            }
            return true;

        }
        catch (Exception)
        {

            Console.WriteLine("Could not read DICM letters in bits 128-131.");
            return false;
        }

    }
于 2011-09-06T15:05:28.187 に答える