First time here? Check out the FAQ!

Ask Your Question
1

OpenGL 4x4 camera matrix, OpenCV ?x? camera matrix

asked Nov 18 '17

sjhalayka gravatar image

updated Nov 18 '17

In OpenGL, the camera matrix is a 4x4 matrix. Is the camera matrix in OpenCV a 4x4 matrix as well?

The following is the code needed to make a very simple camera matrix. Compatible with OpenGL ES 2.0 and higher. See the camera matrix applied in the full code https://github.com/sjhalayka/blind_poker:

float projection_modelview_mat[16];

init_perspective_camera(y_fov_degrees,
                        static_cast<float>(screen_width)/static_cast<float>(screen_height),
                        0.01f, 2.0f, // Z near, far distances.
                        0, 0, 1, // Camera position.
                        0, 0, 0, // Look at position.
                        0, 1, 0, // Up direction vector.
                        projection_modelview_mat);

... where ...

void get_perspective_matrix(float fovy, float aspect, float znear, float zfar, float (&mat)[16])
{
    // https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
    const float pi = 4.0f*atanf(1.0);

    // Convert fovy to radians, then divide by 2
    float       f = 1.0f / tan(fovy/360.0*pi);

    mat[0] = f/aspect; mat[4] = 0; mat[8] = 0;                              mat[12] = 0;
    mat[1] = 0;        mat[5] = f; mat[9] = 0;                              mat[13] = 0;
    mat[2] = 0;        mat[6] = 0; mat[10] = (zfar + znear)/(znear - zfar); mat[14] = (2.0f*zfar*znear)/(znear - zfar);
    mat[3] = 0;        mat[7] = 0; mat[11] = -1;                            mat[15] = 0;
}

void get_look_at_matrix(float eyex, float eyey, float eyez,
                        float centrex, float centrey, float centrez,
                        float upx, float upy, float upz,
                        float (&mat)[16])
{
    // https://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
    vertex_3 f, up, s, u;

    f.x = centrex - eyex;
    f.y = centrey - eyey;
    f.z = centrez - eyez;
    f.normalize();

    up.x = upx;
    up.y = upy;
    up.z = upz;
    up.normalize();

    s = f.cross(up);
    s.normalize();

    u = s.cross(f);
    u.normalize();

    mat[0] = s.x;  mat[4] = s.y;  mat[8] = s.z;   mat[12] = 0;
    mat[1] = u.x;  mat[5] = u.y;  mat[9] = u.z;   mat[13] = 0;
    mat[2] = -f.x; mat[6] = -f.y; mat[10] = -f.z; mat[14] = 0;
    mat[3] = 0;    mat[7] = 0;    mat[11] = 0;    mat[15] = 1;

    float translate[16];
    translate[0] = 1; translate[4] = 0; translate[8] = 0;  translate[12] = -eyex;
    translate[1] = 0; translate[5] = 1; translate[9] = 0;  translate[13] = -eyey;
    translate[2] = 0; translate[6] = 0; translate[10] = 1; translate[14] = -eyez;
    translate[3] = 0; translate[7] = 0; translate[11] = 0; translate[15] = 1;

    float temp[16];
    multiply_4x4_matrices(mat, translate, temp);

    for(size_t i = 0; i < 16; i++)
        mat[i] = temp[i];
}


void multiply_4x4_matrices(float (&in_a)[16], float (&in_b)[16], float (&out)[16])
{
    /*
    matrix layout:

    [0 4  8 12]
    [1 5  9 13]
    [2 6 10 14]
    [3 7 11 15]
    */

    out[0] =  in_a[0] * in_b[0] +  in_a[4] * in_b[1] +  in_a[8] *  in_b[2] +  in_a[12] * in_b[3];
    out[1] =  in_a[1] * in_b[0] +  in_a[5] * in_b[1] +  in_a[9] *  in_b[2] +  in_a[13] * in_b[3];
    out[2] =  in_a[2] * in_b[0] +  in_a[6] * in_b[1] +  in_a[10] * in_b[2] +  in_a[14] * in_b[3];
    out[3] =  in_a[3] * in_b[0] +  in_a[7] * in_b[1] +  in_a[11] * in_b[2] +  in_a[15] * in_b[3];
    out ...
(more)
Preview: (hide)

Comments

1

May be this blog will help you

LBerger gravatar imageLBerger (Nov 18 '17)edit

Thanks, that is helpful. In fact, there are many helpful blog posts on that blog (as small as it is)!

So the intrinsic camera matrix is 3 rows x 3 columns, and is equivalent to the perspective projection matrix in OpenGL (see get_perspective_matrix() in the code)?

And, the extrinsic camera matrix is 3 rows x 3 columns (http://ksimek.github.io/2012/08/22/ex...), and is equivalent to the modelview matrix in OpenGL (see get_look_at_matrix() in the code)?

Right, or do I have my matrices wrong?

Why aren't the camera matrices 4x4 like in OpenGL, when it apparently takes 4x4 matrices to encode a camera?

sjhalayka gravatar imagesjhalayka (Nov 18 '17)edit

1 answer

Sort by » oldest newest most voted
0

answered Dec 6 '17

sjhalayka gravatar image

updated Dec 6 '17

It turns out that there is a cv::viz::Camera constructor that takes a 4x4 projection matrix. This means that the OpenCV camera is compatible with the OpenGL camera:

https://docs.opencv.org/trunk/dc/d3a/...

Preview: (hide)

Question Tools

2 followers

Stats

Asked: Nov 18 '17

Seen: 2,880 times

Last updated: Dec 06 '17