
本文讲解如何通过改进拟合函数(增加偏移项)、合理初始化参数、数据平滑与相位校准,显著提升抖动视频中单摆运动轨迹的余弦拟合质量。
本文讲解如何通过改进拟合函数(增加偏移项)、合理初始化参数、数据平滑与相位校准,显著提升抖动视频中单摆运动轨迹的余弦拟合质量。
在基于视频运动追踪获取的单摆数据中,手抖导致的噪声、传感器漂移及坐标系偏移常使原始数据严重偏离理想余弦模型(如 x(t) = A·cos(ωt))。直接拟合无偏移的纯余弦函数往往导致整体拟合曲线系统性下移(如问题中“fit is way below my data”),根本原因在于忽略了物理系统的静态偏置——例如摄像头未对准平衡点、图像坐标原点偏移或背景亮度漂移引起的直流分量。
✅ 关键改进:引入偏移项(offset)
最基础且有效的修正,是将拟合函数从
def cos_func(times, amplitude, frequency):
return amplitude * np.cos(frequency * times)升级为包含垂直偏移的完整模型:
def cos_func(times, amplitude, frequency, offset):
return amplitude * np.cos(frequency * times) + offset该模型具备三个自由度,能同时拟合振幅、角频率和平衡位置(即 x 轴截距),避免因强制过原点导致的系统性偏差。
✅ 参数初始化必须可靠
错误的初值会令 curve_fit 陷入局部极小。推荐以下物理驱动的初始化策略:
- amplitude ≈ (max(x) − min(x)) / 2(峰峰值一半)
- frequency ≈ 2π / T₀,其中 T₀ 为目视估计周期(如 150 s → ω₀ ≈ 0.0419 rad/s)
- offset ≈ np.mean(x)(数据均值,即平衡点粗略估计)
⚠️ 注意:问题中手动添加 shift 并修改 popt[2] 的做法是错误的——curve_fit 返回的是最优参数,不应事后人为扰动;相位/偏移应由优化器自主求解。
✅ 进阶建议(显著提升鲁棒性)
- 数据预处理:对 x 应用低通滤波或移动平均(如 scipy.signal.savgol_filter(x, window_length=11, polyorder=3))抑制高频抖动;
- 加入相位项:若需更高精度,使用四参数模型 A·cos(ωt + φ) + c,但需确保初始相位 φ₀ 合理(如用 FFT 估计初相);
- 检查时间轴:确认 t 是否严格等间隔且无累积误差(视频帧率漂移常见);
- 可视化残差:绘制 x − fit 曲线,若残差呈趋势性,说明模型仍不充分(如需二次项校正基线漂移)。
最终稳健代码示例:
from scipy.optimize import curve_fit
from scipy.signal import savgol_filter
import numpy as np
# 加载并平滑数据
data = np.loadtxt('newdata.txt', delimiter=',', skiprows=1)
t, x_raw = data[:, 0], data[:, 1]
x = savgol_filter(x_raw, window_length=11, polyorder=3) # 去噪
# 定义含偏移的模型
def cos_func(t, A, ω, c):
return A * np.cos(ω * t) + c
# 物理驱动初值
p0 = [
(np.max(x) - np.min(x)) / 2, # A
2 * np.pi / 150, # ω ≈ 2π/T
np.mean(x) # c
]
# 拟合
popt, pcov = curve_fit(cos_func, t, x, p0=p0, maxfev=5000)
A_fit, ω_fit, c_fit = popt
# 绘图验证
plt.figure(figsize=(10, 5))
plt.plot(t, x, 'k.', alpha=0.6, label='Smoothed data')
plt.plot(t, cos_func(t, *popt), 'r-', lw=2, label=f'Fit: $A={A_fit:.1f},\, \omega={ω_fit:.4f},\, c={c_fit:.1f}$')
plt.xlabel('Time (s)'); plt.ylabel('Position (px)'); plt.legend(); plt.grid(True)总结:拟合失败往往源于模型欠完备(缺 offset)或初值失当。优先保证模型物理合理性(含偏移)、用数据统计量初始化、辅以轻量平滑,即可解决绝大多数“拟合整体偏低”的问题。

















