Removing hot pixels from an image?

My camera images are now showing the effects of what are called hot pixels. These are bright spots where the CMOS detector is stuck at a specific value. I can determine where these pixels are using a dark image calibration. I want to remove hot pixels from my images. I think the optimal case is to average them against the surrounding pixels. I see that ImageFilter would provide an option via NaNZapMedian. My workflow would seem to be

* Use the dark image to create a matrix map where hot pixels are assigned NaN and all other pixels are assigned unity

* Multiply this matrix map times an image to set the hot pixels in the image to NaN

* Apply the NaNZapMedian filter to the image

Would any other approach be as effective or perhaps even more effective?

In the astrophotography world, if you don't have a master dark to use as a hot pixel map, it's common practice to use a sigma-clipping method for removing hot pixels. I don't know exactly the procedure, but I imagine something like this. This might be more effective in photon-limited shots though, and might not work as well for daylight photography...

Variable kappa = 3 //accepted # standard deviations above the mean
Variable med = median(theImage)
ImageStats theImage
theImage = (theImage > V_avg + kappa * V_sdev) ? med : theImage


My Nika has dezingering code (ugly term)... 

wave image
variable DezingerRatio               //typically3-5x
Duplicate/Free image, dup
MatrixFilter /N=3 median image       // 3x3 median filter (integer result if image integer, fp if fp)
MatrixOp/Free/NTHR=0 DiffWave = dup / (abs(image))      // ratio between raw and filtered, high values (>3-5) are comics and high signals  
    //image = SelectNumber(DiffWave>DezingerRatio,dup,image)    // choose filtered (image) if difference is great
MatrixOp/O/NTHR=0 image = dup * (-1)*(greater(Diffwave,DezingerRatio)-1) + image*(greater(Diffwave,DezingerRatio))     //the MatrixOp is 3x faster than the line above....

Input is Image and ratio at which point you assume it is "zinger". Not sure where I got the MatrixOP line, it looks confusing but it works and is fast. 

Hi Jan,

I'm just wondering what's the point of /NTHR=0 in the above?


Hello AG,

am I wrong in reading help that MatrixOp /NTRH=0 tells MatrixOp to use as many threads as available?


The key in the documentation is that the flag applies to "3D waves".  Recall that MatrixOP operates (mostly) on a layer-by-layer basis and this flag lets you control the performance of layer calculations using multiple threads.

In practice, it is far more important to control when TBB is being used.  As of IP9 you can even control when vectorized calculations are being used.  Naturally all threading options are meaningful only when you are dealing with a sufficient number of points (usually over 2^9).

The bottom line is that /NTHR is not necessary unless we are dealing with 3D or 4D input.