Skip to content

Instantly share code, notes, and snippets.

@ziap
Created July 26, 2025 06:43
Show Gist options
  • Select an option

  • Save ziap/6e1a143a38e18340dae7a8c7e5a7d4af to your computer and use it in GitHub Desktop.

Select an option

Save ziap/6e1a143a38e18340dae7a8c7e5a7d4af to your computer and use it in GitHub Desktop.
Efficient binomial-approximated gaussian blur with FFT
def binomial_filter_fft(filter_size, fft_size):
k = np.arange(fft_size)
z = -2j * np.pi * k / fft_size
L = np.log1p(np.exp(z)) - np.log(2)
logH = (filter_size - 1) * L
return np.exp(logH)
def conv_separable_fft(img2d, filter_size, filter):
H, W, C = img2d.shape
n = filter_size | 1
pad = n // 2
padded = np.pad(img2d, ((pad, pad), (pad, pad), (0, 0)), mode='edge')
fft_h = 1 << (H + n - 2).bit_length()
fft_w = 1 << (W + n - 2).bit_length()
fft_img = np.fft.rfft2(padded, s=(fft_h, fft_w), axes=(0, 1))
fft_img *= filter(n, fft_h)[:, None, None]
fft_img *= filter(n, fft_w)[None, :(fft_w // 2) + 1, None]
conv = np.fft.irfft2(fft_img, s=(fft_h, fft_w), axes=(0, 1))
return conv[n - 1:n - 1 + H, n - 1:n - 1 + W, :]
def blur_fft(img2d, filter_size):
return conv_separable_fft(img2d, filter_size, binomial_filter_fft)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment