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

问题描述

我正在尝试将2D高斯拟合到某些由2D数组给出的灰度图像数据上。
lmfit库实现了一个易于使用的Model类,应该能够做到这一点。
不幸的是,文档()仅提供一维拟合的示例。对于我来说,我只是用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:函数调用不是正确的float数组。

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

我真的不明白这是什么意思,因为值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)

Anf最后在这里将此拟合函数称为:

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

展平您要适合的2D输入数组:

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

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

修改两个1D 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:拟合2D模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-28 03:02
查看更多