title: Pixel interpolation(binning?)
body: <p>I am trying to write up a pixel interpolation(binning?) algorithm (I want to, for example, take four pixels and take their average and produce that average as a new pixel). I've had success with stride tricks to speed up the "partitioning" process, but the actual calculation is really slow. For a 256x512 16-bit grayscale image I get the averaging code to take 7s on my machine. I have to process from 2k to 20k images depending on the data set. The purpose is to make the image less noisy (I am aware my proposed method decreases resolution, but this might not be a bad thing for my purposes).</p>
  
  <pre><code>import numpy as np
  from numpy.lib.stride_tricks import as_strided
  from scipy.misc import imread
  import matplotlib.pyplot as pl
  import time
  
  def sliding_window(arr, footprint):
      """ Construct a sliding window view of the array"""
      t0 = time.time()
      arr = np.asarray(arr)
      footprint = int(footprint)
      if arr.ndim != 2:
          raise ValueError("need 2-D input")
      if not (footprint &gt; 0):
          raise ValueError("need a positive window size")
      shape = (arr.shape[0] - footprint + 1,
               arr.shape[1] - footprint + 1, footprint, footprint)
      if shape[0] &lt;= 0:
          shape = (1, shape[1], arr.shape[0], shape[3])
      if shape[1] &lt;= 0:
          shape = (shape[0], 1, shape[2], arr.shape[1])
      strides = (arr.shape[1]*arr.itemsize, arr.itemsize,
                 arr.shape[1]*arr.itemsize, arr.itemsize)
  
      t1 = time.time()
      total = t1-t0
      print "strides"
      print total
  
      return as_strided(arr, shape=shape, strides=strides)
  
  
  
  
  def binning(w,footprint):
  
      #the averaging block
      #prelocate memory
      binned = np.zeros(w.shape[0]*w.shape[1]).reshape(w.shape[0],w.shape[1])
      #print w
      t2 = time.time()
      for i in xrange(w.shape[0]):
          for j in xrange(w.shape[1]):
              binned[i,j] = w[i,j].sum()/(footprint*footprint + 0.0)
  
      t3 = time.time()
      tot = t3-t2
      print tot
  
      return binned
  
  Output:
  5.60283660889e-05
  7.00565886497
  </code></pre>
  
  <p>Is there some built-in/optimized function that would to the same thing I want, or should I just try and make a C extension (or even something else) ?</p>
  
  <p>Below is the additional part of the code just for completeness, since I think the functions are the most important here. Image plotting is slow, but I think there is a way to improve it for example here</p>
  
  <pre><code>for i in range(2000):
      arr = imread("./png/frame_" + str("%05d" % (i + 1) ) + ".png").astype(np.float64)
      w = sliding_window(arr,footprint)
      binned = binning(w,footprint)
      pl.imshow(binned,interpolation = "nearest")
      pl.gray()
      pl.savefig("binned_" + str(i) + ".png")
      enter code here
  </code></pre>
  
  <p>What I am looking for could be called interpolation. I just used the term the person who advised me to do this used. Probably that is the reason why I was finding histogram related stuff !</p>
  
  <p>Apart from the median_filter I tried generic_filter from scipy.ndimage but those did not give me the results I wanted (they had no "valid" mode like in convolution i.e. these relied on going out of bounds of the array when moving the kernel arround). I asked in code review and it seems that stackoverflow would be a more suitable place for this question.</p>