Python lmfit:拟合2D模型

时间:2014-10-22 07:49:40

标签: python 2d lmfit

我正在尝试将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])

2 个答案:

答案 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