Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 视图矩阵中的平移和旋转向量(和背面) 问题:_Opencv_Matrix_Coordinate Systems - Fatal编程技术网

Opencv 视图矩阵中的平移和旋转向量(和背面) 问题:

Opencv 视图矩阵中的平移和旋转向量(和背面) 问题:,opencv,matrix,coordinate-systems,Opencv,Matrix,Coordinate Systems,我有一个我相机的视图矩阵(作为4x4矩阵),我想从中提取旋转和平移向量,然后返回(从旋转和平移向量到视图矩阵) 我已经找到了一些这样做的方法,但它们不起作用 我该怎么做 背景 对于增强现实应用程序,我根据失真参数和参数计算视图矩阵。该方法有效:我在图像平面中找到一些点(通过单击它们),知道真实世界中的点,就可以估计相机的位置 单击过程有一些错误(单击不精确),因此我想通过手动修改平移和旋转向量来优化摄影机位置 所以我在寻找一种从矩阵得到向量的方法,然后返回,从向量到矩阵 测验 我现在正在做的是:

我有一个我相机的视图矩阵(作为4x4矩阵),我想从中提取旋转和平移向量,然后返回(从旋转和平移向量到视图矩阵)

我已经找到了一些这样做的方法,但它们不起作用

我该怎么做

背景 对于增强现实应用程序,我根据失真参数和参数计算视图矩阵。该方法有效:我在图像平面中找到一些点(通过单击它们),知道真实世界中的点,就可以估计相机的位置

单击过程有一些错误(单击不精确),因此我想通过手动修改平移和旋转向量来优化摄影机位置

所以我在寻找一种从矩阵得到向量的方法,然后返回,从向量到矩阵

测验 我现在正在做的是:

void matrix2vector(cv::Mat n) { // n is the pose matrix
    this->position[0] = n.at<float>(3);
    this->position[1] = n.at<float>(7);
    this->position[2] = n.at<float>(11);

    float rx, ry, rz;
    rx = atan2(n.at<float>(9), n.at<float>(10));
    ry = atan2(-n.at<float>(8), 
               sqrt( n.at<float>(9)*n.at<float>(9) + n.at<float>(10)*n.at<float>(10) ));
    rz = atan2(n.at<float>(4), n.at<float>(0));
    this->angle[0] = rx * RAD2DEG;
    this->angle[1] = ry * RAD2DEG;
    this->angle[2] = rz * RAD2DEG;
}

