我正在尝试将2D高斯拟合到一些灰度图像数据,这是由一个2D数组给出的。 lmfit库实现了一个易于使用的Model类,它应该能够做到这一点。 遗憾的是,文档(http://lmfit.github.io/lmfit-py/model.html)仅提供了1D拟合的示例。对于我的情况,我只是用2个独立变量构造lmfit模型。
以下代码似乎对我有用,但会导致scipy抛出“minpack.error:函数调用的结果不是一个正确的浮点数组。”
Tom总结一下:如何将2D(x1,x2) - >(y)数据输入到lmfit模型中。?
这是我的方法: 所有内容都包含在GaussianFit2D类中,但以下是重要部分: 那是高斯函数。文档说明了用户定义的函数
当然,模型函数必须返回一个与建模数据大小相同的数组。通常,这也可以通过指定一个或多个自变量来处理。
我真的不明白这应该是什么意思,因为对于给定的值x1,x2,唯一合理的结果是标量值。
def _function(self, x1, x2, amp, wid, cen1, cen2):
val = (amp/(np.sqrt(2*np.pi)*wid)) * np.exp(-((x1-cen1)**2+(x2-cen2)**2)/(2*wid**2))
return val
此处生成模型:
def _buildModel(self, **kwargs):
model = lmfit.Model(self._function, independent_vars=["x1", "x2"],
param_names=["amp", "wid", "cen1", "cen2"])
return model
这是获取数据的函数,构建模型和参数并调用lmfit fit():
def fit(self, data, freeX, **kwargs):
freeX = np.asarray(freeX, float)
model = self._buildModel(**kwargs)
params = self._generateModelParams(model, **kwargs)
model.fit(data, x1=freeX[0], x2=freeX[1], params=params)
Anf终于在这里调用了这个拟合函数:
data = np.asarray(img, float)
gaussFit = GaussianFit2D()
x1 = np.arange(len(img[0, :]))
x2 = np.arange(len(img[:, 0]))
fit = gaussFit.fit(data, [x1, x2])
答案 0 :(得分:0)
好的,和开发人员一起写了并得到了答案(感谢Matt在这里)。
基本思想是将所有输入展平为1D数据,从lmfit中隐藏> 1维输入。 这是你怎么做的。 修改你的功能:
def function(self, x1, x2):
return (x1+x2).flatten()
展平您想要适合的2D输入数组:
...
data = data.flatten()
...
修改两个1D x变量,使其具有任意组合:
...
x1n = []
x2n = []
for i in x1:
for j in x2:
x1n.append(i)
x2n.append(j)
x1n = np.asarray(x1n)
x2n = np.asarray(x2n)
...
把任何东西扔进钳工:
model.fit(data, x1=x1n, x2=x2n, params=params)
答案 1 :(得分:0)
以下是供您参考的示例,希望它可以为您提供帮助。
import numpy
from lmfit import Model
def gaussian(x, cenu, cenv, wid):
u = x[:, 0]
v = x[:, 1]
return (1/(2*numpy.pi*wid**2)) * numpy.exp(-(u-cenu)**2 / (2*wid**2)-(v-cenv)**2 / (2*wid**2))
data = numpy.empty((25,3))
x = numpy.arange(-2,3,1)
y = numpy.arange(-2,3,1)
xx, yy = numpy.meshgrid(x, y)
data[:,0] = xx.flatten()
data[:,1] = yy.flatten()
data[:, 2]= gaussian(data[:,0:2],0,0,0.5)
print 'xx\n', xx
print 'yy\n',yy
print 'data to be fit\n', data[:, 2]
cu = 0.9
cv = 0.5
wid = 1
gmod = Model(gaussian)
gmod.set_param_hint('cenu', value=cu, min=cu-2, max=cu+2)
gmod.set_param_hint('cenv', value=cv, min=cv -2, max=cv+2)
gmod.set_param_hint('wid', value=wid, min=0.1, max=5)
params = gmod.make_params()
result = gmod.fit(data[:, 2], x=data[:, 0:2], params=params)
print result.fit_report(min_correl=0.25)
print result.best_values
print result.best_fit