代码之家  ›  专栏  ›  技术社区  ›  Pandoro

如何在Android中使用opengles的OpenCV旋转和平移向量?

  •  12
  • Pandoro  · 技术社区  · 16 年前

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

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

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

    2 回复  |  直到 8 年前
        1
  •  11
  •   Pandoro    16 年前

    好吧,经过更多的测试,我终于成功了。虽然我不明白。。。它确实有用。对于将来需要这样做的人,这里是我的解决方案。

    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需要一个列的主顺序,所以所有的东西都需要被转换。(感谢你的评论,我之前已经看到了那一页。)此外,y和z的旋转角度以及y和z的平移需要乘以-1。我觉得这有点奇怪。为什么只有这些而不是x值呢?

    我想这是应该的。但这些角并不完全匹配。我猜这是由一些错误的openGLView配置造成的。因此,尽管我仍然不是100%满意我的解决方案,我想这是我的问题的答案。

        2
  •  2
  •   coder9    15 年前

    潘多罗的方法真的很管用!如果有人想知道“如何将旋转向量转换成旋转矩阵”,我是这样做的。顺便说一下,我在opengl2中使用了这些,而不是在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};