我想用 C# 读取 DICOM 文件。我不想做任何花哨的事情,我只是现在想知道如何读取元素,但首先我实际上想知道如何读取标题以查看是否是有效的 DICOM 文件.
它由二进制数据元素组成。前 128 个字节未使用(设置为零),后跟字符串“DICM”。紧随其后的是标题信息,这些信息被组织成组。
示例 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
在上面的示例中,标题被组织成组。 group 0002 hex是文件元信息组,包含3个元素:一个定义组长度,一个存储文件版本,一个存储传输语法。
问题
- 如何读取头文件并通过检查 128 字节序言后的“D”、“I”、“C”、“M”字符来验证它是否为 DICOM 文件?
- 如何继续解析文件以读取数据的其他部分?
最佳答案
像这样的东西应该读取文件,它是基本的并且不能处理所有情况,但这将是一个起点:
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 组元素之后可能发生变化,它也没有尝试对读入的实际值做任何事情。
关于c#:如何读取文件的一部分? (DICOM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2381983/