Python lmfit:拟合二维模型 [英] Python lmfit: Fitting a 2D Model

查看:40
本文介绍了Python lmfit:拟合二维模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to fit a 2D-Gaussian to some greyscale image data, which is given by one 2D array. The lmfit library implements a easy-to-use Model class, that should be capable of doing this. Unfortunately the documentation (http://lmfit.github.io/lmfit-py/model.html) does only provide examples for 1D fitting. For my case I simply construct the lmfit Model with 2 independent variables.

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

The following code seems valid for me, but causes scipy to throw a "minpack.error: Result from function call is not a proper array of floats."

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

Tom sum it up: How to input 2D (x1,x2)->(y) data to a Model of lmfit.?

这是我的方法:一切都打包在 GaussianFit2D 类中,但这里是重要的部分:这就是高斯函数.文档说明了用户定义的函数

Here is my approach: Everything is packed in a GaussianFit2D class, but here are the important parts: That's the Gaussian function. The documentation says about user defined functions

当然,模型函数必须返回一个与被建模数据大小相同的数组.通常,这也是通过指定一个或多个自变量来处理的.

Of course, the model function will have to return an array that will be the same size as the data being modeled. Generally this is handled by also specifying one or more independent variables.

我真的不明白这应该意味着什么,因为对于给定的值 x1、x2,唯一合理的结果是标量值.

I don't really get what this should mean, since for given values x1,x2 the only reasonable result is a scalar value.

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() 的函数:

That's the function that takes the data, builds the model and params and calls 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)

终于在这里调用了这个 fit 函数:

Anf finally here this fit function gets called:

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

Ok, wrote with the devs and got the answer from them (thanks to Matt here).

基本思想是将所有输入展平为一维数据,从 lmfit 中隐藏 >1 维输入.这是你如何做到的.修改你的函数:

The basic idea is to flatten all the input to 1D data, hiding from lmfit the >1 dimensional input. Here's how you do it. Modify your function:

 def function(self, x1, x2):
       return (x1+x2).flatten()

展平您想要适合的二维输入数组:

Flatten your 2D input array you want to fit to:

...
data = data.flatten()
...

修改两个一维 x 变量,使它们具有任意组合:

Modify the two 1D x-variables such that you have any combination of them:

...
x1n = []
x2n = []
    for i in x1:
         for j in x2:
              x1n.append(i)
              x2n.append(j)
x1n = np.asarray(x1n)
x2n = np.asarray(x2n)
...

把任何东西都扔给钳工:

And throw anything into the fitter:

model.fit(data, x1=x1n, x2=x2n, params=params)

这篇关于Python lmfit:拟合二维模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