Pythonでのガウシアンフィッティングで以下の画像のような出力結果が得られました。この時グラフだけではなくて、フィッティングして得たそれぞれのピークの位置座標をリストに入れて出力したいです。[ピーク1,ピーク2,ピーク3]といった感じです。
グラフ上に記載する必要はなく、terminal上にprintできれば十分です。
詳しい方お力をお借りしたいです。
コードは以下です。
Python
1from scipy.optimize import curve_fit 2import numpy as np 3import matplotlib.pyplot as plt 4import matplotlib.cm as cm 5import pandas as pd 6import cv2 7 8img = cv2.imread('convert.png', 0) 9img_split = np.split(img, 36) 10 11x=list(range(1500)) 12y=np.sum(img_split[0],axis=0) 13 14def func(x, *params): 15 16 #paramsの長さでフィッティングする関数の数を判別。 17 num_func = int(len(params)/3) 18 19 #ガウス関数にそれぞれのパラメータを挿入してy_listに追加。 20 y_list = [] 21 for i in range(num_func): 22 y = np.zeros_like(x) 23 param_range = list(range(3*i,3*(i+1),1)) 24 amp = params[int(param_range[0])] 25 ctr = params[int(param_range[1])] 26 wid = params[int(param_range[2])] 27 y = y + amp * np.exp( -((x - ctr)/wid)**2) 28 y_list.append(y) 29 30 #y_listに入っているすべてのガウス関数を重ね合わせる。 31 y_sum = np.zeros_like(x) 32 for i in y_list: 33 y_sum = y_sum + i 34 35 #最後にバックグラウンドを追加。 36 y_sum = y_sum + params[-1] 37 38 return y_sum 39 40def fit_plot(x, *params): 41 num_func = int(len(params)/3) 42 y_list = [] 43 for i in range(num_func): 44 y = np.zeros_like(x) 45 param_range = list(range(3*i,3*(i+1),1)) 46 amp = params[int(param_range[0])] 47 ctr = params[int(param_range[1])] 48 wid = params[int(param_range[2])] 49 y = y + amp * np.exp( -((x - ctr)/wid)**2) + params[-1] 50 y_list.append(y) 51 return y_list 52 53#初期値のリストを作成 54#[amp,ctr,wid] 55guess = [] 56guess.append([2500, 464, 170]) 57guess.append([2400, 1000, 100]) 58guess.append([2100, 1300, 100]) 59#バックグラウンドの初期値 60background = 0 61 62#初期値リストの結合 63guess_total = [] 64for i in guess: 65 guess_total.extend(i) 66guess_total.append(background) 67 68popt, pcov = curve_fit(func, x, y, p0=guess_total) 69 70fit = func(x, *popt) 71plt.scatter(x, y, s=20) 72plt.plot(x, fit , ls='-', c='black', lw=1) 73 74y_list = fit_plot(x, *popt) 75baseline = np.zeros_like(x) + popt[-1] 76for n,i in enumerate(y_list): 77 plt.fill_between(x, i, baseline, facecolor=cm.rainbow(n/len(y_list)), alpha=0.6) 78 79plt.show() 80 81コード
「def func(x, *params):」内の「for i in range(num_func):」のループの
y = y + amp * np.exp( -((x - ctr)/wid)**2)
の「ctr」が、各ピークの横軸の値だと思うので、そのforループの最後に
print(ctr)
を追加して実行したら、各ピークの横軸の値が表示されませんか?
jbpb0様
回答誠にありがとうございます!
指摘していただいた通り、print(ctr)を加えたところ、ctrの値は得られました!
ただ、最適なctrの値が得られるまで経たctrの値が全てprintされる形となりました。以下のような感じです
464
1000
1300
464.0
1000.0
1300.0
・
・
・
465.3400467007296
989.5366921257119
1318.6099804641717
この最後の3つのみを出力できれば良いのですが、結果をリストに入れて後ろから3つを取り出せば良いのかなと思い色々試しているのですが、上手くいきません。。。
それでしたら、「def func(x, *params):」ではなく、「def fit_plot(x, *params):」内のforループの最後に追加してみてください
できました!ありがとうございます!

回答1件
あなたの回答
tips
プレビュー