在考虑传感器标定误差度量时,除了直接计算投影值和实际值之间的欧氏距离之外,以下是一些更复杂的误差度量方式,可以用来考虑方向误差或为不同类型的误差赋予不同的权重:
加权欧氏距离:
给不同的错误分量(如X, Y, Z方向)赋予不同的权重。这可以通过构造一个加权矩阵来实现,并使用此矩阵对错误向量进行缩放。
平方和根误差(RMSE):
对于具有多个误差源的系统,计算每个误差值的平方,求和后再取平方根。这通常对大的误差赋予更大的权重。
最小二乘法:
对预测值和实际值之间的差异进行平方和,这是最常见的最优化目标函数形式,特别适合处理有噪声的数据。
马氏距离(Mahalanobis Distance):
一种考虑数据变异性和数据特征相关性的距离度量,用于多变量数据,并可以用来考虑不同特征的误差权重。
角度误差:
在旋转问题中,可以单独考虑方向误差,通过将两个旋转矩阵之间的角度差异最小化。例如,可以通过计算旋转矩阵的跟踪来估计角度差异,并将其最小化。
Huber损失(Huber Loss):
一种结合了平方误差损失和绝对误差损失的方法,对于小误差,其表现与平方误差损失相似,对于大误差,其表现与绝对误差损失相似,从而提高了模型对异常点的鲁棒性。
Tukey’s biweight (Tukey Loss):
与Huber损失类似,但在处理超出某个范围的异常点时,误差的增加会更加缓慢,使得算法对于异常值更为鲁棒。
定向约束优化:
在某些案例中,你可能更关心方向而不是具体位置。例如,可能想要最小化两个向量之间的夹角。这可以通过最小化余弦距离或直接最小化夹角来实现。
复合误差度量:
可以定义一个复合误差度量,将位置误差和方向误差结合起来作为目标函数,可以通过分别计算并赋予不同的权重。
选择错误度量的依据需要基于应用的特定需求。某些应用可能对位置误差更为敏感,而另一些应用可能对方向误差更为敏感。通过对问题的详细理解,可以选择或设计更为适合的误差度量方式。
针对重投影误差最小目标函数,下面为每种提出的错误度量方法给出具体的公式表达式,以及如何在该函数中使用它们。
加权欧氏距离:
weights = np.array([w1, w2, w3]) # w1, w2, w3为对应X, Y, Z方向的权重
error.append(np.sqrt(np.sum(weights * (Y_pred - YM)**2)))
平方和根误差(RMSE):
error.append(np.sqrt(np.mean((Y_pred - YM)**2))) # 对于所有数据点计算RMSE
最小二乘法:
使用目标函数的现有形式已经是最小化平方和误差:
error.append((Y_pred - YM)**2) # 最后返回均方误差的均值
马氏距离(Mahalanobis Distance):
S = np.cov(np.hstack((Y.T, Y_pred.T)).T) # 计算样本协方差矩阵,其中Y.T和Y_pred.T是真实值和预测值的转置
error.append((Y_pred - YM).T @ np.linalg.inv(S) @ (Y_pred - YM)) # 计算马氏距离
角度误差:
计算旋转矩阵间的角度差异
R_pred = rot_mat1 @ rot_mat3
R_true = Y[:3, :3] # 假设Y也是一个具有旋转部分的齐次变换矩阵
angle_error = np.arccos((np.trace(np.dot(R_pred.T, R_true)) - 1) / 2)
error.append(angle_error)
Huber损失(Huber Loss):
delta = 1.0 # Huber损失的阈值参数
residual = Y_pred - YM
mask = np.abs(residual) < delta
error.append(np.where(mask, 0.5 * residual**2, delta * (np.abs(residual) - 0.5 * delta))) # Huber损失计算
Tukey’s biweight (Tukey Loss):
c = 4.685 # Tukey损失的参数
residual = Y_pred - YM
mask = np.abs(residual) <= c
error.append(np.where(mask, ((1 - (1 - (residual/c)**2)3) / 6) * c2, 0)) # Tukey损失计算
定向约束优化:
假设 XM 和 Y 是方向向量,则它们之间的夹角误差可以这样计算
angle_error = np.arccos(np.clip(np.dot(XM / np.linalg.norm(XM), (Y_pred / np.linalg.norm(Y_pred)).T), -1.0, 1.0))
error.append(angle_error)
复合误差度量:
position_weight = 1.0 # 位置误差的权重
orientation_weight = 1.0 # 方向误差的权重
position_error = np.linalg.norm(Y_pred[:3] - YM[:3]) # 位置误差
orientation_error = angle_error # 方向误差计算
error.append(position_weight * position_error + orientation_weight * orientation_error)
当在目标函数中使用这些方法时,需要确保Y和Y_pred的对应部分具有相同的意义,例如,如果在角度计算中将Y视为旋转矩阵,则Y_pred也应相应地从旋转参数中计算得到旋转矩阵。同样,不同方法有不同的假设和需求,因此要确保输入数据格式与期望的格式匹配,并适用于评估的场景。