2

我正在尝试将 2D-Gaussian 拟合到由一个 2D 数组给出的一些灰度图像数据。lmfit 库实现了一个易于使用的模型类,它应该能够做到这一点。不幸的是,文档(http://lmfit.github.io/lmfit-py/model.html)只提供了一维拟合的示例。就我而言,我只是用 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 终于在这里调用了这个 fit 函数:

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

2 回答 2

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
于 2015-04-16T16:08:12.620 回答
0

好的,与开发人员一起写信并从他们那里得到答案(感谢 Matt here)。

基本思想是将所有输入展平为一维数据,对 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)
于 2014-10-24T01:41:41.320 回答