scipy.optimize.curve_fit报TypeError参数超数据量问题排查
问题定位
你触发报错的核心原因是scipy.optimize.curve_fit的输入格式不符合要求:
curve_fit默认要求待拟合函数返回一维数组,同时传入的目标值也必须是相同长度的一维数组- 你当前的
px_to_mm_v4返回的是(x坐标数组, y坐标数组)的二元组,curve_fit会误判你只有2个数据点(也就是报错里的M=2),远少于要优化的7个参数,因此触发参数数量不匹配的错误。
另外你代码里的2D点旋转公式存在笔误,y坐标旋转的计算式第一个三角函数项应该是math.sin,而非math.cos,如果不修正会导致拟合结果完全偏离预期。
修复后完整代码
from scipy import optimize import numpy as np import math def px_to_mm_v4(coords, cf_x, cf_y, nudge_x, nudge_y, center_x, center_y, rotate_degrees): ## set lower left loc ll_x = center_x - (127.76/2/cf_x) ## lower left x location in pixels ll_y = center_y + (85.47/2/cf_y) ## lower left y location in pixels ## unpack coordinates x,y = coords ## rotate points around center rotate_radians = math.radians(rotate_degrees) x_rotated = center_x + math.cos(rotate_radians) * (x - center_x) - math.sin(rotate_radians) * (y - center_y) # 修正旋转公式的笔误,第一项改为sin y_rotated = center_y + math.sin(rotate_radians) * (x - center_x) + math.cos(rotate_radians) * (y - center_y) ## convert px to mm x_converted = (x_rotated - ll_x) * cf_x + nudge_x y_converted = (ll_y - y_rotated) * cf_y + nudge_y # 把返回值打平为一维数组,适配curve_fit要求 return np.ravel([x_converted, y_converted]) x_px = np.array([1723,1530,1334,1135,943,747,548,2520,2322,2120,1921,1726,1530,1331,1132,937,741,545,346,349,352,355,358,358,361,361,148]) y_px = np.array([596,791,986,1176,1373,1569,1769,1973,1967,1967,1964,1962,1964,1967,1967,1967,1962,1964,1967,1769,1569,1373,1178,986,791,602,2162]) x_mm = np.array([80,70,60,50,40,30,20,120,110,100,90,80,70,60,50,40,30,20,10,10,10,10,10,10,10,10,0]) y_mm = np.array([80,70,60,50,40,30,20,10,10,10,10,10,10,10,10,10,10,10,10,20,30,40,50,60,70,80,0]) test_coords_tup = (x_px,y_px) # 目标值也打平为一维数组,和函数返回值长度一致(27*2=54个数据点,远大于7个待优化参数) points_to_fit = np.ravel([x_mm, y_mm]) cf_x_test = 0.05072 cf_y_test = 0.05076 nudge_x_test = -2.2 nudge_y_test = 2.1 center_x_test = 1374 center_y_test = 1290 rotate_degrees_test = 1.4 params0 = [cf_x_test,cf_y_test,nudge_x_test,nudge_y_test,center_x_test,center_y_test,rotate_degrees_test] popt, pcov = optimize.curve_fit(px_to_mm_v4, test_coords_tup, points_to_fit, p0=params0) # 输出优化后的参数 print("优化后参数:", popt)
内容的提问来源于stack exchange,提问作者cbcbcbc
相关产品推荐
相关产品推荐

