如何用Eigen::Transform实现欧式变换?矩阵运算断言失败求助
解决Eigen欧式变换的维度匹配断言错误
嘿,这个问题我之前也踩过坑!咱们先拆解一下报错的原因,再给你两种靠谱的解决办法:
为什么会触发断言错误?
你用了Eigen::Transform<Type, 3, Eigen::Projective>这个类型,它对应的是4×4的齐次投影变换矩阵。但你的输入X是3×N的普通3D列向量矩阵(非齐次坐标),直接做矩阵乘法时,4×4矩阵的列数是4,而3×N矩阵的行数是3,维度不匹配,Eigen的断言机制就直接报错了,完全是维度不对导致的。
解决方案1:改用欧式变换专用的Transform类型
既然你要实现的是欧式变换X = R*X + t,根本不需要用投影变换类型,直接用Eigen::Isometry(欧式变换专用,性能最优)或者Eigen::Affine(通用仿射变换)就好。这两种类型会自动处理3D向量和变换矩阵的维度匹配:
// 替换成Isometry类型,专门用于欧式变换 Eigen::Transform<Type, 3, Eigen::Isometry> transformation; // 注意给AngleAxis指定模板参数Type,避免类型推导问题 Eigen::AngleAxis<Type> rotation(R); Eigen::Translation<Type,3> translation(t); // 先旋转再平移,和X = R*X + t的数学逻辑完全一致 transformation = translation * rotation; // 现在直接乘3×N的X就不会报错了 X = transformation * X;
这里要提一句:Isometry会严格保证变换矩阵的正交性,比Affine更高效,是欧式变换的首选。
解决方案2:如果必须用Projective类型(比如有投影需求)
如果你后续需要用到投影变换,非得保留Projective类型,那得先把3D向量转换成齐次坐标(4×N矩阵,最后一行全为1),变换完成后再转换回非齐次坐标:
// 把3×N的X转换成4×N的齐次坐标矩阵 Eigen::Matrix<Type, 4, Eigen::Dynamic> X_homo(4, X.cols()); X_homo.topRows(3) = X; X_homo.bottomRows(1).setOnes(); // 执行投影变换 X_homo = transformation * X_homo; // 转换回3×N的非齐次坐标(注意除法是逐元素的) X = X_homo.topRows(3).array() / X_homo.bottomRows(1).array();
额外注意点
- 你之前写的
Eigen::AngleAxis rotation(R);最好加上模板参数Type,不然如果R的类型和Type不一致,可能会出现隐式转换的问题。 translation * rotation的顺序是对的:Eigen里的变换是左乘逻辑,transformation * X等价于先旋转X,再对旋转后的结果做平移,完美对应X' = R*X + t的数学公式。
内容的提问来源于stack exchange,提问作者Frank-Rene Schäfer
相关产品推荐
相关产品推荐

