Last active
October 30, 2024 00:11
-
-
Save nvladimus/fc88abcece9c3e0dc9212c2adc93bfe7 to your computer and use it in GitHub Desktop.
Computing FWHM of PSF using 2D Gaussian fit
This file contains 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
# 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) |
There will be ValueError if the image has nan
Worked perfectly for me. Thanks.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That's the alias of the scipy.optimize module!