Technical - How do I build my own camera projection matrix?

July 31, 2012 - 1:04pm #1

Vuforia sets up a camera sitting at the origin, pointing in the positive Z direction with X to the right and Y down. For details on this coordinate system see this article: ProjectionMatrixExplained.xml The projection matrix is created using device-specific camera parameters. Here is the code for building the projection matrix from the camera parameters:

float nearPlane = 2.0f;
float farPlane = 2000.0f;

const QCAR::CameraCalibration& cameraCalibration =
                            QCAR::CameraDevice::getInstance().getCameraCalibration();
projectionMatrix = QCAR::Tool::getProjectionGL(cameraCalibration, nearPlane, farPlane);

// The following code reproduces the projectionMatrix above using the camera parameters

QCAR::Vec2F size = cameraCalibration.getSize();
QCAR::Vec2F focalLength = cameraCalibration.getFocalLength();
QCAR::Vec2F principalPoint = cameraCalibration.getPrincipalPoint();

float dx = principalPoint.data[0] - size.data[0] / 2;
float dy = principalPoint.data[1] - size.data[1] / 2;

float x =  2.0f * focalLength.data[0] / size.data[0];
float y = -2.0f * focalLength.data[1] / size.data[1];
float a =  2.0f * dx / size.data[0];
float b = -2.0f * (dy + 1.0f) / size.data[1];
float c = (farPlane + nearPlane) / (farPlane - nearPlane);
float d = -nearPlane * (1.0f + c);

QCAR::Matrix44F mat;
mat.data[0] = x;      mat.data[1] = 0.0f;   mat.data[2] = 0.0f;  mat.data[3] = 0.0f;
mat.data[4] = 0.0f;   mat.data[5] = y;      mat.data[6] = 0.0f;  mat.data[7] = 0.0f;
mat.data[8] = a;      mat.data[9] = b;      mat.data[10] = c;    mat.data[11] = 1.0f;
mat.data[12] = 0.0f;  mat.data[13] = 0.0f;  mat.data[14] = d;    mat.data[15] = 0.0f;

Sometimes it is necessary to find the field of view of the camera, especially when integrating with third party rendering engines. This can be calculated from the CameraCalibration size and focal length parameters. This article describes the relationship between field of view and focal length: http://paulbourke.net/miscellaneous/lens/

Here's a code snippet for finding the vertical field of view:

const QCAR::CameraCalibration& cameraCalibration =
                            QCAR::CameraDevice::getInstance().getCameraCalibration();

QCAR::Vec2F size = cameraCalibration.getSize();
QCAR::Vec2F focalLength = cameraCalibration.getFocalLength();

float fovRadians = 2 * atan(0.5f * size.data[1] / focalLength.data[1]);
float fovDegrees = fovRadians * 180.0f / M_PI;

Finally, you can read more about the camera calibration parameters here: http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/parameters.html

Topic locked