Last active
July 6, 2021 16:09
-
-
Save thomasaarholt/4db19dc94062856f81f08cd0a49c9b79 to your computer and use it in GitHub Desktop.
Bilinear binning, supports numpy and CuPy inputs using the np.array(..., like=arr) synax
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def bilinear_binning(points, intensities, subpixel=1, gaussian_blur=False): | |
"""Bilinear weighting of points onto a grid. | |
Extent of grid given by min and max of points in each dimension | |
points should be an array of shape (N, 2) | |
intensity should be an array of shape (N,) | |
subpixel will increase the gridsize by its factor | |
gaussian_blur: blur the binned intensity and weighting images before they are divided, avoiding divide-by-zero warnings | |
TODO: Give a known grid as input | |
""" | |
points = subpixel * points | |
floor = np.floor(points) | |
ceil = floor + 1 | |
floored_indices = floor.astype(int) | |
minimum_indices = floored_indices.min(0) | |
maximum_indices = floored_indices.max(0) | |
floored_indices = floored_indices - minimum_indices | |
shape = (floored_indices.max(0) - floored_indices.min(0) + 2) | |
shape = tuple(s.item() for s in shape) | |
upper_diff = ceil - points | |
lower_diff = points - floor | |
w1 = upper_diff[:, 0] * upper_diff[:, 1] | |
w2 = upper_diff[:, 0] * lower_diff[:, 1] | |
w3 = lower_diff[:, 0] * upper_diff[:, 1] | |
w4 = lower_diff[:, 0] * lower_diff[:, 1] | |
shifts = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], like=points) | |
indices = floored_indices[:, None] + shifts | |
indices = (indices * np.array([shape[1], 1], like=points)).sum(-1) | |
weights = np.array([w1, w2, w3, w4], like=points).T | |
intens_bins = np.bincount(indices.flatten(), weights=( | |
intensities[:, None]*weights).flatten(), minlength=np.prod(shape, dtype=float).astype(int).item()) | |
weight_bins = np.bincount( | |
indices.flatten(), weights=weights.flatten(), minlength=np.prod(shape, dtype=float).astype(int).item()) | |
intens_image = intens_bins.reshape(shape) | |
weight_image = weight_bins.reshape(shape) | |
if gaussian_blur: | |
if gaussian_blur == True: | |
gaussiann_blur = 1 | |
intens_image = gaussian_filter(intens_image, gaussian_blur) | |
weight_image = gaussian_filter(weight_image, gaussian_blur) | |
return intens_image/weight_image |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment