2

1 つの 2D 配列によって与えられるグレースケール画像データに 2D-Gaussian を当てはめようとしています。lmfit ライブラリは、これを実行できる使いやすい Model クラスを実装しています。残念ながら、ドキュメント ( http://lmfit.github.io/lmfit-py/model.html ) は 1D フィッティングの例しか提供していません。私の場合、2 つの独立変数を使用して lmfit モデルを構築するだけです。

次のコードは私には有効に思えますが、scipy が「minpack.error: 関数呼び出しの結果は浮動小数点数の適切な配列ではありません」をスローします。

トムはそれを要約します: 2D (x1,x2)->(y) データを lmfit のモデルに入力する方法.?

これが私のアプローチです。すべてが GaussianFit2D クラスにパックされていますが、重要な部分は次のとおりです。それがガウス関数です。ドキュメントには、ユーザー定義関数について書かれています

もちろん、モデル関数は、モデル化されているデータと同じサイズの配列を返す必要があります。通常、これは 1 つ以上の独立変数も指定することによって処理されます。

与えられた値 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

わかりました、開発者と一緒に書いて、彼らから答えを得ました (ここで Matt に感謝します)。

基本的な考え方は、1 次元以上の入力を lmfit から隠して、すべての入力を 1D データに平坦化することです。方法は次のとおりです。関数を変更します。

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

適合させたい 2D 入力配列を平坦化します。

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

任意の組み合わせになるように、2 つの 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 に答える
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 に答える