title: Automatically remove hot/dead pixels from an image in python
body: <p>I am using numpy and scipy to process a number of images taken with a CCD camera. These images have a number of hot (and dead) pixels with very large (or small) values. These interfere with other image processing, so they need to be removed. Unfortunately, though a few of the pixels are stuck at either 0 or 255 and are always at the same value in all of the images, there are some pixels that are temporarily stuck at other values for a period of a few minutes (the data spans many hours). </p>
  
  <p>I am wondering if there is a method for identifying (and removing) the hot pixels already implemented in python. If not, I am wondering what would be an efficient method for doing so. The hot/dead pixels are relatively easy to identify by comparing them with neighboring pixels. I could see writing a loop that looks at each pixel, compares its value to that of its 8 nearest neighbors. Or, it seems nicer to use some kind of convolution to produce a smoother image and then subtract this from the image containing the hot pixels, making them easier to identify. </p>
  
  <p>I have tried this "blurring method" in the code below, and it works okay, but I doubt that it is the fastest. Also, it gets confused at the edge of the image (probably since the gaussian_filter function is taking a convolution and the convolution gets weird near the edge). So, is there a better way to go about this?</p>
  
  <p>Example code:</p>
  
  <pre><code>import numpy as np
  import matplotlib.pyplot as plt
  import scipy.ndimage
  
  plt.figure(figsize=(8,4))
  ax1 = plt.subplot(121)
  ax2 = plt.subplot(122)
  
  #make a sample image
  x = np.linspace(-5,5,200)
  X,Y = np.meshgrid(x,x)
  Z = 255*np.cos(np.sqrt(x**2 + Y**2))**2
  
  
  for i in range(0,11):
      #Add some hot pixels
      Z[np.random.randint(low=0,high=199),np.random.randint(low=0,high=199)]= np.random.randint(low=200,high=255)
      #and dead pixels
      Z[np.random.randint(low=0,high=199),np.random.randint(low=0,high=199)]= np.random.randint(low=0,high=10)
  
  #Then plot it
  ax1.set_title('Raw data with hot pixels')
  ax1.imshow(Z,interpolation='nearest',origin='lower')
  
  #Now we try to find the hot pixels
  blurred_Z = scipy.ndimage.gaussian_filter(Z, sigma=2)
  difference = Z - blurred_Z
  
  ax2.set_title('Difference with hot pixels identified')
  ax2.imshow(difference,interpolation='nearest',origin='lower')
  
  threshold = 15
  hot_pixels = np.nonzero((difference&gt;threshold) | (difference&lt;-threshold))
  
  #Don't include the hot pixels that we found near the edge:
  count = 0
  for y,x in zip(hot_pixels[0],hot_pixels[1]):
      if (x != 0) and (x != 199) and (y != 0) and (y != 199):
          ax2.plot(x,y,'ro')
          count += 1
  
  print 'Detected %i hot/dead pixels out of 20.'%count
  ax2.set_xlim(0,200); ax2.set_ylim(0,200)
  
  
  plt.show()
  </code></pre>
  
  <p>And the output:
  <img src="https://i.stack.imgur.com/dgmDg.png" alt="enter image description here"></p>