>projection matrix in form of a 4x3 matrix. That matrix will be extended to
>a 4x4 matrix and then loaded onto the OpenGL projection stack. My question
>is basically how and where in the source code this matrix gets defined.
>Does it contain information about the orientation (position, up vector and
>dir vector), the field-of-view angle and the aspect ratio?
It is in 'lib/SRC/Gl/gsub.c'.
The function 'argConvGLcpara2()' generates OpenGL projection matrix
based on real camera parameter and user-specified far/near clip plane.
static void argConvGLcpara2( double cparam[3][4], int width, int height, double
gnear, double gfar, double m[16] )
{
double icpara[3][4];
double trans[3][4];
double p[3][3], q[4][4];
int i, j;
/* Usually we do not need to take care of this */
/* If the specified cparam includes translation and rotation
components, this function divides it into perspective projection
component and translation/rotation components. */
/* Usually cparam does not include translation/rotation components. */
if( arParamDecompMat(cparam, icpara, trans) < 0 ) {
printf("gConvGLcpara: Parameter error!!\n");
exit(0);
}
/* Camera parameters are converted openGL representation. */
/* Camera parameter represents the transformation from camera coordinates
to screen coordinates[pixel]. OpenGL projection matrix represents the
transformation from the camera coordinates to normalized view volume. */
for( i = 0; i < 3; i++ ) {
for( j = 0; j < 3; j++ ) {
p[i][j] = icpara[i][j] / icpara[2][2];
}
}
q[0][0] = (2.0 * p[0][0] / width);
q[0][1] = (2.0 * p[0][1] / width);
q[0][2] = ((2.0 * p[0][2] / width) - 1.0);
q[0][3] = 0.0;
q[1][0] = 0.0;
q[1][1] = (2.0 * p[1][1] / height);
q[1][2] = ((2.0 * p[1][2] / height) - 1.0);
q[1][3] = 0.0;
q[2][0] = 0.0;
q[2][1] = 0.0;
q[2][2] = (gfar + gnear)/(gfar - gnear);
q[2][3] = -2.0 * gfar * gnear / (gfar - gnear);
q[3][0] = 0.0;
q[3][1] = 0.0;
q[3][2] = 1.0;
q[3][3] = 0.0;
/* This multiplies translation/rotation component to above calculated
matrix. Usually we do not need to take care of this. */
for( i = 0; i < 4; i++ ) {
for( j = 0; j < 3; j++ ) {
m[i+j*4] = q[i][0] * trans[0][j]
+ q[i][1] * trans[1][j]
+ q[i][2] * trans[2][j];
}
m[i+3*4] = q[i][0] * trans[0][3]
+ q[i][1] * trans[1][3]
+ q[i][2] * trans[2][3]
+ q[i][3];
}
}
In artoolkit, camera parameter consists of perspective projection
matrix and distortion parameters. The perspective projection
matrix does not contain translation/rotation components. It consists
of field of view (f), aspect ratio(a), skew factor(s) and image center(x,y):
f s x 0
0 af y 0
0 0 1 0
Also usually s = 0. It depends on camera calibration method.
This represents relationship between camera coordinates (X,Y,Z) and
screen coordinates (x, y).
Unit of (X,Y,Z) is usually [mm]. This also depends on camera calibration.
Unit of (x,y) is [pixel].
However, in OpenGL, projection matrix represents relationship between
camera coordinates and normalized view volume. This is similar to screen
coordinates but a little different. It is 3D (X', Y', Z'). Also the values
are within +-1.0 (unit is none), when the position (X,Y,Z) is in view area.
Above function convert camera parameter to OpenGL projection parameter.
One important point is that Z axis directs forward. This is not OpenGL
standard.
If you want to use opposite Z axis direction, you have to change a little:
(1) For camera parameter:
cparam.mat[0][2] *= -1.0;
cparam.mat[1][2] *= -1.0;
cparam.mat[2][2] *= -1.0;
This should be applied before argInit( &cparam, 1.0, 0, 0, 0, 0 ).
But for arInitCparam( &cparam ), original parameter have to be used.
(2) For transformation matrix from arGetTransMat(),
trans[2][0] *= -1.0;
trans[2][1] *= -1.0;
trans[2][2] *= -1.0;
trans[2][3] *= -1.0;
-------------
Above explanation is applied when 3D CG objects are rendered.
If you want to change the field of view, you may change parameters
based on above explanation. However if you want to get good registration,
you also have to change the filed of view of input camera image.
This is done in the different place. But this is just 2D processing.
I think that the easiest way is to change the viewport.
------------------------------------------------------------------
Hirokazu Kato
Graduate School of Engineering Science
Osaka University Phone: +81-6-6850-6381
Email: kato@s ................... Fax: +81-6-6850-6341
URL: http://www.sys.im.hiroshima-cu.ac.jp/people/kato/
|