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)

the image from which I am extracting data

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?

+3


source to share


1 answer


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='--')

      

quadratic fit

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='--')

      

Gaussian fit

(Although for a Gaussian fit, you're probably better off calculating the mean and variance of the distribution.)

+3


source







All Articles