in opensfm/src/bundle/reconstruction_alignment.h [315:368]
bool operator()(const T *const reconstruction_a,
const T *const reconstruction_b, T *residuals) const {
const double *const rotation_ai = shot_ai_ + RA_SHOT_RX;
const double *const rotation_bi = shot_bi_ + RA_SHOT_RX;
const double *const translation_ai = shot_ai_ + RA_SHOT_TX;
const double *const translation_bi = shot_bi_ + RA_SHOT_TX;
double pose_ai[3], pose_bi[3];
const double rotation_ait[3] = {-rotation_ai[0], -rotation_ai[1],
-rotation_ai[2]};
ceres::AngleAxisRotatePoint(rotation_ait, translation_ai, pose_ai);
const double rotation_bit[3] = {-rotation_bi[0], -rotation_bi[1],
-rotation_bi[2]};
ceres::AngleAxisRotatePoint(rotation_bit, translation_bi, pose_bi);
for (int i = 0; i < 3; ++i) {
pose_ai[i] = -pose_ai[i];
pose_bi[i] = -pose_bi[i];
}
// optical center error in world coordinates :
// Ta(-1)(shot_a center) - Tb(-1)(shot_b center)
T world_pose_ai[3], world_pose_bi[3];
transform_point(reconstruction_a, pose_ai, world_pose_ai);
transform_point(reconstruction_b, pose_bi, world_pose_bi);
// rotation error in world coordinates :
// (Ra^t Rai^t)(^T)(Rb^t Rbi^t) = (Rai Ra)(Rb^t Rbi^t)
const T *const Ra = reconstruction_a + RA_RECONSTRUCTION_RX;
const T *const Rb = reconstruction_b + RA_RECONSTRUCTION_RX;
const T Rbt[3] = {-Rb[0], -Rb[1], -Rb[2]};
const T Rbit[3] = {T(-rotation_bi[0]), T(-rotation_bi[1]),
T(-rotation_bi[2])};
const T Rai[3] = {T(rotation_ai[0]), T(rotation_ai[1]), T(rotation_ai[2])};
T qRai[4], qRa[4], qRbt[4], qRbit[4], qRai_qRa[4], qRai_qRa_qRbt[4],
qRai_qRa_qRbt_qRbit[4];
ceres::AngleAxisToQuaternion(Rai, qRai);
ceres::AngleAxisToQuaternion(Ra, qRa);
ceres::AngleAxisToQuaternion(Rbt, qRbt);
ceres::AngleAxisToQuaternion(Rbit, qRbit);
ceres::QuaternionProduct(qRai, qRa, qRai_qRa);
ceres::QuaternionProduct(qRai_qRa, qRbt, qRai_qRa_qRbt);
ceres::QuaternionProduct(qRai_qRa_qRbt, qRbit, qRai_qRa_qRbt_qRbit);
// final error
ceres::QuaternionToAngleAxis(qRai_qRa_qRbt_qRbit, residuals);
for (int i = 0; i < 3; ++i) {
residuals[i] *= T(inv_std_rotation_);
residuals[3 + i] =
T(inv_std_center_) * (world_pose_ai[i] - world_pose_bi[i]);
}
return true;
}