01-12-2006, 10:18 AM

Hi all,

I'm working on a rather unique project here, I think.

I have a digital camera that looks for a target. I am creating a 3D scene that tries to reproduce as accurately as possible the object observed by the camera.

The camera gives me its TILT and PAN angles, as well as the X,Y coordinates (in the camera frame) of the center of the object being tracked.

So far, I have been using the tilt angle to compute the range to the target (since the elevation of both the camera and target is fixed). I then multiply by the sin/cos of the pan angle to get the X/Z coordinates of the OpenGL eyepoint. This works fine and properly calculates the position and renders the scene for any pan/tilt angle.

The problem is implementing the X/Y error from the camera. I'm trying to use gluUnProject to figure out the object coordinates of where a particular X/Y value in the frame should be, then translating by that quantity. The problem is that gluUnProject can move the Y coordinate as well, resulting in a scene that has the object being tracked properly positioned on the screen, but that has the eyepoint height at a different value.

Hopefully I explained what I am looking for here...let me know if you need more explanation.

Here is the code being used here (using Tao in C# if the syntax looks different - the display list has the target centered at 0,0,0). dSin,dTan,dCos are trig functions that take degrees (all angles are in degrees for that matter). FIELD_HEIGHT is the height from the floor to the target object; robot_height is the height from the floor to the camera.

Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Gl.glLoadIdentity();

double range = (-FIELD_HEIGHT+robot_height)/dTan(tilt);

Glu.gluLookAt(-range*dSin(-pan),robot_height,eyeY,-range*dCos(pan),0.0,FIELD_HEIGHT,0.0,0.0,1.0,upY,0 .0);

double[] modelview = new double[16];

Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX,modelview);

double[] projection = new double[16];

Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX,projection );

int[] viewport = new int[4];

Gl.glGetIntegerv(Gl.GL_VIEWPORT,viewport);

double adj_x,adj_y,adj_z;

double unused,winz;

Glu.gluProject(0.0,FIELD_HEIGHT,0.0,modelview,proj ection,viewport,out unused,out unused, out winz);

Glu.gluUnProject(screen_to_camera_px_ratio*panErrP x + glControl.Width/2, screen_to_camera_px_ratio*tiltErrPx + glControl.Height/2,

winz,

modelview,

projection,

viewport,

out adj_x,out adj_y,out adj_z);

Gl.glTranslatef((float)adj_x,(float)adj_y-FIELD_HEIGHT,(float)adj_z);

Gl.glCallList(display_list);

I'm working on a rather unique project here, I think.

I have a digital camera that looks for a target. I am creating a 3D scene that tries to reproduce as accurately as possible the object observed by the camera.

The camera gives me its TILT and PAN angles, as well as the X,Y coordinates (in the camera frame) of the center of the object being tracked.

So far, I have been using the tilt angle to compute the range to the target (since the elevation of both the camera and target is fixed). I then multiply by the sin/cos of the pan angle to get the X/Z coordinates of the OpenGL eyepoint. This works fine and properly calculates the position and renders the scene for any pan/tilt angle.

The problem is implementing the X/Y error from the camera. I'm trying to use gluUnProject to figure out the object coordinates of where a particular X/Y value in the frame should be, then translating by that quantity. The problem is that gluUnProject can move the Y coordinate as well, resulting in a scene that has the object being tracked properly positioned on the screen, but that has the eyepoint height at a different value.

Hopefully I explained what I am looking for here...let me know if you need more explanation.

Here is the code being used here (using Tao in C# if the syntax looks different - the display list has the target centered at 0,0,0). dSin,dTan,dCos are trig functions that take degrees (all angles are in degrees for that matter). FIELD_HEIGHT is the height from the floor to the target object; robot_height is the height from the floor to the camera.

Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Gl.glLoadIdentity();

double range = (-FIELD_HEIGHT+robot_height)/dTan(tilt);

Glu.gluLookAt(-range*dSin(-pan),robot_height,eyeY,-range*dCos(pan),0.0,FIELD_HEIGHT,0.0,0.0,1.0,upY,0 .0);

double[] modelview = new double[16];

Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX,modelview);

double[] projection = new double[16];

Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX,projection );

int[] viewport = new int[4];

Gl.glGetIntegerv(Gl.GL_VIEWPORT,viewport);

double adj_x,adj_y,adj_z;

double unused,winz;

Glu.gluProject(0.0,FIELD_HEIGHT,0.0,modelview,proj ection,viewport,out unused,out unused, out winz);

Glu.gluUnProject(screen_to_camera_px_ratio*panErrP x + glControl.Width/2, screen_to_camera_px_ratio*tiltErrPx + glControl.Height/2,

winz,

modelview,

projection,

viewport,

out adj_x,out adj_y,out adj_z);

Gl.glTranslatef((float)adj_x,(float)adj_y-FIELD_HEIGHT,(float)adj_z);

Gl.glCallList(display_list);