[vtkusers] read Analyze files with VTK

Tron Darvann tdarvann at lab3d.odont.ku.dk
Thu Apr 21 05:17:52 EDT 2005


Hello Wouter,
I use vtkImageReader which can read a single .img Analyze file, and is not restricted to 16 bit data.
The way I read the header information in the .hdr file is not optimal.  Maybe you can solve this more
elegantly.  Here below is my ReadAnalyzeImage tcl procedure.
Tron Darvann

proc ReadAnalyzeImage {infilename} {
  # NOTE: This routine can presently only read Analyze headers written in native
  # format, i.e. on the same type of machine as we now try to read it.  This is due
  # to the tcl command binary scan that cannot read floating point values unless native.
  global xpix ypix zpix xs ys zs
  source vtkImageInclude.tcl
  set indir [file rootname $infilename]
  set img_extension ".img"
  set imgname $indir$img_extension
  imreader Delete
  vtkImageReader imreader
  # Get info from Analyze header
  set fileId [open $infilename r]
  set var [read $fileId 4]
  binary scan $var i hsize

  if { $hsize == 348 } {
    # We read the long integer 348 correctly.  Is written on native machine.
    set native 1        
  } else {
    # We did not read the long integer 348 correctly.  Possibly written on other machine.
    # Try to read it again.
    close $fileId
    set fileId [open $infilename r]
    set var [read $fileId 4]
    binary scan $var I hsize
    if { $hsize == 348 } {
      # We read the long integer 348 correctly.  Is written on another machine.
      set native 0
    } else {
      # We did not read the long integer 348 correctly.  Not Analyze format.
      notify_error "Could not read file header. Possibly corrupt or non-Analyze format"
      return
    }           
  }
  if { $native == 0 } { 
    notify_error "Analyze file must be in native format.  Try .hea or convert to native."
    return -1
    #set var [read $fileId 28]
    #set var [read $fileId 4]
    #binary scan $var I extent
    #set var [read $fileId 4]
    #set var [read $fileId 2]
    #binary scan $var S ndims
    #set var [read $fileId 2]
    #binary scan $var S xs
    #notify $xs xs
    #set var [read $fileId 2]
    #binary scan $var S ys
    #set var [read $fileId 2]
    #binary scan $var S zs
    #set var [read $fileId 22]
    #set var [read $fileId 2]
    #binary scan $var S datatype
    #set var [read $fileId 2]
    #binary scan $var S bitpix
    #set var [read $fileId 2]
    #set var [read $fileId 4]
    #set var [read $fileId 4]
    #binary scan $var f xpix
    #set var [read $fileId 4]
    #binary scan $var f ypix
    #set var [read $fileId 4]
    #binary scan $var f zpix
    #set xpix 1.0
    #set ypix 1.0
    #set zpix 1.0
    #imreader SetDataByteOrderToBigEndian
    #EditHeader
  } else {
    # Is in native format.
    set var [read $fileId 28]
    set var [read $fileId 4]
    binary scan $var i extent
    set var [read $fileId 4]
    set var [read $fileId 2]
    binary scan $var s ndims
    set var [read $fileId 2]
    binary scan $var s xs
    set var [read $fileId 2]
    binary scan $var s ys
    set var [read $fileId 2]
    binary scan $var s zs
    set var [read $fileId 22]
    set var [read $fileId 2]
    binary scan $var s datatype
    set var [read $fileId 2]
    binary scan $var s bitpix
    set var [read $fileId 2]
    set var [read $fileId 4]
    set var [read $fileId 4]
    binary scan $var f xpix
    set var [read $fileId 4]
    binary scan $var f ypix
    set var [read $fileId 4]
    binary scan $var f zpix
  }
    if {($bitpix != 8) && ($bitpix != 16) } {
      notify_error "Sorry, image must be 8 or 16 bit in current landmarker implementation."
    }
  close $fileId
  set hx [expr $xs - 1 ]
  set hy [expr $ys - 1 ]
  set hz [expr $zs - 1 ]
  imreader SetDataByteOrderToLittleEndian
  imreader SetFileDimensionality 3
  imreader SetDataExtent 0 $hx 0 $hy 0 $hz
  imreader SetDataSpacing $xpix $ypix $zpix
  imreader SetFileName $imgname
  imreader SetHeaderSize 0
  if {$bitpix == 16} {
    imreader SetDataScalarTypeToShort
  }
  if {$bitpix == 8} {
    imreader SetDataScalarTypeToUnsignedChar
  }

  #imreader SetDataMask 0x7fff
  #reader DebugOn
  #reader Update

  # We set as default that image is to be flipped in y (needed to fit with Mvox)
  set ImageFlipY 1
  
  if {$ImageFlipY == 1} {
  # Flip volume in y
  
  vtkImageFlip reslice1
    reslice1 SetInput [imreader GetOutput]
    reslice1 SetFilteredAxis 1
  }


  viewer Delete
  vtkImageViewer viewer
  viewer SetInput [imreader GetOutput]
  viewer SetZSlice 0
  #viewer SetColorWindow 2000
  #viewer SetColorLevel 1000
  #viewer DebugOn
  #viewer Render

  viewer SetPosition 50 50

  #make interface
  source ImageViewerInterface.tcl

}



More information about the vtkusers mailing list