sub_o
sub_o

Reputation: 2802

How to create perspective projection matrix, given focal points and camera principal center

I managed to acquire camera's intrinsic and extrinsic parameters using OpenCV, thus I have fx, fy, cx and cy. And I also have the screen / image's width and height.

But how do I create an OpenGL perspective projection matrix from these parameters?

glFrustrum shows how to create projection matrix, given Z near, Z far and the image width and height. But how do I include focal points and camera centers in this matrix?

enter image description here

Upvotes: 21

Views: 19556

Answers (5)

hao li
hao li

Reputation: 437

You have cx, cy, fx, fy, width, height.
And you need left, right, top, bottom in your equations. You can calculate these value using this way.

left = cx * near / -fx
top = cy * near / fy
right = -(width - cx) * near / -fx
bottom = -(height - cy) * near / fy

Upvotes: 0

koshy george
koshy george

Reputation: 680

You can check the following links

Kyle Simek's explanation

My explanation

Upvotes: 13

BConic
BConic

Reputation: 8980

Here is the code to obtain the OpenGL projection matrix equivalent to a computer vision camera with camera matrix K=[fx, s, cx; 0, fy, cy; 0, 0, 1] and image size [W, H]:

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity();            // Reset The Projection Matrix
GLdouble perspMatrix[16]={2*fx/W,0,0,0,2*s/W,2*fy/H,0,0,2*(cx/W)-1,2*(cy/H)-1,(zmax+zmin)/(zmax-zmin),1,0,0,2*zmax*zmin/(zmin-zmax),0};
glMultMatrixd(perspMatrix);

NB: zmin and zmax represent the near and far Z clipping planes. This formulation assumes that the OpenGL world coordinate frame is chosen as follows:

enter image description here

The OpenGL camera is assumed to be located at the origin, looking towards positive Z axis, with a down vector collinear and towards the positive Y axis.

Upvotes: 10

Luca
Luca

Reputation: 1350

In relation to the AldurDisciple answer this is the formulation you need to use if the world coordinate frame is choosen with inverted z axe

inverted z axe

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity();            // Reset The Projection Matrix
GLdouble perspMatrix[16]={2*fx/w,0,0,0,0,2*fy/h,0,0,2*(cx/w)-1,2*(cy/h)-1,-(far+near)/(far-near),-1,0,0,-2*far*near/(far-near),0};
glMultMatrixd(perspMatrix);

Upvotes: 5

Vlad
Vlad

Reputation: 4525

Open GL operates with a frustum which is related to perspective projection with some limits in depth referred as near and far values. Imagine a pyramid lying on its side - this is frustum. Another analogy is a projector beam that extends in its width and height with the distance - this is frustum too. So right, left, bottom, and top are your image coordinates while near and far are your depth limits with the near beint your focal plane. OpenGL will put Cx and Cy in the center of the image plane so you can skip them. The alternative and more natural way to specify frustum is based on viewing angle or field of view (50-60 deg is typical); the function you call is glPerspective() where you still have near and far but instead of sizes specify the angle and aspect ratio. Good luck.

Upvotes: 1

Related Questions