Exemple #1
0
def read2DImageROI(path, dimensions, interval, pixelType=UnsignedShortType, header=0, byte_order=ByteOrder.LITTLE_ENDIAN):
  """ Read a region of interest (the interval) of an image in a file.
      Assumes the image is written with the first dimension moving slowest.

      path: the file path to the image file.
      dimensions: a sequence of integer values e.g. [512, 512, 512]
      interval: two sequences of integer values defining the min and max coordinates, e.g.
                [[20, 0], [400, 550]]
      pixeltype: e.g. UnsignedShortType, FloatType
      header: defaults to zero, the number of bytes between the start of the file and the start of the image data.

      Supports only these types: UnsignedByteType, UnsignedShortType, FloatType.

      Returns an ArrayImg of the given type.
  """
  ra = RandomAccessFile(path, 'r')
  try:
    width, height = dimensions
    minX, minY = interval[0]
    maxX, maxY = interval[1]
    roi_width, roi_height = maxX - minX + 1, maxY - minY + 1
    tailX = width - roi_width - minX

    #print minX, minY
    #print maxX, maxY
    #print roi_width, roi_height

    size = roi_width * roi_height
    n_bytes_per_pixel = pixelType().getBitsPerPixel() / 8

    #print n_bytes_per_pixel

    bytes = zeros(size * n_bytes_per_pixel, 'b')

    # Read only the 2D ROI
    ra.seek(header + (minY * width + minX) * n_bytes_per_pixel)
    for h in xrange(roi_height):
      ra.readFully(bytes, h * roi_width * n_bytes_per_pixel, roi_width * n_bytes_per_pixel)
      ra.skipBytes((tailX + minX) * n_bytes_per_pixel)
    # Make an image
    roiDims = [roi_width, roi_height]
    if UnsignedByteType == pixelType:
      return ArrayImgs.unsignedBytes(bytes, roiDims)
    if UnsignedShortType == pixelType:
      shorts = zeros(size, 'h')
      ByteBuffer.wrap(bytes).order(byte_order).asShortBuffer().get(shorts)
      return ArrayImgs.shorts(shorts, roiDims)
    if FloatType == pixelType:
      floats = zeros(size, 'f')
      ByteBuffer.wrap(bytes).order(byte_order).asFloatBuffer().get(floats)
      return ArrayImgs.floats(floats, roiDims)
  finally:
    ra.close()
def readFIBSEMdat(path, channel_index=-1, header=1024, magic_number=3555587570):
  """ Read a file from Shan Xu's FIBSEM software, where two channels are interleaved.
      Assumes channels are stored in 16-bit.
      
      path: the file path to the .dat file.
      channel_index: the 0-based index of the channel to parse, or -1 (default) for all.
      header: defaults to a length of 1024 bytes
      magic_number: defaults to that for version 8 of Shan Xu's .dat image file format.
  """
  ra = RandomAccessFile(path, 'r')
  try:
    # Check the magic number
    ra.seek(0)
    if ra.readInt() & 0xffffffff != magic_number:
      print "Magic number mismatch"
      return None
    # Read the number of channels
    ra.seek(32)
    numChannels = ra.readByte() & 0xff # a single byte as unsigned integer
    # Parse width and height
    ra.seek(100)
    width = ra.readInt()
    ra.seek(104)
    height = ra.readInt()
    print numChannels, width, height
    # Read the whole interleaved pixel array
    ra.seek(header)
    bytes = zeros(width * height * 2 * numChannels, 'b') # 2 for 16-bit
    ra.read(bytes)
    print "read", len(bytes), "bytes" # takes ~2 seconds
    # Parse as 16-bit array
    sb = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).asShortBuffer()
    shorts = zeros(width * height * numChannels, 'h')
    sb.get(shorts)
    # Deinterleave channels
    # With Weaver: fast
    channels = w.deinterleave(shorts, numChannels, channel_index)
    # With python array sampling: very slow, and not just from iterating whole array once per channel
    # seq = xrange(numChannels) if -1 == channel_index else [channel_index]
    #channels = [shorts[i::numChannels] for i in seq]
    # With clojure: extremely slow, may be using reflection unexpectedly
    #channels = deinterleave.invoke(shorts, numChannels)
    print len(channels)
    # Shockingly, these values are signed shorts, not unsigned!
    return [ArrayImgs.shorts(s, [width, height]) for s in channels]
  finally:
    ra.close()