First read the image through
from scipy.misc import imread im = imread("thefile.png")
This gives a 3D numpy array, and the third size is the color channels (RGB + alpha). The curve is in the blue channel, but there is also a grid. But in the red channel you have a grid, not a curve. Therefore we use
a = im[:,:,2] - im[:,:,0]
Now we need a maximum position along each column. Up to one pixel, it is set
y0 = np.argmax(a, axis=0)
The result of this is zero when there is no blue curve in the column, that is, outside the frame. On can get the frame limits on
xmin, xmax = np.where(y0>0)[0][[0,-1]
In doing so, you can rescale the x axis.
Then you want subpixel resolution. Let's focus on one column
f=a[:,x]
We use one iteration of Newton's method to refine the position of extrema
y1 = y0 - f'[y]/f''[y]
Please note that we cannot continue the iteration due to discrete sampling. However, we need a good approximation of the derivatives, so we will use a 5-point scheme for both.
coefprime = np.array([1,-8, 0, 8, -1], float) coefsec = np.array([-1, 16, -30, 16, -1], float) y1 = y0 - np.dot(f[y0-2:y0+3], coefprime)/np.dot(f[y0-2:y0+3], coefsec)
PS: Thorsten Kranz was faster than me (at least here), but my answer has subpixel accuracy, and my way of highlighting the blue curve is probably more clear.