void vector2matrix() {
    _viewMatrix =  cv::Mat::eye(4, 4, CV_32F);
    rotateX(_viewMatrix, _viewMatrix, -angle[0]);
    rotateY(_viewMatrix, _viewMatrix, -angle[1]);
    rotateZ(_viewMatrix, _viewMatrix, -angle[2]);
    _viewMatrix.at<float>(3) = position[0];
    _viewMatrix.at<float>(7) = position[1];
    _viewMatrix.at<float>(11) = position[2];
}
void matrix2vector(cv::Mat n){//n是姿势矩阵
此->位置[0]=n.at(3);
此->位置[1]=n.at(7);
该->位置[2]=n.at(11);
浮动rx,ry,rz;
rx=atan2(n.at(9),n.at(10));
ry=atan2(-n.at(8),
sqrt(n.at(9)*n.at(9)+n.at(10)*n.at(10));
rz=atan2(n.at(4),n.at(0));
该->角度[0]=rx*RAD2DEG;
此->角度[1]=ry*RAD2DEG;
该->角度[2]=rz*RAD2DEG;
}
空向量2矩阵(){
_viewMatrix=cv::Mat::eye(4,4,cv_32F);
rotateX(_viewMatrix,_viewMatrix,-角度[0]);
rotateY(_viewMatrix,_viewMatrix,-角度[1]);
rotateZ(_viewMatrix,_viewMatrix,-角度[2]);
_viewMatrix.at(3)=位置[0];
_viewMatrix.at(7)=位置[1];
_viewMatrix.at(11)=位置[2];
}
其中旋转方法为:

inline
void rotateX(cv::Mat &src, cv::Mat &dst, float angleDegree) {
    dst = src.clone();

    float c = cosf(angleDegree * DEG2RAD);
    float s = sinf(angleDegree * DEG2RAD);
    float m4 = src.at<float>(4),
          m5 = src.at<float>(5),
          m6 = src.at<float>(6),
          m7 = src.at<float>(7),
          m8 = src.at<float>(8),
          m9 = src.at<float>(9),
          m10= src.at<float>(10),
          m11= src.at<float>(11);

    dst.at<float>(4) = m4 * c + m8 *-s;
    dst.at<float>(5) = m5 * c + m9 *-s;
    dst.at<float>(6) = m6 * c + m10*-s;
    dst.at<float>(7) = m7 * c + m11*-s;
    dst.at<float>(8) = m4 * s + m8 * c;
    dst.at<float>(9) = m5 * s + m9 * c;
    dst.at<float>(10)= m6 * s + m10* c;
    dst.at<float>(11)= m7 * s + m11* c;
}

inline
void rotateY(cv::Mat &src, cv::Mat &dst, float angleDegree)
{
    float c = cosf(angleDegree * DEG2RAD);
    float s = sinf(angleDegree * DEG2RAD);
    float m0 = src.at<float>(0),
          m1 = src.at<float>(1),
          m2 = src.at<float>(2),
          m3 = src.at<float>(3),
          m8 = src.at<float>(8),
          m9 = src.at<float>(9),
          m10= src.at<float>(10),
          m11= src.at<float>(11);

    dst.at<float>(0) = m0 * c + m8 * s;
    dst.at<float>(1) = m1 * c + m9 * s;
    dst.at<float>(2) = m2 * c + m10* s;
    dst.at<float>(3) = m3 * c + m11* s;
    dst.at<float>(8) = m0 *-s + m8 * c;
    dst.at<float>(9) = m1 *-s + m9 * c;
    dst.at<float>(10)= m2 *-s + m10* c;
    dst.at<float>(11)= m3 *-s + m11* c;
}

inline
void rotateZ(cv::Mat &src, cv::Mat &dst, float angleDegree)
{
    float c = cosf(angleDegree * DEG2RAD);
    float s = sinf(angleDegree * DEG2RAD);
    float m0 = src.at<float>(0),
          m1 = src.at<float>(1),
          m2 = src.at<float>(2),
          m3 = src.at<float>(3),
          m4 = src.at<float>(4),
          m5 = src.at<float>(5),
          m6 = src.at<float>(6),
          m7 = src.at<float>(7);

    dst.at<float>(0) = m0 * c + m4 *-s;
    dst.at<float>(1) = m1 * c + m5 *-s;
    dst.at<float>(2) = m2 * c + m6 *-s;
    dst.at<float>(3) = m3 * c + m7 *-s;
    dst.at<float>(4) = m0 * s + m4 * c;
    dst.at<float>(5) = m1 * s + m5 * c;
    dst.at<float>(6) = m2 * s + m6 * c;
    dst.at<float>(7) = m3 * s + m7 * c;
}
内联
空隙旋转度(cv::垫和src,cv::垫和dst,浮动角度度){
dst=src.clone();
浮点数c=cosf(角度度*DEG2RAD);
浮子s=sinf(角度度*DEG2RAD);
浮球m4=在(4)处的src,
m5=在(5)处的src,
m6=在(6)处的src,
m7=在(7)处的src,
m8=在(8)处的src,
m9=在(9)处的src,
m10=在(10)处的src,
m11=在(11)处的src;
(4)处的dst=m4*c+m8*-s;
(5)处的dst=m5*c+m9*-s;
(6)处的dst=m6*c+m10*-s;
(7)处的dst=m7*c+m11*-s;
(8)处的dst=m4*s+m8*c;
(9)处的dst=m5*s+m9*c;
(10)处的dst=m6*s+m10*c;
(11)处的dst=m7*s+m11*c;
}
内联
空隙旋转(cv::Mat&src、cv::Mat&dst、浮动角度度)
{
浮点数c=cosf(角度度*DEG2RAD);
浮子s=sinf(角度度*DEG2RAD);
浮动m0=在(0)处的src,
m1=在(1)处的src,
m2=在(2)处的src,
m3=在(3)处的钢筋混凝土,
m8=在(8)处的src,
m9=在(9)处的src,
m10=在(10)处的src,
m11=在(11)处的src;
(0)处的dst=m0*c+m8*s;
(1)处的dst=m1*c+m9*s;
(2)处的dst=m2*c+m10*s;
(3)处的dst=m3*c+m11*s;
(8)处的dst=m0*-s+m8*c;
(9)处的dst=m1*-s+m9*c;
(10)处的dst=m2*-s+m10*c;
(11)处的dst=m3*-s+m11*c;
}
内联
空心旋转(cv::Mat和src,cv::Mat和dst,浮动角度度)
{
浮点数c=cosf(角度度*DEG2RAD);
浮子s=sinf(角度度*DEG2RAD);
浮动m0=在(0)处的src,
m1=在(1)处的src,
m2=在(2)处的src,
m3=在(3)处的钢筋混凝土,
m4=在(4)处的src,
m5=在(5)处的src,
m6=在(6)处的src,
m7=在(7)处的src;
(0)处的dst=m0*c+m4*-s;
(1)处的dst=m1*c+m5*-s;
(2)处的dst=m2*c+m6*s;
(3)处的dst=m3*c+m7*-s;
(4)处的dst=m0*s+m4*c;
(5)处的dst=m1*s+m5*c;
(6)处的dst=m2*s+m6*c;
(7)处的dst=m3*s+m7*c;
}

答案取决于您是使用列向量还是行向量按矩阵变换向量。假设有一个矩阵
M
和一个向量
v
,并通过
v'=Mv
对其进行变换,则使用列向量。如果您使用的是
v'=vM
,则使用的是行向量

要查找翻译,只需检查向量
[01]
的结束位置。如果使用列向量,您会发现矩阵的最后一列是平移所在的位置。最后一列的前三个元素将是平移向量(x,y,z)。类似地,在行向量中,您会发现矩阵的最后一行是平移所在的位置。矩阵最后一行的前三个元素将是平移向量(x,y,z)

对于旋转,请尝试将矩阵乘以向量
[1 0 0]
。这将告诉您“x轴”映射到的位置。类似地,对于
[0 1 0 0]
(y轴)和
[0 0 1 0]
(z轴)。无论您使用的是列向量还是行向量,相关条目都是4x4矩阵左上角的3x3子矩阵。行向量和列向量之间唯一的变化是映射轴在子矩阵中是列向量还是行向量


希望这能有所帮助。

Oops——现在你发布了一堆我第一次看到这个问题时不存在的代码。希望这个答案仍然是相关的。(反正我用的是列向量!)旋转不是很清楚。。你能解释得更清楚一点吗?@nkint你能告诉我更多你想要实现的目标吗?如果你“知道”旋转,你希望它采取什么形式?@nkint另外,请记住欧拉角(你要求的)通常不是唯一的,分解取决于你执行旋转的顺序。这是因为旋转不是可交换的,因此依赖于顺序。根据您的情况,最好使用3x3旋转矩阵,如果您希望“调整”,只需将其乘以您设计的附加旋转矩阵(绕X轴旋转10度)即可执行调整。