Bad-pixel detection

HDRL provides bad-pixel detection on a single image, on a stack of identical images, on a sequence of images, and cosmic-ray detection with the LA-Cosmic algorithm.

In PyHDRL these map to hdrl.func.BPM2D, hdrl.func.BPM3D, hdrl.func.BPMFit, hdrl.func.LaCosmic and mask utilities on hdrl.func.BPM.

Bad-pixel detection on a single image

The algorithm first smoothes the image. Then it subtracts the smoothed image and derives bad pixels by thresholding the residual image, i.e. all pixels exceeding the threshold are considered as bad. To compute the upper and lower thresholds, it measures a robust rms (a properly scaled Median Absolute Deviation), which is then scaled by kappa_low and kappa_high. The algorithm is applied iteratively for a number of times defined by maxiter. During each iteration the newly found bad pixels are ignored. The thresholding values are applied as median (residual-image) ± thresholds.

Two methods are available to derive a smoothed version of the image:

  • Filter smoothing (hdrl.func.BPM2D.Filter): apply a filter such as a median filter. The filtering is controlled by the PyCPL filter mode, border mode, and the kernel size smooth_x, smooth_y.

  • Legendre smoothing (hdrl.func.BPM2D.Legendre): fit a Legendre polynomial of order order_x and order_y. Sampling points steps_x × steps_y (the median within a box of filter_size_x and filter_size_y) decrease the fitting time.

compute() takes an hdrl.core.Image and returns a cpl.core.Mask with the newly found bad pixels.

fs = hdrl.func.BPM2D.Filter(4.0, 5.0, 6, cpl.core.Filter.MEDIAN, cpl.core.Border.NOP, 7, 9)
mask = fs.compute(image)

ls = hdrl.func.BPM2D.Legendre(4, 5, 6, 20, 21, 11, 12, 2, 10)
mask = ls.compute(image)

Bad-pixel detection on a stack of identical images

hdrl.func.BPM3D detects bad pixels on a stack of identical images in an imagelist. The algorithm first collapses the stack by using the median in order to generate a master image. Then it subtracts the master image from each individual image and derives the bad pixels on the residual images by thresholding.

The mean level of the different images is assumed to be the same.

Methods:

  • hdrl.func.BPM3D.Method.Absolute: uses kappa_low and kappa_high as absolute thresholds

  • hdrl.func.BPM3D.Method.Relative: scales the measured RMS on the residual image with kappa_low and kappa_high (MAD-based RMS)

  • hdrl.func.BPM3D.Method.Error: scales the propagated error of each individual pixel with kappa_low and kappa_high

compute() takes an hdrl.core.ImageList and returns a cpl.core.ImageList containing the newly found bad pixels for each input image (0 for good pixels, 1 for bad pixels). Already known bad pixels given to the routine are not included in the output mask.

bpm_3d = hdrl.func.BPM3D(4, 5, hdrl.func.BPM3D.Method.Absolute)
result = bpm_3d.compute(imglist)

Bad-pixel detection on a sequence of images

hdrl.func.BPMFit fits a polynomial to each pixel sequence and determines bad pixels based on this fit. Three thresholding methods are available:

  • hdrl.func.BPMFit.PVal(degree, pval): pixels with p-values below the threshold are considered bad

  • hdrl.func.BPMFit.RelChi(degree, low, high): relative cutoff on the chi distribution of all fits

  • hdrl.func.BPMFit.RelCoef(degree, low, high): relative cutoff on the distribution of the fit coefficients

compute() takes an hdrl.core.ImageList and a cpl.core.Vector of sampling positions (e.g. exposure time) and returns a cpl.core.Image of integer pixels. When using RelCoef, the value encodes the coefficient that was outside the relative threshold as a power of two.

p = hdrl.func.BPMFit.PVal(1, 0.1)
out_mask = p.compute(himlist, sample)

LA-Cosmic

hdrl.func.LaCosmic implements the LA-Cosmic algorithm described in van Dokkum et al. 2001, PASP, 113, 1420 to detect bad pixels and cosmic-ray hits on a single image.

The HDRL implementation does not use the error model as described in the paper, but instead uses the error image passed to the function. Several iterations are performed until no new bad pixels are found or the number of iterations reaches max_iter. In each iteration the detected cosmic ray hits are replaced by the median of the surrounding 5×5 pixels taking into account the pixel quality information.

The implementation only detects positive bad pixels or cosmic ray hits.

edgedetect() takes an hdrl.core.Image and returns a cpl.core.Mask.

lac = hdrl.func.LaCosmic(sigma_lim, f_lim, max_iter)
result_mask = lac.edgedetect(himg)

Mask filtering

hdrl.func.BPM.filter sets pixels to bad if the pixel is surrounded by other bad pixels. It allows growing and shrinking of bad pixel masks. It takes a cpl.core.Mask and a cpl.core.Filter mode (EROSION, DILATION, OPENING or CLOSING) and returns a cpl.core.Mask. hdrl.func.BPM.filter_list applies the same operation to a cpl.core.ImageList.