我的实验目的是将环高斯模型拟合到图像数据中,并找出图像中椭圆或环高斯物体的参数。
为了简单和试用,我尝试使用Astropy制作环高斯模型。不幸的是,它与我的人工数据完全不同。
from astropy.modeling import Fittable2DModel, Parameter, fitting
import matplotlib.pyplot as plt
import numpy as np
class ringGaussian(Fittable2DModel):
background = Parameter(default=5.)
amplitude = Parameter(default=1500.)
x0 = Parameter(default=15.)
y0 = Parameter(default=15.)
radius = Parameter(default=2.)
width = Parameter(default=1.)
@staticmethod
def evaluate(x, y, background, amplitude, x0, y0, radius, width):
z = background + amplitude * np.exp( -((np.sqrt((x-x0)**2. + (y-y0)**2.) - radius) / width)**2 )
return z
然后我做了一些人工数据(初始参数)来测试环高斯类的拟合函数。
back = 10 # background
amp = 2000 # highest value of the Gaussian
x0 = 10 # x coordinate of center
y0 = 10 # y coordinate of center
radius = 3
width = 1
xx, yy = np.mgrid[:30, :30]
z = back + amp * np.exp( -((np.sqrt((xx-x0)**2. + (yy-y0)**2.) - radius) / width)**2 )
我使用contourf:
绘制了xx,yy和zfig = plt.subplots(figsize=(7,7))
plt.contourf(xx,yy,z)
plt.show()
这是我得到的: enter image description here
然后我尝试使用我的fittable类来拟合z:
p_init = ringGaussian() #bounds={"x0":[0., 20.], "y0":[0., 20.]}
fit_p = fitting.LevMarLSQFitter()
p = fit_p(p_init, xx, yy, z)
# It is the parameter I got:
<ringGaussian(background=133.0085329497139, amplitude=-155.53652181827655, x0=25.573499373946227, y0=25.25813520725603, radius=8.184302497405568, width=-7.273935403490675)>
我绘制了模型:
fig = plt.subplots(figsize=(7,7))
plt.contourf(xx,yy,p(xx,yy))
plt.show()
这是我得到的: enter image description here
最初,我也试图在我的班级中加入衍生物:
@staticmethod
def fit_deriv(x, y, background, amplitude, x0, y0, radius, width):
g = (np.sqrt((x-x0)**2. + (y-y0)**2.) - radius) / width
z = amplitude * np.exp( -g**2 )
dg_dx0 = - (x-x0)/np.sqrt((x-x0)**2. + (y-y0)**2.)
dg_dy0 = - (y-y0)/np.sqrt((x-x0)**2. + (y-y0)**2.)
dg_dr0 = - 1/width
dg_dw0 = g * -1/width
dz_dB = 1.
dz_dA = z / amplitude
dz_dx0 = -2 * z * g**3 * dg_dx0
dz_dy0 = -2 * z * g**3 * dg_dy0
dz_dr0 = -2 * z * g**3 * dg_dr0
dz_dw0 = -2 * z * g**3 * dg_dw0
return [dz_dB, dz_dA, dz_dx0, dz_dy0, dz_dr0, dz_dw0]
但它返回“ValueError:用序列设置数组元素。”
我现在非常绝望。有谁能提出一些可能的解决方案或者在python中实现环高斯拟合的替代方法?
非常感谢~~~
答案 0 :(得分:2)
您的实施正常(我没有尝试或检查您的fit_deriv
实施)。
问题在于您的拟合不会收敛,因为初始模型参数与真值相差太远,因此优化器失败。当我运行你的代码时,我收到了这个警告:
WARNING: The fit may be unsuccessful; check fit_info['message'] for more information. [astropy.modeling.fitting]
如果更改模型参数以使模型与数据大致匹配,则拟合成功:
p_init = ringGaussian(x0=11, y0=11)
要检查模型与数据的比较方式,您可以使用imshow
显示数据和模型图像(或者还有残差图像):
plt.imshow(z)
plt.imshow(p_init(xx,yy))
plt.imshow(p(xx,yy))