質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

5259閲覧

Python3, curve_fitによる2次元画像データのガウシアンフィッティング

oknd1

総合スコア17

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2017/08/31 10:00

編集2017/09/01 02:36

###前提・実現したいこと
Python3とscipy.optimize.curve_fitを用いて二次元画像データからガウシアンフィッティングを行いたいのですが,

Result from function call is not a proper array of floats.

のエラーメッセージの対処がわからず困っています。
対処法をお教えくださると幸いです。

画像データ
###該当のソースコード

Python

1import numpy as np 2from PIL import Image as pil 3import matplotlib.pyplot as plt 4from scipy.optimize import curve_fit 5 6data = np.array(pil.open("figs/image.png")) 7data = data/np.max(data) 8 9x,y=np.meshgrid(np.linspace(0,data.shape[1],data.shape[1]),np.linspace(0,data.shape[0],data.shape[0])) 10 11def twoDgaussian(X,wx,wy,x0,y0): 12 x,y=X 13 z=np.exp(-(x-x0)**2/wx**2-(y-y0)**2/wy**2) 14 return z 15 16initial=(50,50,500,500) 17 18popt,pcov=curve_fit(twoDgaussian,(x,y),data,initial)

###発生している問題・エラーメッセージ

------------------------------------------------------------------------- ValueError Traceback (most recent call last) ValueError: object too deep for desired array ------------------------------------------------------------------------- error Traceback (most recent call last) <ipython-input-133-8afc316156ee> in <module>() ----> 1 popt,pcov=curve_fit(twoDgaussian,(x,y),data,initial) C:\Users\***\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs) 734 # Remove full_output from kwargs, otherwise we're passing it in twice. 735 return_full = kwargs.pop('full_output', False) --> 736 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs) 737 popt, pcov, infodict, errmsg, ier = res 738 cost = np.sum(infodict['fvec'] ** 2) C:\Users\***\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag) 385 maxfev = 200*(n + 1) 386 retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol, --> 387 gtol, maxfev, epsfcn, factor, diag) 388 else: 389 if col_deriv: error: Result from function call is not a proper array of floats.

###追加点

def twoDgaussian(X,wx,wy,x0,y0): x,y=X z=np.exp(-(x-x0)**2/wx**2-(y-y0)**2/wy**2) return z.ravel() initial=(50,50,500,500) data_ravel=data.ravel() popt,pcov=curve_fit(twoDgaussian,(x,y),data_ravel,initial)

とすることで通るようになったものの、出力結果が
popt=array([ 1.05774768e+00, 1.23219802e-02, 5.00141975e+02, 5.00041068e+02])
でwxとwyは同程度のはずなのでまだおかしい。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/08/31 10:21

どの変数が適切なfloatになっていないか呈示できそうでしょうか?何行目の何がどうこう、というエラーメッセージが表示されていなさそうという理由です。
oknd1

2017/08/31 10:30

すみません。表示されているメッセージとしては他にないのではっきりとわからないのですが、関数twoDgaussianの出力のことを指していると思います。ただ、この関数の出力は確認するとfloatのarrayになっているようでした。
退会済みユーザー

退会済みユーザー

2017/08/31 12:57 編集

Q.1 curve_fit(以下略)で twoDgaussian(X,wx,wy,x0,y0) を呼び出す際に、twoDgaussian()の引数が省略されているのはこれで大丈夫でしょうか? Q.2 差し支えなければimage.pngをアップロードしてください
oknd1

2017/08/31 13:52

アップロードしました。引数の省略ですが、チュートリアルなどでも省略しているのと、一変数関数のフィッティングを試してみて問題なく通ったことからそこは問題ないと思います。第一引数を独立変数として扱ってそれ以外はパラメータとして扱われるようです。
guest

回答1

0

ベストアンサー

完成形がよく分からないので、回答でありながら確認になってしまいますが、
以下のコード添付の画像で動くようにするイメージでしょうか?

Stackoverflowのコードを動くようにしただけですが...

イメージ

Python

1import scipy.optimize as opt 2import numpy as np 3import pylab as plt 4from PIL import Image as pil 5 6#define model function and pass independant variables x and y as a list 7def twoD_Gaussian(XY, amplitude, xo, yo, sigma_x, sigma_y, theta, offset): 8 x,y = XY[0:2] 9 xo = float(xo) 10 yo = float(yo) 11 a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2) 12 b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2) 13 c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2) 14 g = offset + amplitude*np.exp( - (a*((x-xo)**2) + 2*b*(x-xo)*(y-yo) 15 + c*((y-yo)**2))) 16 return g.ravel() 17 18 19# Create x and y indices 20x = np.linspace(0, 200, 201) 21y = np.linspace(0, 200, 201) 22x, y = np.meshgrid(x, y) 23 24#create data 25data = twoD_Gaussian((x, y), 3, 100, 100, 20, 40, 0, 10) 26 27 28# plot twoD_Gaussian data generated above 29plt.figure() 30plt.imshow(data.reshape(201, 201)) 31plt.colorbar() 32 33# add some noise to the data and try to fit the data generated beforehand 34initial_guess = (3,100,100,20,40,0,10) 35 36data_noisy = data + 0.2*np.random.normal(size=data.shape) 37 38popt, pcov = opt.curve_fit(twoD_Gaussian, (x, y), data_noisy, p0=initial_guess) 39 40data_fitted = twoD_Gaussian((x, y), *popt) 41 42fig, ax = plt.subplots(1, 1) 43ax.hold(True) 44ax.imshow(data_noisy.reshape(201, 201), cmap=plt.cm.jet, origin='bottom', 45 extent=(x.min(), x.max(), y.min(), y.max())) 46ax.contour(x, y, data_fitted.reshape(201, 201), 8, colors='w') 47plt.show() 48

投稿2017/08/31 22:55

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

oknd1

2017/09/01 02:31

slash様 まさにそうです。ただstackoverflowの提示していただいたページは参照にしていたもののpython2.7系とpython3系で微妙に違いがあるようで苦戦していました。 先程ravel()を適宜加えることで通るようにはなったのですが、まだ出力結果がおかしい状態です。 ありがとうございます。
oknd1

2017/09/01 03:00

出力結果がおかしいといった話でしたが、別にテストデータを生成して確認してみたところ問題ないようでしたのでフィッティングの流れとしてはこれで問題ないようです。 ほぼ解決しましたありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問