Я хотел бы считать файл DICOM в C#. Я не хочу делать что-либо необычное, я только на данный момент хотел бы знать, как читать в элементах, но сначала я на самом деле хотел бы знать, как прочитать заголовок, чтобы видеть, ли допустимый файл DICOM.
Это состоит из Элементов Двоичных данных. Первые 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 элемента: каждый определяет длину группы, каждый хранит версию файла и их хранилища синтаксис передачи.
Вопросы
Что-то вроде этого должно читать файл, его основной и не обрабатывать все случаи, но это будет отправная точка:
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, он также не пытается ничего сделать с фактическими считанными значениями.
Просто псевдология
Как мне прочитать файл заголовка и проверить, является ли он файлом DICOM, проверив наличие символов «D», «I», «C», «M» после 128-байтовой преамбулы?
Как мне продолжить синтаксический анализ файла, читая другие части данных?
Не забудьте закрыть и утилизировать файл.
вы также можете использовать это так.
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
}