Ask Your Question
1

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

asked 2017-11-18 14:40:28 -0600

sjhalayka gravatar image

updated 2017-11-18 15:31:12 -0600

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)
edit retag flag offensive close merge delete

Comments

1

May be this blog will help you

LBerger gravatar imageLBerger ( 2017-11-18 15:38:40 -0600 )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 ( 2017-11-18 15:50:41 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2017-12-06 14:44:29 -0600

sjhalayka gravatar image

updated 2017-12-06 14:47:08 -0600

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/...

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2017-11-18 14:40:28 -0600

Seen: 2,852 times

Last updated: Dec 06 '17