Python: mapping curve to integer
I have a list of integers.
intList = [96, 98, 120, 163, 158, 166, 201, 201, 159, 98, 93, 73, 77, 72]
These numbers represent the gray values of the 14px band, I would like to fit the curve to the distribution and keep the x location of the vertex.
For context: I am actually working with (much larger) lists of lists, each containing a gray value of a pixel string from an image. For each row of pixels, I would like to plot a curve for the data and add the x-location of the vertex to the growing list. Each row of pixels will have some noise, but one and only one wide, clear peak in pixel intensity (sample image below)
I have NumPy, SciPy, matplotlib, and pillow, but I don't know very much about the many functions found inside each. Can anyone point me to a module or functions that can do this?
source to share
To set a polynomial eg. quadratic, use polyfit
:
from pylab import *
x = arange(len(intList))
p = polyfit(x, intList, 2)
a, b, c = p
x0 = -0.5*b/a # x coordinate of vertex
# plot
x = arange(len(intList))
plot(x, intList)
plot(x, polyval(p, x))
axvline(x0, color='r', ls='--')
To install a more complex function, eg. gaussian, you can use curve_fit
:
from scipy.optimize import curve_fit
# define function to fit
ffunc = lambda x, a, x0, s: a*exp(-0.5*(x-x0)**2/s**2)
# fit with initial guess a=100, x0=5, s=2
p, _ = curve_fit(ffunc, x, intList, p0=[100,5,2])
x0 = p[1] # location of the mean
# plot
plot(x, intList)
plot(x, ffunc(x, *p))
axvline(x0, color='r', ls='--')
(Although for a Gaussian fit, you're probably better off calculating the mean and variance of the distribution.)
source to share