A multi camera geometric and photometric calibration example, with OpenGL augmentation.
#include <iostream>
#include <vector>
#include <cv.h>
#include <highgui.h>
#ifdef HAVE_CONFIG_H
#endif
#ifdef HAVE_APPLE_OPENGL_FRAMEWORK
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
static void
{
GLfloat h = (GLfloat) height / (GLfloat) width;
glViewport(0, 0, (GLint) width, (GLint) height);
glutPostRedisplay();
}
static void usage(
const char *s) {
cerr << "usage:\n" << s
<< "[-m <model image>] [-r]\n"
" -m specifies model image\n"
" -r do not load any data\n"
" -t train a new classifier\n"
" -g recompute geometric calibration\n"
" -l rebuild irradiance map from scratch\n";
exit(1);
}
static bool init(
int argc,
char** argv )
{
bool redo_geom=false;
bool redo_training=false;
bool redo_lighting=false;
for (int i=1; i<argc; i++) {
if (strcmp(argv[i], "-m") ==0) {
if (i==argc-1)
usage(argv[0]);
modelFile = argv[i+1];
i++;
} else if (strcmp(argv[i], "-r")==0) {
redo_geom=redo_training=redo_lighting=true;
} else if (strcmp(argv[i], "-g")==0) {
redo_geom=redo_lighting=true;
} else if (strcmp(argv[i], "-l")==0) {
redo_lighting=true;
} else if (strcmp(argv[i], "-t")==0) {
redo_training=true;
} else if (argv[i][0]=='-') {
}
}
if( multi->
init(!redo_training) ==0 )
{
cerr <<"Initialization error.\n";
return false;
}
return true;
}
static void keyboard(
unsigned char c,
int x,
int y)
{
switch (c) {
case 'n' :
case '+' : if (current_cam < multi->cams.size()-1)
break;
case 'p':
break;
case 'q': exit(0); break;
case 'f': glutFullScreen(); break;
}
glutPostRedisplay();
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
int main(
int argc,
char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("Multi-Cam Teapot augmentation");
if (!
init(argc,argv))
return -1;
cvDestroyAllWindows();
glutMainLoop();
return 0;
}
{
if (!tex || !tex->
getIm())
return false;
IplImage *im = tex->
getIm();
int w = im->width-1;
int h = im->height-1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBegin(GL_QUADS);
glColor4f(1,1,1,1);
glTexCoord2f(tex->
u(0), tex->
v(0));
glVertex2f(-1, 1);
glTexCoord2f(tex->
u(w), tex->
v(0));
glVertex2f(1, 1);
glTexCoord2f(tex->
u(w), tex->
v(h));
glVertex2f(1, -1);
glTexCoord2f(tex->
u(0), tex->
v(h));
glVertex2f(-1, -1);
glEnd();
return true;
}
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_LIGHTING);
if (!multi) return;
if (!im) return;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, im->width-1, im->height-1, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
if (detector.object_is_detected) {
glPointSize(2);
glBegin(GL_POINTS);
glColor4f(0,1,0,1);
for (int i=0; i<detector.match_number; ++i) {
glVertex2f(x,y);
}
}
glEnd();
}
glutSwapBuffers();
}
{
{
cout << "failed to load camera calibration.\n";
exit(-1);
}
glutIdleFunc(0);
calib=0;
}
{
int nbdet=0;
for (
int i=0; i<multi->
cams.size(); ++i) {
if (multi->
cams[i]->detect()) nbdet++;
}
if (nbdet>0) {
for (
int i=0; i<multi->
cams.size(); ++i) {
if (multi->
cams[i]->detector.object_is_detected) {
} else {
}
}
}
50,
(multi->
cams.size() > 1 ? 1:2),
(multi->
cams.size() > 1 ? 0:3),
1,
0,
0,
0.0078125,
0.9,
0.001953125,
10,
0.05,
3
))
{
return;
}
}
glutPostRedisplay();
}
{
return;
}
for (
int i=0; i<multi->
cams.size(); ++i) {
}
}
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_LIGHTING);
if (!multi) return;
if (!im) return;
Mat3x4 moveObject, rot, obj2World, movedRT_;
CvMat cvMoveObject = cvMat(3,4,CV_64FC1, moveObject.
m);
CvMat movedRT=cvMat(3,4,CV_64FC1,movedRT_.
m);
double a_proj[3][4];
for( int i = 0; i < 3; i++ )
for( int j = 0; j < 4; j++ ) {
a_proj[i][j] =
cvmGet( proj, i, j );
obj2World.
m[i][j] =
cvmGet(world, i, j);
}
cvReleaseMat(&proj);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glBegin(GL_QUADS);
#ifndef DEBUG_SHADER
glColor4f(1,1,1,0);
glNormal3f(0,0,-1);
#else
float normal[3] = {
for (int i=0; i<3; i++) {
color.val[i] = (g[i]*(color.val[i]/255.0)*irradiance.val[i] + b[i]);
}
glColor3d(color.val[2], color.val[1], color.val[0]);
float half[2] = {
};
glNormal3f(0,0,1);
#endif
glEnd();
#ifndef DEBUG_SHADER
#endif
glDisable(GL_LIGHTING);
#ifdef DEBUG_SHADER
#else
#endif
} else {
GLfloat light_diffuse[] = {1.0, 1, 1, 1.0};
GLfloat light_position[] = {500, 400.0, 500.0, 1};
w2obj.
transform(light_position, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
}
cvReleaseMat(&world);
{
glColor3d(c.val[2], c.val[1], c.val[0]);
#ifndef DEBUG_SHADER
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glutSolidSphere(120, 16, 16);
} else {
glCullFace(GL_FRONT);
glRotatef(-270, 1.0, 0.0, 0.0);
glutSolidTeapot(120);
}
#else
glDisable(GL_CULL_FACE);
glBegin(GL_QUADS);
glNormal3f(0,0,-1);
glEnd();
glutSolidSphere(120, 16, 16);
#endif
}
else
glDisable(GL_LIGHTING);
}
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
{
glColor4f(1,1,1,1);
glTexCoord2d(0,0);
glVertex2d(.5, 1);
glTexCoord2d(1,0);
glVertex2d(1,1);
glTexCoord2d(1,1);
glVertex2d(1,.8);
glTexCoord2d(0,1);
glVertex2d(.5,.8);
}
glEnd();
glEnable(GL_DEPTH_TEST);
}
glutSwapBuffers();
}
{
int nbdet=0;
for (
int i=0; i<multi->
cams.size(); ++i) {
if (multi->
cams[i]->detect()) nbdet++;
}
if (nbdet>0) {
for (
int i=0; i<multi->
cams.size(); ++i) {
if (multi->
cams[i]->detector.object_is_detected) {
} else {
}
}
}
float normal[3];
for (int j=0;j<3;j++) normal[j] = cvGet2D(mat, j, 2).val[0];
cvReleaseMat(&mat);
for (
int i=0; i<multi->
cams.size();++i) {
if (multi->
cams[i]->detector.object_is_detected) {
}
}
}
}
}
}
glutPostRedisplay();
}
{
}