我想在C#中读取DICOM文件。我不想做任何花哨的事情,我现在只想知道如何读取元素,但首先我实际上想知道如何读取标题以查看是否是有效的DICOM文件< / em>的
它由二进制数据元素组成。前128个字节未使用(设置为零),后跟字符串'DICM'。接下来是标题信息,它被组织成组。
示例DICOM标题
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
在上面的示例中,标题被组织成组。组0002十六进制是文件元信息组,包含3个元素:一个定义组长度,一个存储文件版本,它们存储传输语法。
问题
答案 0 :(得分:11)
这样的东西应该读取文件,它是基本的,并不处理所有情况,但它将是一个起点:
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 :(得分:4)
快速Google search提出了三个DICOM C#库:
答案 2 :(得分:1)
答案 3 :(得分:1)
只是一些假的
如何通过检查128字节前导后的'D','I','C','M'字符来读取头文件并验证它是否是DICOM文件?
如何继续解析读取数据其他部分的文件?
别忘了关闭并处理该文件。
答案 4 :(得分: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
}
答案 5 :(得分: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;
}
}