14

我正在开发 Android 上的基本增强现实应用程序。到目前为止,我所做的是用 opencv 检测一个正方形,然后使用 cvFindExtrinsicCameraParams2() 我计算了一个旋转和平移向量。为此,我使用了 4 个对象点,它们只是 (0,0,0) 周围正方形的角和图像中正方形的 4 个角。

这给我一个很好的旋转和平移矩阵。我还使用 cvRodrigues2() 计算了旋转矩阵,因为使用它比旋转向量更容易。只要我使用这些在图像中绘制一些点,一切正常。然而,我的下一步是将这些向量和矩阵传递回 java,然后将它们与 OpenGL 一起使用,在 OpenGLView 中绘制一个正方形。正方形应该正好在 OpenGLView 后面显示的图像中的正方形周围。

我的问题是我找不到在 OpenGL 中使用旋转矩阵和平移向量的正确方法。我开始使用与 openCV 函数完全相同的对象点。然后我以我能想到的几乎所有可能的方式应用旋转矩阵和平移向量。遗憾的是,这些方法都没有产生接近我希望的结果。谁能告诉我如何正确使用它们?

到目前为止,我得到的“最接近”的结果是将整个矩阵随机乘以 -1。但大多数情况下,正方形仍然像镜子一样倒转或旋转 180 度。所以我想这只是一个幸运的打击,但不是正确的方法。

4

2 回答 2

11

好的,经过更多的测试,我终于设法让它工作了。虽然我不明白......它确实“工作”。对于将来需要这样做的任何人,这是我的解决方案。

float rv[3]; // the rotation vector
float rotMat[9]; // rotation matrix
float tv[3]; // translation vector.


rv[1]=-1.0f * rv[1]; rv[2]=-1.0f * rv[2];
//Convert the rotation vector into a matrix here.

//Complete matrix ready to use for OpenGL
float RTMat[] = {rotMat[0], rotMat[3], rotMat[6], 0.0f,
                 rotMat[1], rotMat[4], rotMat[7], 0.0f,
                 rotMat[2], rotMat[5], rotMat[8], 0.0f,
                 tv[0], -tv[1], -tv[2], 1.0f};

正如 genpfault 在他的评论中所说,自 OpenGL 以来,所有内容都需要转置,因为 OpenGL 需要以列为主的顺序。(感谢您的评论,我之前已经看过该页面。)此外,y 和 z 旋转角度以及 y 和 z 平移需要乘以 -1。这是我觉得有点奇怪的地方。为什么只有那些而不是 x 值呢?

这就像我猜的那样有效。但是角落并不完全匹配。我猜这是由一些错误的 openGLView 配置引起的。因此,即使我对我的解决方案仍然不是 100% 满意,我想这就是我问题的答案。

于 2010-09-14T20:43:55.503 回答
2

潘多罗的方法真的很管用!如果有人想知道“如何将旋转向量转换为旋转矩阵”,这就是我的做法。顺便说一句,我在 OpenGL 2 中使用了这些,而不是 ES。

// use the rotation vector generated from OpenCV's cvFindExtrinsicCameraParams2() 
float rv[] = {rotation->data.fl[0], rotation->data.fl[1], rotation->data.fl[2] }; 

// use the translation vector generated from OpenCV's cvFindExtrinsicCameraParams2() 
float tv[] = {translation->data.fl[0], translation->data.fl[1], translation->data.fl[2]} ; 

float rm[9];
// rotation matrix
CvMat* rotMat = cvCreateMat (3, 3, CV_32FC1); 

// rotation vectors can be converted to a 3-by-3 rotation matrix
// by calling cvRodrigues2() - Source: O'Reilly Learning OpenCV
cvRodrigues2(rotation, rotMat, NULL);

for(int i=0; i<9; i++){
    rm[i] = rotMat->data.fl[i];
}

rv[1]=-1.0f * rv[1]; rv[2]=-1.0f * rv[2];
//Convert the rotation vector into a matrix here.

//Complete matrix ready to use for OpenGL
float RTMat[] = {rm[0], rm[3], rm[6], 0.0f,
             rm[1], rm[4], rm[7], 0.0f,
             rm[2], rm[5], rm[8], 0.0f,
             tv[0], -tv[1], -tv[2], 1.0f};

祝你好运!

于 2011-11-16T09:17:43.740 回答