2010-03-04 63 views
10

我想在C#中讀取DICOM文件。我不想做任何事情,我只是爲了現在想知道如何閱讀元素,但首先我真的很想知道如何閱讀標題,看看是否是有效的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個元素:一個定義組長度,一個存儲文件版本並存儲傳輸語法。後

問題

  • 如何我讀的頭文件,並驗證它是否是通過檢查「d」 DICOM文件,「我」,「C」,「M」字128字節的前導碼?
  • 如何繼續解析讀取數據其他部分的文件?
+0

我認爲這將是更好地使用的ReadLine(),而不是按字節讀取文件的字節。每條記錄似乎都在不同的路線上 – A9S6 2010-03-05 15:44:43

回答

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組的元素,它也不會嘗試這樣做,在讀的實際值什麼。

+0

謝謝史蒂夫,我注意到你在很多關於DICOM的文章中,特別是關於ClearCanvas的文章。我尊重你的答案。再次感謝。 – Xaisoft 2010-03-05 14:03:45

+0

謝謝,Xaisoft。如果你真的想看看,我從基於mDCM早期版本的ClearCanvas庫中複製了一些代碼。您可以查看ClearCanvas.Dicom.IO.DicomStreamReader類來查看我們的解析器,這顯然比這個片段複雜得多。 – 2010-03-05 15:37:15

+0

你好史提夫,你能告訴我什麼是* .dcm文件格式。例如,第一個128字節是前導碼,接下來的4個字節是前綴。哪裏會有關於患者姓名,真實圖像等的信息。 – 2011-05-10 14:55:11

4

快速Google search帶來了三個DICOM C#庫:

+1

圖書館很好,但我只是爲了學習目的而自己去做。我只需要一個關於如何閱讀文件的起點...感謝您的鏈接 – Xaisoft 2010-03-04 19:50:40

1

只是一些pseudologic

如何我讀的頭文件,並驗證它是否是一個DICOM文件,通過檢查128字節前導後的'D','I','C','M'字符?

  • 打開爲二進制文件,使用File.OpenRead
  • 尋求到位置128和讀4個字節到陣列,並比較它反對票爲DICM字節[]值。您可以使用ASCIIEncoding.GetBytes()

如何繼續解析讀取數據其他部分的文件?

  • 繼續閱讀使用Read或ReadByte使用您以前
  • 使用像上面同樣的方法做你的比較FileStream對象句柄的文件。

不要忘了關閉和處理文件。

+0

感謝Psudocode,這有助於。 – Xaisoft 2010-03-05 14:05:53

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

從EvilDicom.Helper.DicomReader取自Evil Dicom庫:

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

    }