Skip to content

Instantly share code, notes, and snippets.

@nvladimus
Last active August 20, 2023 20:43
Show Gist options
  • Save nvladimus/fc88abcece9c3e0dc9212c2adc93bfe7 to your computer and use it in GitHub Desktop.
Save nvladimus/fc88abcece9c3e0dc9212c2adc93bfe7 to your computer and use it in GitHub Desktop.
Computing FWHM of PSF using 2D Gaussian fit
# Compute FWHM(x,y) using 2D Gaussian fit, min-square optimization
# Optimization fits 2D gaussian: center, sigmas, baseline and amplitude
# works best if there is only one blob and it is close to the image center.
# author: Nikita Vladimirov @nvladimus (2018).
# based on code example: https://stackoverflow.com/questions/21566379/fitting-a-2d-gaussian-function-using-scipy-optimize-curve-fit-valueerror-and-m
import numpy as np
import scipy.optimize as opt
def twoD_GaussianScaledAmp((x, y), xo, yo, sigma_x, sigma_y, amplitude, offset):
"""Function to fit, returns 2D gaussian function as 1D array"""
xo = float(xo)
yo = float(yo)
g = offset + amplitude*np.exp( - (((x-xo)**2)/(2*sigma_x**2) + ((y-yo)**2)/(2*sigma_y**2)))
return g.ravel()
def getFWHM_GaussianFitScaledAmp(img):
"""Get FWHM(x,y) of a blob by 2D gaussian fitting
Parameter:
img - image as numpy array
Returns:
FWHMs in pixels, along x and y axes.
"""
x = np.linspace(0, img.shape[1], img.shape[1])
y = np.linspace(0, img.shape[0], img.shape[0])
x, y = np.meshgrid(x, y)
#Parameters: xpos, ypos, sigmaX, sigmaY, amp, baseline
initial_guess = (img.shape[1]/2,img.shape[0]/2,10,10,1,0)
# subtract background and rescale image into [0,1], with floor clipping
bg = np.percentile(img,5)
img_scaled = np.clip((img - bg) / (img.max() - bg),0,1)
popt, pcov = opt.curve_fit(twoD_GaussianScaledAmp, (x, y),
img_scaled.ravel(), p0=initial_guess,
bounds = ((img.shape[1]*0.4, img.shape[0]*0.4, 1, 1, 0.5, -0.1),
(img.shape[1]*0.6, img.shape[0]*0.6, img.shape[1]/2, img.shape[0]/2, 1.5, 0.5)))
xcenter, ycenter, sigmaX, sigmaY, amp, offset = popt[0], popt[1], popt[2], popt[3], popt[4], popt[5]
FWHM_x = np.abs(4*sigmaX*np.sqrt(-0.5*np.log(0.5)))
FWHM_y = np.abs(4*sigmaY*np.sqrt(-0.5*np.log(0.5)))
return (FWHM_x, FWHM_y)
#calling example: img is your image
(FWHM_x, FWHM_y) = getFWHM_GaussianFitScaledAmp(img)
@chasevan
Copy link

chasevan commented Nov 3, 2020

what is opt?

@astronasko
Copy link

astronasko commented Feb 25, 2021

what is opt?

That's the alias of the scipy.optimize module!

@WiilyLin
Copy link

There will be ValueError if the image has nan

@teymursaif
Copy link

Worked perfectly for me. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment