OpenCV solvePnP到OpenGL:大翻译向量

时间:2013-08-08 16:31:27

标签: objective-c opengl opencv

我正在使用OpenCV和OpenGL构建Mac OSX AR应用程序。它是基于标记的AR,我正在使用名为ARma的库。这个lib只是使用OpenCV函数将可视输出直接写入图像缓冲区。但是我想使用OpenGL进行可视化输出,所以我创建了一个OpenGL视图,我正在使用内部参数(我使用OpenCV凸轮校准程序获得)初始化GL_PROJECTION矩阵,如下所示:

cv::Mat intrMat = tracker.camMatrix; // intrinsic 3x3 matrix
// contains:
// 641.68  0.00    319.50   
// 0.00    641.68  212.50   
// 0.00    0.00    1.00

const float fx = intrMat.at<double>(0,0);
const float fy = intrMat.at<double>(1,1);
const float fovy = 2 * atan(0.5f * screenH / fy) * RAD2DEG;
const float aspect = (screenW*fy) / (screenH*fx);
// GL Perspective values: fx=641.68 / fy=641.68 / fovy=41.01 / aspect=1.33

gluPerspective(fovy, aspect, 0.1, 100.0);

这就是我在类似项目中看到的情况,我直到这里一切正确。当检测到标记时,使用cvFindExtrinsicCameraParams2()(与cv::solvePnP相同)在ARma库中计算外部参数。所以我得到了旋转向量rotVec和转换向量tVec并将它们抛入以下方法来计算GL_MODELVIEW矩阵:

-(void)calcModelviewMat:(GLfloat *)mvMat fromRotVec:(cv::Mat const &)rotVec transVec:(cv::Mat const &)tVec {
    cv::Mat rotMat;
    cv::Mat rotVecGL = rotVec.clone();

    rotVecGL.at<float>(1) = -rotVecGL.at<float>(1);
    rotVecGL.at<float>(2) = -rotVecGL.at<float>(2);

    cv::Rodrigues(rotVecGL, rotMat);

    // init array with zeros
    memset((void *)mvMat, 0, 16 * sizeof(float));

    // set the rotation
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            mvMat[i * 4 + j] = rotMat.at<float>(i, j);
        }
    }

    // set the translation
    for (int i = 0; i < 3; i++) {
        float s = (i > 0) ? -1 : 1;
        mvMat[12 + i] = s * tVec.at<float>(i);
    }

    mvMat[15] = 1;
}

这是将这两个向量转换为我发现here的GL_MODELVIEW矩阵的方法。我相信这是正确的,但问题是我得到的翻译向量中的组件太大(在+/- 500和+/- 1500之间)才能显示。以下是矩阵的示例输出:

0.96    0.05    -0.26   0.00    
0.01    0.97    0.23    0.00    
0.27    -0.22   0.94    0.00    
-72.55  8.47    -479.63 1.00

为什么会这样? solvePnP()在翻译向量中使用了哪些单位,如何将它们转换为可用值以便在我的OpenGL视图中显示?

0 个答案:

没有答案