python - Scipy leastsq: fitting a square grid to experimental points in 2D -
i'm trying use scipy leastsq
find best fit of "square" grid set of measured points coordinates in 2-d (the experimental points approximately on square grid).
the parameters of grid pitch (equal x , y), center position (center_x
, center_y
) , rotation
(in degree).
i defined error function calculating euclidean distance each pairs of points (experimental vs ideal grid) , taking mean. want minimize function thorugh leastsq
error.
here function definitions:
import numpy np scipy.optimize import leastsq def get_spot_grid(shape, pitch, center_x, center_y, rotation=0): x_spots, y_spots = np.meshgrid( (np.arange(shape[1]) - (shape[1]-1)/2.)*pitch, (np.arange(shape[0]) - (shape[0]-1)/2.)*pitch) theta = rotation/180.*np.pi x_spots = x_spots*np.cos(theta) - y_spots*np.sin(theta) + center_x y_spads = x_spots*np.sin(theta) + y_spots*np.cos(theta) + center_y return x_spots, y_spots def get_mean_distance(x1, y1, x2, y2): return np.sqrt((x1 - x2)**2 + (y1 - y2)**2).mean() def err_func(params, xe, ye): pitch, center_x, center_y, rotation = params x_grid, y_grid = get_spot_grid(xe.shape, pitch, center_x, center_y, rotation) return get_mean_distance(x_grid, y_grid, xe, ye)
this experimental coordinates:
xe = np.array([ -23.31, -4.01, 15.44, 34.71, -23.39, -4.10, 15.28, 34.60, -23.75, -4.38, 15.07, 34.34, -23.91, -4.53, 14.82, 34.15]).reshape(4, 4) ye = np.array([-16.00, -15.81, -15.72, -15.49, 3.29, 3.51, 3.90, 4.02, 22.75, 22.93, 23.18, 23.43, 42.19, 42.35, 42.69, 42.87]).reshape(4, 4)
i try use leastsq
in way:
leastsq(err_func, x0=(19, 12, 5, 0), args=(xe, ye))
but following error:
--------------------------------------------------------------------------- typeerror traceback (most recent call last) <ipython-input-19-ee91cf6ce7d6> in <module>() ----> 1 leastsq(err_func, x0=(19, 12, 5, 0), args=(xe, ye)) c:\anaconda\lib\site-packages\scipy\optimize\minpack.pyc in leastsq(func, x0, args, dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag) 369 m = shape[0] 370 if n > m: --> 371 raise typeerror('improper input: n=%s must not exceed m=%s' % (n, m)) 372 if epsfcn none: 373 epsfcn = finfo(dtype).eps typeerror: improper input: n=4 must not exceed m=1
i can't figure out what's problem here :(
since leastsq function assumes err_function return array of residuals docs , little difficult write err_function in manner why not use scipy's function - minimize. add metric - error function have , works. however, think there 1 more typo in get_spot_grid function (y_spots vs y_spads). complete code:
import numpy np scipy.optimize import leastsq, minimize def get_spot_grid(shape, pitch, center_x, center_y, rotation=0): x_spots, y_spots = np.meshgrid( (np.arange(shape[1]) - (shape[1]-1)/2.)*pitch, (np.arange(shape[0]) - (shape[0]-1)/2.)*pitch) theta = rotation/180.*np.pi x_spots = x_spots*np.cos(theta) - y_spots*np.sin(theta) + center_x y_spots = x_spots*np.sin(theta) + y_spots*np.cos(theta) + center_y return x_spots, y_spots def get_mean_distance(x1, y1, x2, y2): return np.sqrt((x1 - x2)**2 + (y1 - y2)**2).mean() def err_func(params, xe, ye): pitch, center_x, center_y, rotation = params x_grid, y_grid = get_spot_grid(xe.shape, pitch, center_x, center_y, rotation) return get_mean_distance(x_grid, y_grid, xe, ye) xe = np.array([-23.31, -4.01, 15.44, 34.71, -23.39, -4.10, 15.28, 34.60, -23.75, -4.38, 15.07, 34.34, -23.91, -4.53, 14.82, 34.15]).reshape(4, 4) ye = np.array([-16.00, -15.81, -15.72, -15.49, 3.29, 3.51, 3.90, 4.02, 22.75, 22.93, 23.18, 23.43, 42.19, 42.35, 42.69, 42.87]).reshape(4, 4) # leastsq(err_func, x0=(19, 12, 5, 0), args=(xe, ye)) minimize(err_func, x0=(19, 12, 5, 0), args=(xe, ye))
Comments
Post a Comment