2010-03-04 17 views
10

Me gustaría leer un archivo DICOM en C#. No quiero hacer nada elegante, solo por ahora me gustaría saber cómo leer en los elementos, pero primero me gustaría saber cómo leer el encabezado para ver si es un archivo DICOM válido.C#: ¿cómo leer partes de un archivo? (DICOM)

Se compone de elementos de datos binarios. Los primeros 128 bytes no se utilizan (se establece en cero), seguidos de la cadena 'DICM'. A esto le sigue la información del encabezado, que está organizada en grupos.

Un encabezado muestra 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 

En el ejemplo anterior, la cabecera se organiza en grupos. El grupo 0002 hex es el grupo de metainformación de archivos que contiene 3 elementos: uno define la longitud del grupo, uno almacena la versión del archivo y su almacena la sintaxis de transferencia.

Preguntas

  • Cómo leo el archivo de cabecera y verificar si se trata de un archivo DICOM mediante la comprobación de la 'D', 'I', 'C', personajes de 'M' después de la ¿Preámbulo de 128 bytes?
  • ¿Cómo puedo seguir analizando el archivo leyendo las otras partes de los datos?
+0

Creo que va a ser mejor usar ReadLine() en lugar de leer el byte a byte de archivos. Cada registro parece estar en una línea diferente – A9S6

Respuesta

11

Algo como esto debería leer el archivo, es básico y no maneja todos los casos, pero sería un punto de partida:


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

El código en realidad no tratar de tomar en cuenta que la sintaxis de transferencia de los datos codificados pueden cambiar después de que el grupo de 2 elementos, sino que también no tratar de hacer cualquier cosa con los valores reales leídos en.

+0

Gracias Steve, me di cuenta de que estás en una gran cantidad de publicaciones sobre DICOM especialmente con respecto a ClearCanvas. Respeto tu respuesta Gracias de nuevo. – Xaisoft

+0

Gracias, Xaisoft. Si realmente quieres mirar, copié parte de este código de las bibliotecas de ClearCanvas, que se basan en una versión anterior de mDCM. Puede ver la clase ClearCanvas.Dicom.IO.DicomStreamReader para ver nuestro analizador sintáctico, que obviamente es mucho más complejo que este fragmento. –

+0

hola Steve, ¿puedes decirme qué tiene el formato de archivo * .dcm? Por ejemplo, el primer byte de 128 es un preámbulo, los siguientes 4 bytes son el prefijo. ¿Dónde estará la información sobre el nombre del paciente, la imagen real, etc. –

4

Una rápida Google search criados tres # bibliotecas DICOM C:

+1

Las bibliotecas son buenas, pero estoy tratando de hacerlo solo para fines de aprendizaje. Solo necesito un punto de partida sobre cómo leer los archivos ... Gracias por los enlaces – Xaisoft

1

Sólo algunos pseudologic

Cómo leo el archivo de cabecera y verificar si puede es un archivo DICOM al buscar los caracteres 'D', 'I', 'C', 'M' después del preámbulo de 128 bytes?

  • Abrir como archivo binario, usando File.OpenRead
  • Se posiciona en 128 y leer 4 bytes en la matriz y compararlo againts byte [] Valor SMI. Puede usar ASCIIEncoding.GetBytes() para ese

¿Cómo puedo seguir analizando el archivo leyendo las otras partes de los datos?

  • seguir leyendo el archivo usando Lea o ReadByte utilizando el asa objeto FileStream que tiene antes
  • uso el mismo método como el anterior para hacer su comparación.

No olvide cerrar y desechar el archivo.

+0

Gracias por el Psudocode, esto ayuda. – Xaisoft

0

también se puede usar así.

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

Tomado de EvilDicom.Helper.DicomReader de la biblioteca 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; 
     } 

    }