ios – OpenCV OpenGL:使用solvePnP正确构建相机

我有使用OpenCV从iPad相机获得适当的相机姿势的问题.

我正在使用定制的2D标记(基于AruCo library) – 我想使用OpenGL在该标记上渲染3D立方体.

为了接收相机姿势,我正在使用OpenCV中的solvePnP函数.

根据THIS LINK我这样做:

cv::solvePnP(markerObjectPoints, imagePoints, [self currentCameraMatrix], _userDefaultsManager.distCoeffs, rvec, tvec);

tvec.at<double>(0, 0) *= -1; // I don't know why I have to do it, but translation in X axis is inverted

cv::Mat R;
cv::Rodrigues(rvec, R); // R is 3x3

R = R.t();  // rotation of inverse
tvec = -R * tvec; // translation of inverse

cv::Mat T(4, 4, R.type()); // T is 4x4
T(cv::Range(0, 3), cv::Range(0, 3)) = R * 1; // copies R into T
T(cv::Range(0, 3), cv::Range(3, 4)) = tvec * 1; // copies tvec into T
double *p = T.ptr<double>(3);
p[0] = p[1] = p[2] = 0;
p[3] = 1;

相机矩阵& dist系数来自findChessboardCorners函数,imagePoints是手动检测到的标记角(您可以在下面发布的视频中看到它们为绿色方块),而markerObjectPoints是手动硬编码点,代表标记角:

markerObjectPoints.push_back(cv::Point3d(-6, -6, 0));
markerObjectPoints.push_back(cv::Point3d(6, -6, 0));
markerObjectPoints.push_back(cv::Point3d(6, 6, 0));
markerObjectPoints.push_back(cv::Point3d(-6, 6, 0));

因为标记在现实世界中长12厘米,所以我选择了相同的尺寸以便于调试.

结果我收到了4×4矩阵T,我将在OpenCV中用作ModelView矩阵.
使用GLKit绘图功能看起来或多或少像这样:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    // preparations
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    float aspect = fabsf(self.bounds.size.width / self.bounds.size.height);
    effect.transform.projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(39), aspect, 0.1f, 1000.0f);

    // set modelViewMatrix
    float mat[16] = generateOpenGLMatFromFromOpenCVMat(T);
    currentModelMatrix = GLKMatrix4MakeWithArrayAndTranspose(mat);
    effect.transform.modelviewMatrix = currentModelMatrix;

    [effect prepareToDraw];

    glDrawArrays(GL_TRIANGLES, 0, 36); // draw previously prepared cube
}

我不是围绕X轴旋转180度(正如之前链接文章中提到的那样),因为我看起来并不是必要的.

问题是它不起作用!翻译矢量看起来不错,但X和Y旋转搞砸了:(

我录制了一个介绍该问题的视频:

http://www.youtube.com/watch?v=EMNBT5H7-os

我已经尝试了几乎所有的东西(包括逐个反转所有轴),但实际上没有任何效果.

我该怎么办?我该如何正确显示3D立方体?来自solvePnP的平移/旋转向量看起来很合理,所以我猜我无法将这些向量正确映射到OpenGL矩阵.

最佳答案 多亏了
http://answers.opencv.org/的Djo1509,我发现问题是不必要的转置旋转矩阵R矩阵用作矩阵T的一部分,并且不必要的tvec = -R * tvec操作.

欲了解更多信息,请查看there

点赞