我正在做一个项目,在这个项目中,我试图对kymograph中对象的运动进行建模。为了做到这一点,我将一条曲线拟合到图像中的每一行像素,并附加顶点的位置来近似模拟图像中对象的位置。下面是一个示例图像。
正如您所看到的,在时间序列的早期(在图像的顶部),对象的位置被很好地聚焦,并且很容易用高斯曲线建模。然而,更接近时间序列的结尾(在图像的底部),峰值更具漫射性。我怀疑图像底部的数据将由泊松分布(下图,右图)曲线拟合得更接近,而图像顶部/中间的数据将由高斯或多项式曲线(下图,左图)拟合得更紧密。
有没有办法,对于每一行像素,将多条曲线拟合到相同的数据,然后对每条曲线进行最小二乘拟合?这样,我可以(希望)在图像中途切换模型,以适应我试图跟踪的对象不断变化的行为。我当前的代码如下:
from PIL import Image
def populateData(picture) :
"""Open an image and populate a list of lists with the grayscale value"""
im = Image.open(picture)
size = im.size
width = size[0]
height = size[1]
allPixels = list(im.getdata())
pixelList = [allPixels[width*i :
width * (i+1)] for i in range(height)]
return(pixelList)
rawData = populateData("testTop.tif")
import numpy as np
from scipy.optimize import curve_fit
def findVertex(listOfRows) :
xList = []
for row in listOfRows :
x = np.arange(len(row))
ffunc = lambda x, a, x0, s: a*np.exp(-0.5*(x-x0)**2/s**2)
p, _ = curve_fit(ffunc, x, row, p0=[100,5,2])
x0 = p[1]
xList.append(x0)
xArray = np.array(xList)
return(xArray)
xValues = findVertex(rawData)
def buildRows(listOfRows) :
yArray = np.arange(len(listOfRows))
return(yArray)
yValues = buildRows(rawData)
from matplotlib import pyplot as plt
from scipy import ndimage
image = ndimage.imread("testTop.tif",flatten=True)
fig = plt.figure()
axes = fig.add_subplot(111)
axes.imshow(image)
axes.plot(xValues, yValues, 'k-')
axes.set_title('testLine')
axes.grid()
axes.set_xlabel('x')
axes.set_ylabel('time')
plt.show()
编辑:这是我用作输入的文件(testTop.tif)
发布于 2015-06-02 07:38:28
你需要在fit和你的数据之间建立某种形式的goodness of fit。取当前拟合(高斯)和数据之间的平方差之和除以方差。
sumerrsq = 0.
for i in range(yValues.shape[0]):
sumerrsq += np.power(yValues[i] - xValues[i],2)
goodfit = np.sqrt(sumerrsq/var)
我认为你可以使用曲线拟合的第二个输出(协方差)来获得方差,
p, pcov = curve_fit(ffunc, x, row, p0=[100,5,2])
var = np.diag(pcov)
然后,您可以检查goodfit的值,如果该值不够,则切换到不同的发行版。在使用不同的分布时,您可能需要使用不同的误差估计(假设误差是正态分布的)。
注意,没有数据(并且不确定是哪个数组),我无法测试这些代码中的任何一个……
发布于 2015-06-02 07:38:44
据the curve_fit
docs报道
使用perr = np.sqrt(np.diag(pcov))
计算参数上的1个标准差的
。
因此,如果这是您试图比较的值,那么您可以从curve_fit
(当前赋值给_
的值)中获取第二个返回值,使用它来计算perr
,并比较多条曲线之间的误差。
发布于 2015-06-02 07:50:12
我建议您使用2D拟合模型。一维高斯分布是基础,但均值和方差取决于位置和时间。然后,将模型与2d图像数据进行拟合。
如果你想继续使用你的方法,它看起来只是均值和方差的起始值,你需要调整它,以便更好地拟合时间较长的线。
对于你的问题,你可以模拟任何你想要的分数函数,所以你可以这样做:
def score(x,y):
if x < 10:
return x**2 - y
else:
return x - y
因此,为了在不同的范围内使用两个不同的模型,请遵循以下示例。
https://stackoverflow.com/questions/30589640
复制相似问题