误差预算怎么做?从雅可比到蒙特卡洛的三维定位不确定度分析

"相机误差 0.2 mm、标定误差 0.3 mm,所以总误差 0.5 mm"看起来直观,却缺少方向、统计定义与相关性。误差预算需要先写清测量模型,再让输入的不确定性通过模型传播。把每个模块的宣传数字直接相加,很难得到可信的目标位置结论。

**阅读范围:**本文是三维视觉与医学影像软件工程系列的独立技术教程。数据和数值实验均为合成示例,不读取患者数据,不代表实际设备性能或临床精度。文中长度按示例明确的单位解释。资料核对日期:2026 年 10 月 16 日。

图 1:误差预算:先写模型,再谈合成误差(原创教学配图)

一、先定义输出量与扰动模型

本篇输出是一个三维目标点的位置。基准旋转为单位旋转,目标点在 (0,0,150) mm;平移扰动与小旋转向量扰动都按目标参考系表达。不同扰动施加方向会改变雅可比,因此不能在任意坐标约定下照抄同一公式。

位置误差、每坐标标准差、三维 RMS、径向 P95 和最大误差是不同统计量。零均值并不意味着没有随机误差;标准差小也不意味着没有固定偏差。报告时需要把中心偏移与散布分别记录。

二、小角度雅可比怎样得到?

对接近单位旋转的扰动 δθ,有 R(δθ)p≈p+δθ×p=p−p×δθ。加上平移 δt 后,位置误差近似为 δy=δt−p×δθ。因此 J=I,−\[p×],输入六维协方差 Σ 传播为 Σ_y≈JΣJᵀ。

角度必须按弧度输入。位于旋转中心附近的点对旋转扰动不敏感,远处目标则因杆长放大而敏感;沿目标方向的旋转分量可能不产生一阶位置变化。这也是单纯用一个杆长乘一个角误差,只能作为有方向假设的近似。

三、相关性与系统偏差不能省略

若平移与旋转由同一套数据估计,它们可能相关;完整协方差中的交叉项可能增加也可能减少输出方差。各模块共享参考或数据时,也不应默认独立。平方和开根号只在相应独立或不相关及统计口径条件成立时才适用。

固定偏差不能通过增加随机样本自然消失。把所有 Monte Carlo 样本都平移 1 mm,协方差保持不变,输出均值与 RMS 却明显变化。本篇用这个反例说明:只画误差椭球,可能遗漏整个椭球中心已经偏了。

四、蒙特卡洛是传播模型,不是制造真值

按照假设的输入分布抽样,通过完整非线性模型计算输出,再估计均值、协方差和分位数。它能检查线性近似是否适合当前范围,也能处理某些复杂模型,但结果质量取决于输入分布与相关性是否可信。

样本多只减少模拟统计误差,不会修复遗漏的弯曲、时间延迟或参考偏差。径向 P95 是当前模型样本中误差长度的第 95 百分位,不自动等于临床成功率,也不能拿每坐标 1.96σ 直接替代三维半径阈值。

五、可运行的完整合成实验

抽样十万次,平移每坐标标准差 0.2 mm,旋转向量每坐标标准差 0.1°,假设独立零均值高斯。使用 SciPy 完整旋转作用于 150 mm 处目标,比较实际样本协方差与一阶雅可比结果;再加入固定 1 mm 的 x 方向偏差。

环境说明:代码在本机 Python 3.14 环境中实际执行。为便于复现,请保存为 demo.py,在支持这些库的独立环境中安装依赖;若目标解释器没有兼容 wheel,应先选择受支持的解释器。环境差异可能影响最后几位数值,不影响本文所检查的几何或统计关系。

复制代码
python -m pip install numpy scipy
python demo.py

import numpy as np
from scipy.spatial.transform import Rotation

rng=np.random.default_rng(16)
n=100000;sigma_t=.2;sigma_angle=np.deg2rad(.1)
dt=rng.normal(0,sigma_t,(n,3))
dr=rng.normal(0,sigma_angle,(n,3))
point=np.array([0.,0.,150.])
error=Rotation.from_rotvec(dr).apply(point)+dt-point
cov=np.cov(error,rowvar=False)
def skew(v):
    x,y,z=v
    return np.array([[0,-z,y],[z,0,-x],[-y,x,0.]])
