一、作用
这是一个曲线 / 圆拟合 + 参数优化的残差函数 ,专门用于最小二乘法优化 (配合 scipy.optimize.least_squares 使用)。
总结功能
同时优化「圆心位置」和「坐标修正系数」,让所有修正后的点精准拟合一个标准圆,同时防止模型过拟合。
典型应用场景:
- 视觉测量 / 工业检测中的圆轮廓拟合
- 传感器数据误差校正
- 精密定位、圆心标定
好处:
-
带正则化,防止过拟合 不会因为过度修正导致模型在新数据上失效,鲁棒性更强。
-
标准残差函数格式 可以直接对接
least_squares等优化库,自动最小化误差,使用极其方便。 -
径向残差物理意义明确直接表示 "点到理想圆的距离误差",符合工程测量需求
二、Code
cpp
# 完整整合版:圆拟合 + 坐标校正 + 正则化优化
import numpy as np
from scipy.optimize import least_squares
# ==============================================
# 1. 全局配置与模拟测量数据(真实使用时替换这里)
# ==============================================
np.random.seed(666) # 固定随机种子,结果可复现
# 真实圆参数(用于生成测试数据)
TRUE_CENTER_X = 2.0
TRUE_CENTER_Z = 3.0
TRUE_RADIUS = 10.0
SAMPLE_POINTS = 60 # 测量点数
# 生成标准圆周点
theta = np.linspace(0, 2 * np.pi, SAMPLE_POINTS)
std_x = TRUE_CENTER_X + TRUE_RADIUS * np.cos(theta)
std_z = TRUE_CENTER_Z + TRUE_RADIUS * np.sin(theta)
# 模拟测量误差(系统误差 + 随机噪声)
sys_error_x = 0.8 * np.cos(theta)
sys_error_z = -0.6 * np.sin(theta)
noise_x = np.random.normal(0, 0.2, SAMPLE_POINTS)
noise_z = np.random.normal(0, 0.2, SAMPLE_POINTS)
# 最终模拟原始测量数据
meas_x = std_x + sys_error_x + noise_x
meas_z = std_z + sys_error_z + noise_z
# 归一化数据
norm_x = meas_x / 15.0
norm_b = meas_z / 15.0
norm_u_const = 1.2
# 优化参数
target_radius = TRUE_RADIUS
lambda_reg = 0.005 # 正则化系数
# ==============================================
# 2. 核心函数(已重命名,语义清晰)
# ==============================================
def split_parameters(param_vec):
"""拆分优化变量:圆心x、圆心z、x修正系数、z修正系数"""
center_x = param_vec[0]
center_z = param_vec[1]
coeff_x = param_vec[2:5]
coeff_z = param_vec[5:8]
return center_x, center_z, coeff_x, coeff_z
def correct_coordinates(x_raw, z_raw, nx, nb, nu, kx, kz):
"""坐标校正模型:修正原始测量坐标"""
corr_x = x_raw + kx[0] * nx + kx[1] * nb + kx[2] * nu
corr_z = z_raw + kz[0] * nx + kz[1] * nb + kz[2] * nu
return corr_x, corr_z
def compute_residual(param_vec):
"""计算残差(拟合误差 + 正则项)"""
# 解包参数
cx, cz, coef_x, coef_z = split_parameters(param_vec)
# 构造归一化常数数组
u_array = np.full_like(norm_x, norm_u_const)
# 坐标校正
x_fit, z_fit = correct_coordinates(meas_x, meas_z, norm_x, norm_b, u_array, coef_x, coef_z)
# 径向残差
radius_calc = np.hypot(x_fit - cx, z_fit - cz)
radial_error = radius_calc - target_radius
# 正则化惩罚项
regularization = np.sqrt(lambda_reg) * np.concatenate([coef_x, coef_z])
# 返回总残差
return np.concatenate([radial_error, regularization])
# ==============================================
# 3. 执行优化拟合
# ==============================================
# 初始参数猜测 [cx, cz, kx1,kx2,kx3, kz1,kz2,kz3]
initial_params = np.zeros(8)
# 最小二乘优化
result = least_squares(compute_residual, initial_params)
# 解析最优结果
fit_cx, fit_cz, fit_coef_x, fit_coef_z = split_parameters(result.x)
# ==============================================
# 4. 输出最终结果
# ==============================================
print("=" * 50)
print(" 圆拟合 + 坐标校正 优化结果")
print("=" * 50)
print(f"真实圆心 X: {TRUE_CENTER_X:.3f} 拟合圆心 X: {fit_cx:.3f}")
print(f"真实圆心 Z: {TRUE_CENTER_Z:.3f} 拟合圆心 Z: {fit_cz:.3f}")
print(f"标准半径: {target_radius} mm")
print("-" * 50)
print(f"X 方向修正系数: {np.round(fit_coef_x, 4)}")
print(f"Z 方向修正系数: {np.round(fit_coef_z, 4)}")
print("-" * 50)
print(f"总残差平方和: {np.sum(result.fun ** 2):.6f}")
print(f"优化状态: {'成功' if result.success else '失败'}")
print("=" * 50)


三、总结
- 功能:圆拟合 + 坐标误差校正 + 正则化防过拟合
- 优势:精度高、鲁棒强、适配标准优化库、物理意义清晰
- 测试代码:可直接运行,验证拟合效果与残差计算