Python lmfit:拟合二维模型



我正在尝试将2D高斯拟合到一些灰度图像数据中,这些数据由一个2D阵列给出。lmfit库实现了一个易于使用的Model类,它应该能够做到这一点。遗憾的是,文档(http://lmfit.github.io/lmfit-py/model.html)仅提供了1D拟合的示例。在我的例子中,我简单地用两个自变量构造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()的函数:

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)

最后,这个拟合函数被称为:

    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])

好的,和开发人员一起写了文章,并从他们那里得到了答案(感谢Matt)。

其基本思想是将所有输入平坦化为1D数据,从而隐藏>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)

这里有一个例子供您参考,希望对您有所帮助。

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 'xxn', xx
print 'yyn',yy
print 'data to be fitn', 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

最新更新