我打算用一个2D高斯函数来拟合激光束的图像,以获得它的参数,如FWHM
和位置。到目前为止,我试图理解如何在Python中定义2D高斯函数,以及如何向它传递x和y变量。
我已经写了一个小脚本,它定义了这个函数,绘制了它,添加了一些噪声,然后尝试使用curve_fit
来拟合它。除了最后一步,我尝试将我的模型函数拟合到噪声数据之外,一切似乎都正常。下面是我的代码:
import scipy.optimize as opt
import numpy as np
import pylab as plt
#define model function and pass independant variables x and y as a list
def twoD_Gaussian((x,y), amplitude, xo, yo, sigma_x, sigma_y, theta, offset):
xo = float(xo)
yo = float(yo)
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)
return offset + amplitude*np.exp( - (a*((x-xo)**2) + 2*b*(x-xo)*(y-yo) + c*((y-yo)**2)))
# Create x and y indices
x = np.linspace(0, 200, 201)
y = np.linspace(0, 200, 201)
x,y = np.meshgrid(x, y)
#create data
data = twoD_Gaussian((x, y), 3, 100, 100, 20, 40, 0, 10)
# plot twoD_Gaussian data generated above
plt.figure()
plt.imshow(data)
plt.colorbar()
# add some noise to the data and try to fit the data generated beforehand
initial_guess = (3,100,100,20,40,0,10)
data_noisy = data + 0.2*np.random.normal(size=len(x))
popt, pcov = opt.curve_fit(twoD_Gaussian, (x,y), data_noisy, p0 = initial_guess)
以下是我在使用winpython 64-bit
Python 2.7
运行脚本时收到的错误消息:
ValueError: object too deep for desired array
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "E:/Work Computer/Software/Python/Fitting scripts/2D Gaussian function fit/2D_Gaussian_LevMarq_v2.py", line 39, in <module>
popt, pcov = opt.curve_fit(twoD_Gaussian, (x,y), data_noisy, p0 = initial_guess)
File "C:\Python\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\scipy\optimize\minpack.py", line 533, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "C:\Python\WinPython-64bit-2.7.6.2\python-2.7.6.amd64\lib\site-packages\scipy\optimize\minpack.py", line 378, in leastsq
gtol, maxfev, epsfcn, factor, diag)
minpack.error: Result from function call is not a proper array of floats.
我做错了什么?是不是我把自变量传递给模型function/curve_fit
的方式?
4条答案
按热度按时间ipakzgxi1#
twoD_Gaussian
的输出必须是1D。您可以在最后一行的结尾加上.ravel()
,如下所示:显然,您需要重新调整输出以进行绘图,例如:
按照之前的步骤进行装配:
并绘制结果:
lymgl2op2#
为了进一步解释Dietrich的答案,我在使用Python 3.4(在Ubuntu 14.04上)运行建议的解决方案时遇到了以下错误:
运行
2to3
建议进行以下简单修复:这是因为,从Python 3开始,当元组作为参数传递给函数时,元组自动解包已经被删除了。更多信息,请参见这里:PEP 3113
jrcvhitl3#
curve_fit()
希望xdata
的维度是(2,n*m)
而不是(2,n,m)
。ydata
的形状应该是(n*m)
而不是(n,m)
。因此,可以使用ravel()
来展平二维数组:顺便说一句:我不确定用三角函数项进行参数化是否是最好的。例如,在数值方面和大偏差情况下,采用here描述的参数化可能会更稳健一些。
pwuypxnk4#
是否可以在任何轮廓级别获得半长轴值?