【问题标题】:Python lmfit: Fitting a 2D ModelPython lmfit:拟合二维模型
【发布时间】:2014-12-17 14:47:33
【问题描述】:

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

以下代码对我来说似乎有效,但会导致 scipy 抛出“minpack.error: 函数调用的结果不是正确的浮点数组。”

Tom 总结一下:如何将 2D (x1,x2)->(y) 数据输入到 lmfit 的 Model 中?

这是我的方法: 一切都打包在一个 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])

【问题讨论】:

  • 您需要lmfit,还是其他工具(来自scipy 的curve_fitleastsq)也可以?
  • lmfit 很迷人,因为它很容易为参数、约束等添加初始化值......如果我不能让它工作,scipy 可能是接下来要尝试的东西。

标签: python 2d lmfit


【解决方案1】:
好吧,用devs写作,从这里得到答案(谢谢这里)。

基本思想是将所有输入达到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)

【讨论】:

    【解决方案2】:

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

    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
    

    【讨论】:

    • 解释你的答案也会有所帮助。
    猜你喜欢
    • 2019-02-08
    • 2014-06-18
    • 2018-11-07
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    相关资源
    最近更新 更多