J=np.column_stack([np.eye(3),-skew(point)])
input_cov=np.diag([sigma_t**2]*3+[sigma_angle**2]*3)
linear=J@input_cov@J.T
assert np.allclose(np.diag(cov),np.diag(linear),rtol=.03)
length=np.linalg.norm(error,axis=1)
biased=error+np.array([1.,0,0])
np.testing.assert_allclose(np.cov(biased,rowvar=False),cov,atol=1e-12)
assert np.linalg.norm(biased.mean(0))>.9
print('empirical_coordinate_SD_mm',np.sqrt(np.diag(cov)))
print('linear_coordinate_SD_mm',np.sqrt(np.diag(linear)))
print('radial_RMS_mm',np.sqrt(np.mean(length**2)),'radial_P95_mm',np.percentile(length,95))
print('biased_radial_RMS_mm',np.sqrt(np.mean(np.sum(biased**2,axis=1))))
print('PASS: small-angle covariance and constant-bias counterexample')

六、运行结果与应该怎样解读

经验坐标标准差约 (0.32959,0.32930,0.19938) mm,线性预测约 (0.32945,0.32945,0.2) mm。径向 RMS 约 0.50677 mm,P95 约 0.83555 mm。加入固定偏差后 RMS 约 1.12092 mm,协方差不变。

图 2:杆长与小扰动标准差关系(原创教学配图)

代码中的断言验证了本篇明确描述的性质。配图中标为原理示意的部分用于解释模型,不是实测截图;由公式生成的曲线只在图注与正文列出的假设下成立。不要把合成实验输出当成真实产品的性能报告。

七、常见现象与排查方向

现象 优先检查 处理方向
角度误差大了几十倍 度与弧度混用 在模型边界统一单位
总误差比预期大 遗漏杆长或相关项 写出目标点与完整雅可比
标准差很好但整体偏移 固定系统偏差未建模 同时报告均值和散布
模拟很稳定却对不上实测 输入模型缺少真实因素 用独立观测检查模型假设

八、独立验证与适用边界

误差预算应标明每个输入的来源、统计定义、坐标系、相关性假设与有效范围。将预算结果与独立参考下的实际目标误差分布比较,分析偏差、尾部和随工作距离变化的趋势。BIPM 的 JCGM 指南提供不确定度表达与蒙特卡洛传播的参考入口;本文不是对完整指南的替代,也未覆盖真实设备或合规验证。

建议把原始输入、参数、软件版本、输出结果和失败状态一起保留。若把同一份检查数据反复用于选择参数,它就不再是完全独立的最终验证集。将算法演示接入真实系统时,应另行验证输入质量、参考不确定性和完整处理链路。

参考资料

BIPM:JCGM 不确定度与蒙特卡洛指南目录

SciPy:Rotation

上述资料用于核对相关接口与基本约定;本文的合成数据、推导示例与代码不声称复刻库内全部实现。

写在最后

"不积小流,无以成江海。"

------ 荀子,《劝学》

先写明假设,再解释数字,误差预算才会成为可检验的工程判断。

相关推荐
文章永久免费只为良心1 小时前
Ctfshow_Web应用安全与防护_第二章_无字母数字命令执行
前端·python·安全·网络安全·渗透测试·ctf·红队渗透测试
2601_962885721 小时前
如何用 Python 获取上证指数、沪深300、中证500 等指数行情?
开发语言·python
昔我往昔1 小时前
LangChain_RAG_学习小结
后端·python
张张123y2 小时前
后端第六课:Python 语法速通(0 基础入门,AI 应用开发的第一门语言)
开发语言·人工智能·python·ai·后端开发
小马不起床2 小时前
Django 后端实战指南_10:用户扩展档案信息表
python·django·sqlite
Want5952 小时前
Python跳动的爱心①
开发语言·python·数学建模
SamChan902 小时前
PDF 翻译后 1,250 变成 1.250,是错了吗?用 Python 核对数字格式
python·pdf·ocr·数据校验·文档翻译
Yolanda_20222 小时前
30.利用GPU训练(一)
python
迅猛龙办公室2 小时前
Python实现PM空气质量提醒
服务器·前端·python