title: Optimizing performance when reading a satellite image file in python
body: <p>I have a multiband satellite image stored in the band interleaved pixel (BIP) format along with a separate header file. The header file provides the details such as the number of rows and columns in the image, and the number of bands (can be more than the standard 3).</p>
  
  <p>The image itself is stored like this (assume a 5 band image):</p>
  
  <p>[B1][B2][B3][B4][B5][B1][B2][B3][B4][B5] ... and so on (basically 5 bytes - one for each band - for each pixel starting from the top left corner of the image).</p>
  
  <p>I need to separate out each of these bands as PIL images in Python 3.2 (on Windows 7 64 bit), and currently I think I'm approaching the problem incorrectly. My current code is as follows:</p>
  
  <pre><code>def OpenBIPImage(file, width, height, numberOfBands):
      """
      Opens a raw image file in the BIP format and returns a list
      comprising each band as a separate PIL image.
      """
      bandArrays = []
      with open(file, 'rb') as imageFile:
          data = imageFile.read()
      currentPosition = 0
      for i in range(height * width):
          for j in range(numberOfBands):
              if i == 0:
                  bandArrays.append(bytearray(data[currentPosition : currentPosition + 1]))
              else:
                  bandArrays[j].extend(data[currentPosition : currentPosition + 1])
              currentPosition += 1
      bands = [Image.frombytes('L', (width, height), bytes(bandArray)) for bandArray in bandArrays]
      return bands
  </code></pre>
  
  <p>This code takes way too long to open a BIP file, surely there must be a better way to do this. I do have the numpy and scipy libraries as well, but I'm not sure how I can use them, or if they'll even help in any way.</p>
  
  <p>Since the number of bands in the image are also variable, I'm finding it hard to figure out a way to read the file quickly and separate the image into its component bands.</p>
  
  <p>And just for the record, I have tried messing with the list methods in the loops (using slices, not using slices, using only append, using only extend etc), it doesn't particularly make a difference as the major time is lost because of the number of iterations involved - (width * height * numberOfBands).</p>
  
  <p>Any suggestions or advice would be really helpful. Thanks.</p>