PDA

View Full Version : calibrating projector (2D to 3D)



GLJantan
04-02-2007, 10:37 AM
hi, I'm currently doing a project which involves a user navigation with the aid of projectors and camera. However, I'm unable to finish my project but I was told that I could get a passing grade if I can get the calibration of the projector working. Basically, the projection of the openGL model must be aligned to the surfaces of the room. What I have done so far was measure the room in the real world and do a scaling of 60cm to represent 1 openGL unit.

From the origin to the defined top of the room, the measurement was 180cm. The width of the room was taken to be at 240cm. The six points I used was (1)origin, (2)Top of the room, (3) the halfway point from point 2 to the defined end of the room which was measured at 120cm, (4)the halfway point from origin to the defined end of the room which was measured at 120cm, (5)the halfway point from point 2 to the other defined end of the room which was measured at 120cm and (6)the halfway point from origin to the other defined end of the room which was measured at 120cm. The room was then modelled in openGL according to the scale. Six points were defined in the real world and their corresponding 6 x, y coordinates were found by using the glutMouseFunc() and clicking on the respective points on the surface of the projection. The six points are defined as follows

Xi, Yi, Zi
(1) 0,0,0
(2) 0,3,0
(3) 2,3,0
(4) 2,0,0
(5) 0,2,2
(6) 0,0,2

Real world measurements
(1) 0,0,0
(2) 0,180,0
(3) 120,180,0
(4) 120,0,0
(5) 0,120,120
(6) 0,0,120


The six x,y coordinates I got when using glutMouseFunc() are
(1) 428 489
(2) 430 6
(3) 766, 21
(4) 756, 527
(5) 296, 47
(6) 294, 626

Basically I have to derive a transformation matrix. The formula is as follows

A(12x11) * B(11x1) = C(12x1)

B is the matrix containing 11 unknowns. By rearranging the above,

B = A(pseudo-inverse) * C

I used Matlab to derive the 11 unknowns to get
h[0] = 146.8604;
h[1] = -1.8296;
h[2] = -137.9049;
h[3] = 427.5915;
h[4] = 6.8721;
h[5] = -161.0364;
h[6] = -83.3737;
h[7] = 488.9966;
h[8] = -0.0230;
h[9] = -0.0064;
h[10] = -0.2426;

After this I was unsure how to progress and I tried to define these 11 unknowns as a 11 X 1 matrix and use it in the openGL code but the the output was changed into something nonsensical.

Below is my openGL code :

//#include<GL/glut.h>
#include<glut.h>
#include <stdlib.h>
#include <stdio.h>


float width,height;

void changeSize(int w, int h) {

// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;

// we're storing these values for latter use in the
// mouse motion functions
width = w;
height = h;
float ratio = 1.0* w / h;

// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set the viewport to be the entire window
glViewport(0, 0, w, h);

// Set the correct perspective.
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);

// glLoadIdentity(); // Reset The Current Modelview Matrix
gluLookAt(0.0f,0.0f,5.0f,
0.0f,0.0f,-1.0f,
0.0f,1.0f,0.0f);

}

void renderScene(void) {

/*The matrix was calculated using Matlab
B * A = W
A = B(pseudo inverse) * W
A is the 11 unknowns of the transformation matrix*/

/* In this commented part, when I tried to implement it, it does not work
GLdouble h[11];

h[0] = 146.8604;
h[1] = -1.8296;
h[2] = -137.9049;
h[3] = 427.5915;
h[4] = 6.8721;
h[5] = -161.0364;
h[6] = -83.3737;
h[7] = 488.9966;
h[8] = -0.0230;
h[9] = -0.0064;
h[10] = -0.2426;

glMatrixMode(GL_PROJECTION);

// glLoadIdentity();
// glOrtho(0,1024,0,1024,0,0);
// glOrtho(0,1024,0,768,-2,0);
glMultMatrixd(h);
glMatrixMode(GL_MODELVIEW);

*/

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glPushMatrix();


// glTranslatef(0.0f,0.0f,-7.0f);

glBegin(GL_QUADS); // Draw A Quad

glColor3f(0.6f,1.5f,0.7f); // Set The Color To navy blue
glVertex3f( 3.0f,-1.5f, 0.0f); // Bottom Right Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f,4.0f); // Bottom Left Of The Quad (Bottom)
glVertex3f(0.0f,0.0f, 0.0f); // Top Left Of The Quad (Bottom)
glVertex3f( 4.0f,0.0f,0.0f); //// Top Right Of The Quad (Bottom)

glColor3f(0.7f,1.0f,0.0f); // Set The Color To green
glVertex3f( 4.0f,0.0f,0.0f); // Bottom Right Of The Quad (Back)
glVertex3f(0.0f,0.0f,0.0f); //// Bottom Left Of The Quad (Back)
glVertex3f(0.0f, 3.0f,0.0f); //// Top Left Of The Quad (Back)
glVertex3f( 4.0f, 3.0f,0.0f); // Top Right Of The Quad (Back)

glColor3f(1.0f,0.0f,0.0f); // Set The Color To red
glVertex3f(0.0f, 3.0f, 0.0f); // Top Right Of The Quad (Left)
glVertex3f(-1.0f, 1.5f,4.0f); // Top Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f,4.0f); // Bottom Left Of The Quad (Left)
glVertex3f(0.0f,0.0f, 0.0f); // Bottom Right Of The Quad (Left)


glEnd(); // Done Drawing The Quad

//draw arrow

glTranslatef(1.0f,-1.0f,-10.0f);
glRotatef(45,0,1,0);
glRotatef(90,0,0,1);
glRotatef(45,0,1,0);
// glScalef(0.8f,0.5f,1.0f);


glBegin(GL_POLYGON);
glColor3f(0.0f,0.0f,0.0f);
glVertex2f(-0.5f, -0.5f); //bottom left
glVertex2f(-0.5f, 0.5f); //top left
glVertex2f( 0.5f, 0.5f);
glVertex2f( 1.0f, 0.0f); //pointy end
glVertex2f( 0.5f, -0.5f);


glEnd();


glutSwapBuffers();

}


void testMouse(int button, int state, int x, int y) {
if (state == GLUT_DOWN)
printf("mouseclick x=%d, y = %d\n", x,y);
}


void keyboard (unsigned char key, int x, int y )
{
switch ( key )
{
case 27:
exit ( 0 );
break;
default:
break;
}
}


void main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0,0);
glutInitWindowSize(1300,1024);

glutCreateWindow("Smartspace Room");

glutDisplayFunc(renderScene);
// glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);

//adding here the mouse processing callbacks

glutMouseFunc(testMouse);
glutKeyboardFunc (keyboard);
//glutFullScreen();
glutMainLoop();


}

Can some kind soul assist me pleeeeeeease?