PDA

View Full Version : Object to screen coordinates



LucaFr
09-02-2008, 10:18 AM
Hi to all,

i am new to this forum and i hope someone can help me with my problem.

Suppose that i have a transformation matrix R, a vector T and that i use R and T to model the object->eye transformation of a point U in object space:

V = R*U+T

Suppose that i have four real number Fx,Fy,Cx,Cy. They represents the intrinsic videocamera parameters:
-Fx = focal length * dimension of pixel in horizontal direction
-Fy = focal length * dimension of pixel in vertical direction
-Cx,Cy = coordinates of the principal point

R and T are computed solving the camera pose estimation problem.

In order to obtain the pixel coordinates and render a cube (the cube is rendered (or "registered") perfectly on a planar rectangular target viewed with the videocamera; i print the target on simple hard paper), i do the following:


(eq 1)
x = -Fx*(V_x/V_z)+Cx
y = -Fy*(V_y/V_z)+Cy

I then use custom made routines to draw lines in order to render a wire-frame cube.

Now i would like to switch to opengl, but i am facing a lot of problems.
First, the projection matrix. I have studied the opengl coordinate transformation pipeline in order to understand how should i setup the projection matrix. To obtain the equation (1), i do the following:

the frustum planes are defined as:
r=right plane
l=left plane
t=top plane
b=bottom plane
f=far plane
n=near plane
the screen width is w, the screen height is h. The viewport
is set at (0,0) of width w and height h. The center of the
viewport is (w/2,h/2)=(ox,oy).

Ok,now let

r-l=(w*n)/Fx
t-b=(h*n)/Fy
r+l=(1-(2*Cx)/w)*((w*n)/Fx)
t+b=(1-(2*Cy)/h)*((h*n)/Fy)

I setup the projection matrix in the standard way, using n=0.1 and f=1000.0 and the values above:


glViewport( 0, 0, 320,240);
glMatrixMode( GL_PROJECTION );
float intrinsic[16];
float near, far;
near = 0.1;
far = 1000.0;
memset(intrinsic, 0, sizeof(intrinsic));
float rml = (320.0*near)/Fx;
float tmb = (240.0*near)/Fy;
float rpl = (1.0-(2.0*Cx)/320.0)*((320.0*near)/Fx);
float tpb = (1.0-(2.0*Cy)/240.0)*((240.0*near)/Fy);
intrinsic[0] = (2.0*near)/rml;
intrinsic[5] = (2.0*near)/tmb;
intrinsic[8] = rpl/rml;
intrinsic[9] = tpb/tmb;
intrinsic[10] = - (far + near)/(far - near);
intrinsic[11] = -1.0;
intrinsic[14] = - (2.0 * far * near)/(far - near);
glLoadMatrixf(intrinsic);


After all the tranformation, the pixel coordinates should be exactly (or at least very near to) the same as those that obtained with equation (1).

But they are not!!! :sorrow:

I must say that i have to do the following in order to setup
the modelview matrix:

float glR[16];
glR[12] = T[0];
glR[13] = -T[1];
glR[14] = T[2];
float S[3] = {-1, 1, -1};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
glR[j*4+i] = R[i][j] * S[i];
}
}

I then load the modelviewmatrix :

glMatrixMode( GL_MODELVIEW );
glLoadMatrixf(glR);

I don't know why i have to put -T[1] (negate the y component
of the translation vector) and negate the first and last row
of the matrix to obtain good result.

I say good because the cube rendered does not coincide with that rendered with my custom routines. The discrepancy is such that is not a problem of line-drawing precision, but is a problem of coordinate transformation or something. The cube seems to stay too high on the paper, but if i translate the object up or down i do not get the results.
Ah, the cube have the lower face at Z=0, the upper face at Z=0.5 (i have tried Z=-0.5). so the lower face must be on the planar target, but it does not!!!

I really need your help!!!!

Best regards,
Luca