问题描述
我正在尝试将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模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!