首页 文章

c#:如何读取文件的部分? (DICOM)

提问于
浏览
11

我想在C#中读取DICOM文件 . 我不想做任何花哨的事情,我现在只想知道如何读取元素,但首先我实际上想知道如何读取 Headers 以查看是否是有效的DICOM文件 .

它由二进制数据元素组成 . 前128个字节未使用(设置为零),后跟字符串'DICM' . 接下来是 Headers 信息,它被组织成组 .

A sample DICOM header

First 128 bytes: unused DICOM format.
Followed by the characters 'D','I','C','M'
Followed by extra header information such as:

0002,0000, File Meta Elements Groups Len: 132
0002,0001, File Meta Info Version: 256
0002,0010, Transfer Syntax UID: 1.2.840.10008.1.2.1.
0008,0000, Identifying Group Length: 152
0008,0060, Modality: MR
0008,0070, Manufacturer: MRIcro

在上面的示例中, Headers 被组织成组 . 组0002十六进制是文件元信息组,其包含3个元素:一个定义组长度,一个存储文件版本,它们存储传输语法 .

Questions

  • 如何通过在128字节前导码后检查'D','I','C','M'字符来读取头文件并验证它是否是DICOM文件?

  • 如何继续解析读取数据其他部分的文件?

6 回答

  • 4

    像这样的东西应该读取文件,它的基本并不处理所有情况,但它将是一个起点:

    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元素之后改变,它也不会尝试对读入的实际值做任何事情 .

  • 1

    快速Google search带来了三个DICOM C#库:

  • 1
  • 11

    只是一些假的

    如何通过检查128字节前导码后面的'D','I','C','M'字符来读取头文件并验证它是否是DICOM文件?

    • 使用File.OpenRead以二进制文件打开

    • 寻找位置128并将4个字节读入数组并再次比较DICM的byte []值 . 您可以使用ASCIIEncoding.GetBytes()

    如何继续解析读取数据其他部分的文件?

    • 使用您之前使用的FileStream对象句柄继续使用Read或ReadByte读取文件

    • 使用与上面相同的方法进行比较 .

    别忘了关闭并处理文件 .

  • 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
            }
    
  • 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;
            }
    
        }
    

相关问题