我有一个不对称斑点的图像(2d numpy数组,形状为600x600),它相对于数组轴居中并旋转。我使用scipy.optimize.curve_fit
在其上进行了2D高斯拟合,并获得了拟合参数的合理结果。下面是我的代码和这部分的结果。
from scipy import optimize
import numpy as np
x0, y0 = np.shape(image)[1]//2, np.shape(image)[0]//2
def gaussian_func(xy, x0, y0, sigma_x, sigma_y, amp, theta, offset):
x, y = xy
a = np.cos(theta)**2/(2*sigma_x**2) + np.sin(theta)**2/(2*sigma_y**2)
b = -np.sin(2*theta)/(4*sigma_x**2) + np.sin(2*theta)/(4*sigma_y**2)
c = np.sin(theta)**2/(2*sigma_x**2) + np.cos(theta)**2/(2*sigma_y**2)
inner = a * (x-x0)**2
inner += 2 * b * (x-x0) * (y-y0)
inner += c * (y-y0)**2
return (offset + amp * np.exp(-inner)).ravel()
def Sigma2FWHM(sigma):
return 2 * np.sqrt(2*np.log(2)) * sigma
def generate(data_set):
xvec = np.arange(0, np.shape(data_set)[1], 1)
yvec = np.arange(0, np.shape(data_set)[0], 1)
X, Y = np.meshgrid(xvec, yvec)
return X, Y
# Fit subimage of image to 2D Gaussian (subimage helps with computation time)
# Guesses
theta_guess = np.deg2rad(96)
sigma_x, sigma_y = 5, 4
amp = 1 #the image was previously normalized so highest intensity point is 1
subimage = image[y0-14:y0+14, x0-14:x0+14] #the entire blob is contained within this region
offset = np.min(subimage)
guesses = [np.shape(subimage)[1]//2, np.shape(subimage}[0]//2, sigma_x, sigma_y, amp, theta_guess, offset]
# Do fit
xx, yy = generate(subimage)
pred_params, uncert_cov = optimize.curve_fit(gaussian_func, (xx.ravel(), yy.ravel()), subimage.ravel(), p0=guesses)
FWHM_x, FWHM_y = Sigma2FWHM(np.abs(pred_params[2])), Sigma2FWHM(np.abs(pred_params[2]))
# Add back origin to centroid and convert angle back to degrees
x_0, y_0 = pred_params[0]+(x0-14), pred_params[1]+(y0-14)
angle_deg = np.rad2deg(pred_params[5])
print('Predicted FWHM x, y (pixels):', FWHM_x, FWHM_y)
输出:
Predicted FWHM x, y (pixels): 13.503 11.351
我的印象是,进行2D高斯拟合将挑选出半长轴宽度最大的角度(至少对我来说有意义),并且输出sigma_x
和sigma_y
确实对应于沿半长轴和短轴的标准偏差(半轴是与标准x轴和y轴成合适角度旋转的轴)。
但是,出于好奇,我手动计算了非旋转图像沿标准x和y轴的半高全宽。我期望的东西比高斯拟合给我的要小,但是我得到的结果却更大!以下是该部分的代码。
ylim, xlim = np.shape(image)
ypix, xpix = np.where(image==1)
x = np.take(image, ypix[0], axis=0)
y = np.take(image, xpix[0], axis=1)
#Print manually calculated FWHMs (integer estimates)
FWHM_x = len(np.where(x >= 0.5)[0])
FWHM_y = len(np.where(y >= 0.5)[0])
print('Estimated FWHM x, y without rotation:', FWHM_x, FWHM_y)
输出:
Estimated FWHM x, y without rotation: 15 13
所以我的问题是,我对高斯拟合的假设是否错误?我不明白为什么没有所谓的旋转,FWHM会更大。如果是这样,该配合给出的角度和标准偏差实际上提供了哪些信息?感谢您提供任何见识,因为这已经困扰了我一段时间。谢谢!