SVD分解双目立体Essential Matrix无法得到正确Rotation与Translation矩阵
问题核心错误点
- numpy SVD返回值特性误用:
numpy.linalg.svd对实矩阵的分解满足公式E = U @ np.diag(S) @ Vh,其中返回的第三个参数是V的转置矩阵Vh,你原有代码计算旋转矩阵时额外对V做了一次转置,相当于用了未转置的V参与计算,是结果错误的核心原因。 - 缺少旋转矩阵合法性校验:SVD分解本质会输出4组可能的(R,T)组合,其中一半为行列式等于-1的反射矩阵,不符合旋转矩阵的要求,需要提前对U、Vh做符号修正,或对输出的R做行列式过滤。
修正后代码
import numpy as np # 原始构造的Essential Matrix E = np.array([[-0.02418259, 0.97527093, 0.15178621], [-0.96115177, -0.01316561, 0.16363519], [-0.21769595, -0.16403593, 0.01268507]]) U, S, Vh = np.linalg.svd(E) # 修正U和Vh的符号,保证行列式为正,避免反射结果 if np.linalg.det(U) < 0: U *= -1 if np.linalg.det(Vh) < 0: Vh *= -1 W = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]]) Z = np.array([[0, 1, 0], [-1, 0, 0], [0, 0, 0]]) # 直接使用Vh计算,无需额外转置 R1 = U.dot(W).dot(Vh) R2 = U.dot(W.T).dot(Vh) # 过滤非法反射矩阵,保留行列式为1的旋转矩阵 valid_R = [r for r in [R1, R2] if np.isclose(np.linalg.det(r), 1)] T_mat = U.dot(Z).dot(U.T) T = [T_mat[1,0], -T_mat[2, 0], T_mat[2, 1]]
结果验证
运行上述代码后,输出的有效旋转矩阵中会包含你构造E时使用的原始R矩阵,平移向量T保持原有正确结果。
内容的提问来源于stack exchange,提问作者Sandeep Menon
相关产品推荐
相关产品推荐

