我正在尝试将2-d voigt轮廓拟合到图像的一个子部分(赋予),其中position是一个数组,在整个图像中保存相应的x和y坐标以供传递。
根据两个打印语句的输出,以下代码在我看来应该是真的应该工作。
另外,如果有人对如何更快地构建位置数组有任何快速建议,我会很感激numpy ndarrays的一些建议。我对他们来说还是有点新鲜。
import numpy as np
from scipy.special import wofz
from scipy.optimize import curve_fit
from math import pi
def voigt2d(pos,a,bx,by,Gc,Lc):
val = np.zeros((5,5))
for y in range(5):
for x in range(5):
dst = np.sqrt((pos[y][x][0]-bx)**2+(pos[y][x][1]-by)**2)
z = ((dst+(Lc*1j))/(Gc*np.sqrt(2)))
val[y][x] = a*wofz(z).real/(Gc*np.sqrt(2*pi))
print val
print val.dtype
return val
x = np.arange(93,98)
y = np.arange(7,12)
xpos = np.array([x,x,x,x,x])
ypos = np.array([y,y,y,y,y])
ypos = np.rot90(ypos,k=3)
position = np.dstack((xpos,ypos))
impart = np.array([
[971, 2425, 4331, 4280, 2697,],
[1199, 3416, 6517, 4813, 2412],
[1333, 3957, 7210, 4019, 2183],
[1494, 4115, 4817, 3085, 1758],
[1185, 2273, 2805, 2811, 1797]
],dtype=np.float64)
p,cov = curve_fit(voigt2d,position,impart)
答案 0 :(得分:2)
我不确定这会为你解决,但我相信你的问题与curve_fit
期望你的模型函数返回一维模型数据的事实有关。因此,最简单的方法是将自变量(position
)表示为一维数组:
>>> x = np.arange(93,98)
>>> y = np.arange(7,12)
>>> position = np.transpose([np.tile(x, len(x)), np.repeat(y, len(y))])
>>> position
array([[93, 7],
[94, 7],
[95, 7],
[96, 7],
[97, 7],
[93, 8],
[94, 8],
[95, 8],
[96, 8],
[97, 8],
[93, 9],
[94, 9],
[95, 9],
[96, 9],
[97, 9],
[93, 10],
[94, 10],
[95, 10],
[96, 10],
[97, 10],
[93, 11],
[94, 11],
[95, 11],
[96, 11],
[97, 11]])
然后你必须调整模型函数以适应这个新数组。
答案 1 :(得分:2)
关于你的第二个问题,numpy中有一个方便的网格构造函数:
y,x = pos = np.mgrid[7:12,93:98]
将完全返回您手工构建的数组。 还要注意,numpy允许整个数组之间的操作而不仅仅是标量,消除了对voigt2d内部的两个循环的需要:
def voigt2d(pos,a,bx,by,Gc,Lc):
y,x = pos
dst = np.sqrt((x-bx)**2+(y-by)**2)
z = ((dst+(Lc*1j))/(Gc*np.sqrt(2)))
val = a*wofz(z).real/(Gc*np.sqrt(2*pi))
正如Bhajun所说,curve_fit需要1D数组,所以你需要压扁结果:
return np.ravel(val)
希望有所帮助。