local_percentile_core#

Fast 2D percentile on uint16 images using a sliding histogram window.

Why this exists#

For lightsheet correction background estimation you use:
  • selem = (200, 200, 1)

  • step = (2, 2, 1)

  • spacing = (25, 25, 1) with interpolation

The original Python/Numpy implementation tends to:
  • reallocate per center

  • recompute overlapping regions

  • call np.percentile repeatedly

This Cython implementation:
  • maintains a histogram (size = max_bin + 1)

  • slides the window along x, updating by removing/adding columns

  • updates to next row by removing/adding rows

  • computes percentile from the histogram in O(max_bin) worst case, but typically max_bin is 4096 and the scan is cache-friendly.

Important notes#

  • This is intended for uint16 (or values in [0, max_bin]) after preprocessing.

  • Mask is optional. If mask is provided, only masked-in pixels contribute.

  • Border handling: “cropped window” (window clipped to image bounds).

  • Separate loops: strict interior vs border pixels.

Performance knobs#

  • If your downstream code tolerates approximation, do:
    1. compute on a coarse grid (spacing)

    2. upsample with cv2.INTER_LINEAR

percentile2d_u16(image, q, max_bin, mask=None)#

Compute per-pixel percentile map for 2D uint16 image with cropped borders.

Parameters:
  • image ((H, W) uint16) – Input slice.

  • q (float) – Quantile in [0, 1].

  • max_bin (int) – Maximum histogram bin (inclusive). Typical: 4095 (2**12 - 1) or 4096.

  • mask ((H, W) uint8 or bool, optional) – Non-zero values participate in the histogram. If None, all pixels used.

Returns

out(H, W) uint16

Percentile at each pixel.

percentile2d_u16_window(image, q, rx, ry, max_bin, mask=None)#

Fast percentile map with a rectangular window of radius (ry, rx).

Window at (y, x) is:

y in [y-ry, y+ry], x in [x-rx, x+rx] clipped to image bounds.

Notes

  • Strict interior pixels (ry..H-ry-1, rx..W-rx-1) use constant window size.

  • Border pixels use cropped windows and are computed in a second pass.

Returns uint16 percentile values (bin index).

percentile2d_u16_window_grid(image, q, rx, ry, grid_x, grid_y, max_bin, mask=None)#

Percentile map computed on a coarse grid using a sliding histogram.

Centers are located at:

y = y0 + i*grid_y x = x0 + j*grid_x

where (y0, x0) match the legacy center placement as closely as possible for speed runs (we use y0=0, x0=0 in the grid image coordinates; the wrapper should handle the legacy ‘left’ offset if it matters).