如果我知道三维中的齐次变换矩阵,如何使用opencv找到旋转和平移的角度
How to find the angle of rotation and translation using opencv if I know the homogeneous transformation matrix in 3d?
我发现了几篇关于这个主题的帖子,但没有一个解决方案使用opencv。
我想知道OpenCv是否有任何函数或类可以帮助解决这个问题?
我在opencv中有一个4*4仿射变换,我正在寻找旋转,平移,假设缩放为1,并且矩阵中没有其他变换。
OpenCV中是否有任何函数可以帮助查找这些参数?
您所面临的问题被称为矩阵分解问题
您可以按照以下步骤检索所需的矩阵:
- 将缩放因子计算为矩阵的前三个基向量(列或行)的大小
- 将前三个基向量除以这些值(从而对它们进行归一化)
- 矩阵的左上角3x3部分现在表示旋转(可以按原样使用,也可以将其转换为四元数形式)
- 平移是矩阵的第四个基向量(在齐次坐标中,它将是您感兴趣的前三个元素)
在您的情况下,如果缩放因子为1,则可以跳过前两个步骤
为了检索旋转矩阵的轴和角度(以弧度为单位),我建议您在OpenCV中移植以下Java算法(来源:http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/)
/**
This requires a pure rotation matrix 'm' as input.
*/
public axisAngle toAxisAngle(matrix m) {
double angle,x,y,z; // variables for result
double epsilon = 0.01; // margin to allow for rounding errors
double epsilon2 = 0.1; // margin to distinguish between 0 and 180 degrees
// optional check that input is pure rotation, 'isRotationMatrix' is defined at:
// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/
assert isRotationMatrix(m) : "not valid rotation matrix" ;// for debugging
if ((Math.abs(m[0][1]-m[1][0])< epsilon)
&& (Math.abs(m[0][2]-m[2][0])< epsilon)
&& (Math.abs(m[1][2]-m[2][1])< epsilon)) {
// singularity found
// first check for identity matrix which must have +1 for all terms
// in leading diagonaland zero in other terms
if ((Math.abs(m[0][1]+m[1][0]) < epsilon2)
&& (Math.abs(m[0][2]+m[2][0]) < epsilon2)
&& (Math.abs(m[1][2]+m[2][1]) < epsilon2)
&& (Math.abs(m[0][0]+m[1][1]+m[2][2]-3) < epsilon2)) {
// this singularity is identity matrix so angle = 0
return new axisAngle(0,1,0,0); // zero angle, arbitrary axis
}
// otherwise this singularity is angle = 180
angle = Math.PI;
double xx = (m[0][0]+1)/2;
double yy = (m[1][1]+1)/2;
double zz = (m[2][2]+1)/2;
double xy = (m[0][1]+m[1][0])/4;
double xz = (m[0][2]+m[2][0])/4;
double yz = (m[1][2]+m[2][1])/4;
if ((xx > yy) && (xx > zz)) { // m[0][0] is the largest diagonal term
if (xx< epsilon) {
x = 0;
y = 0.7071;
z = 0.7071;
} else {
x = Math.sqrt(xx);
y = xy/x;
z = xz/x;
}
} else if (yy > zz) { // m[1][1] is the largest diagonal term
if (yy< epsilon) {
x = 0.7071;
y = 0;
z = 0.7071;
} else {
y = Math.sqrt(yy);
x = xy/y;
z = yz/y;
}
} else { // m[2][2] is the largest diagonal term so base result on this
if (zz< epsilon) {
x = 0.7071;
y = 0.7071;
z = 0;
} else {
z = Math.sqrt(zz);
x = xz/z;
y = yz/z;
}
}
return new axisAngle(angle,x,y,z); // return 180 deg rotation
}
// as we have reached here there are no singularities so we can handle normally
double s = Math.sqrt((m[2][1] - m[1][2])*(m[2][1] - m[1][2])
+(m[0][2] - m[2][0])*(m[0][2] - m[2][0])
+(m[1][0] - m[0][1])*(m[1][0] - m[0][1])); // used to normalise
if (Math.abs(s) < 0.001) s=1;
// prevent divide by zero, should not happen if matrix is orthogonal and should be
// caught by singularity test above, but I've left it in just in case
angle = Math.acos(( m[0][0] + m[1][1] + m[2][2] - 1)/2);
x = (m[2][1] - m[1][2])/s;
y = (m[0][2] - m[2][0])/s;
z = (m[1][0] - m[0][1])/s;
return new axisAngle(angle,x,y,z);
}
相关文章:
- 在C++中使用OpenCV矩阵中的特征将图像旋转90度
- 从iPhone相机拍摄的视频似乎被OpenCV旋转了90度?我该如何解决这个问题?
- OpenCV:按一定角度旋转点:溶液中的偏移/偏移
- 如何使用OpenCV从图像中检测旋转对象
- OpenCV 检测多个旋转的缩放对象
- openCV等应角旋转
- 如何从OpenCV rvecs计算旋转角度
- Android OpenCV - 每次旋转是否有可能捕捉到不同的3D对象点击?
- OpenCV 计算相机位置和旋转
- 将OpenCV旋转和平移矢量转换为XYZ旋转和XYZ位置
- 旋转OpenCV中的箭头
- 旋转直接与rect或旋转的openCV的交点
- 如何在OpenCV中获取旋转矩形的顶点
- 无法根据opencv旋转矩形教程获得相同的图像结果
- OpenCV从T形主体获得360度旋转
- 如何使用OpenCV计算两帧之间的旋转平移矩阵
- OpenCV:来自分解同源异构图的奇怪旋转和平移矩阵
- 帧之间的 OpenCV 平移/旋转位移
- OpenCV立体声校准旋转矩阵
- opencv:使用旋转和平移向量设置模型位置