Ask Your Question

Revision history [back]

Camera params problem with OpenGL and OpenCV

Hello everyone!

I have a problem that should be easy to solve, but somehow I can't find the solution. My program would animate a teapot on a square drawn on a paper (4 corners known) by looking through a camera. The problem is, the FindExtrinsicCameraParams2 function doesn't seem to give back the right rotation/translation vectors. In my program to avoid casting errors, I started to give direct values whenever possible, but it still doesn't work. My program would be:

int winWidth = 800;
int winHeight = 600;
GLUquadricObj * quadrics;
float cam_angle = 0;
float cam_height = 0;   
float camera_rad = 10;
float xx=0;
float zz=0;
IplImage *pic;
CvFileNode* fnode;
float objA=50; 

CvMat *OP = cvCreateMat(1, 4, CV_32FC3);
CvPoint3D32f *op = (CvPoint3D32f *)OP->data.fl;

CvMat *IP = cvCreateMat(1, 4, CV_32FC2);
CvPoint2D32f *ip = (CvPoint2D32f *)IP->data.fl;

float rv[3];
float rotMat[9];
float t[3];
float tRotMat[16];
float dist[4];
float kMat[9];

CvMat K = cvMat(3, 3, CV_32F, kMat);
CvMat T = cvMat(3, 1, CV_32F, t);
CvMat RV = cvMat(3, 1, CV_32F, rv);
CvMat R = cvMat(3, 3, CV_32F, rotMat);
CvMat DistV = cvMat(1, 4, CV_32F, dist);

double f_x, f_y, c_x, c_y;
double fovY ;
double aspectRatio ;
double frustum_height ;
double frustum_width ;
double offset_x ;
double offset_y ;
int prev_mode;
const double imgWidth=winWidth;
const double imgHeight=winHeight;
double nearCZ=0.1;
double farCZ=100;

GLuint texture;
int loadTexture_Ipl(IplImage *image, GLuint *text);

float lightdir[4] = {1, 1, 1, 0}; 

// Initialization

void onInitialization() {

pic = cvLoadImage("pic4.jpg");
cvFlip(pic,pic,0);
if( pic ){  loadTexture_Ipl(pic, &texture); }
glViewport(0, 0, winWidth, winHeight); // viewport

glEnable( GL_DEPTH_TEST );
float Ia[4] = {0.1, 0.1, 0.1, 1}, Id[4] = {0.8, 0.8, 0.8, 1}, Is[4] = {2, 2, 2, 1};

glLightfv(GL_LIGHT0, GL_AMBIENT, Ia);
glLightfv(GL_LIGHT0, GL_DIFFUSE, Id);
glLightfv(GL_LIGHT0, GL_SPECULAR, Is);
glEnable(GL_LIGHT0);

quadrics = gluNewQuadric();
//////////////////////////////////////////////////////////////////////////////////
CV_MAT_ELEM( K , GLfloat, 0, 0)=565.146179;
CV_MAT_ELEM( K , GLfloat, 0, 1)=0;
CV_MAT_ELEM( K , GLfloat, 0, 2)=314.276642;
CV_MAT_ELEM( K , GLfloat, 1, 0)=0;
CV_MAT_ELEM( K , GLfloat, 1, 1)=567.260010;
CV_MAT_ELEM( K , GLfloat, 1, 2)=238.061874;
CV_MAT_ELEM( K , GLfloat, 2, 0)=0;
CV_MAT_ELEM( K , GLfloat, 2, 1)=0;
CV_MAT_ELEM( K , GLfloat, 2, 2)=1;
/////////////////////////////////////////////////////////////////////////////////
//glMatrixMode(GL_PROJECTION);     
//glLoadIdentity();        
//gluPerspective( 80,                   
//              (GLfloat)winWidth/(GLfloat)winHeight,   // aspect
//                  0.1,                
//                  1000.0              
//              );
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

f_x =   565.146179;         //cvmGet(intrinsic, 0, 0);
f_y =   567.260010;         //cvmGet(intrinsic, 1, 1);
c_x =   314.276642;         //cvmGet(intrinsic, 0, 2);
c_y =   238.061874;         //cvmGet(intrinsic, 1, 2);

fovY = 1/(f_y/imgHeight*2);
aspectRatio = imgWidth/imgHeight * f_x/f_y;

frustum_height = nearCZ * fovY;
frustum_width = frustum_height * aspectRatio;
offset_x = (imgWidth/2 - c_x)/imgWidth * frustum_width * 2;
offset_y = (imgHeight/2 - c_y)/imgHeight * frustum_height * 2;

glGetIntegerv(GL_MATRIX_MODE, &prev_mode);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();              

glFrustum(-frustum_width - offset_x, frustum_width - offset_x, -frustum_height - offset_y, frustum_height - offset_y, nearCZ, farCZ);

glMatrixMode(prev_mode);
}

//TextureCreating
int loadTexture_Ipl(IplImage *image, GLuint *text) {

if (image==NULL) return -1;

glGenTextures(1, text);

glBindTexture( GL_TEXTURE_2D, *text ); 
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width, image->height,0, GL_BGR_EXT, GL_UNSIGNED_BYTE, image->imageData);
return 0;
}

// Display 
void onDisplay( ) {

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 25, 0, 0,-1, 0, 1, 0); 
glLightfv(GL_LIGHT0, GL_POSITION, lightdir);
float blue[4] = {0, 0, 1, 1};
glClearColor(0, 0, 0, 0);           
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     
glEnable( GL_LIGHTING );    
glEnable(GL_LIGHT0);    

glDisable(GL_DEPTH_TEST);
glDrawPixels(pic->width,pic->height,GL_BGR_EXT, GL_UNSIGNED_BYTE,pic->imageData);
glEnable(GL_DEPTH_TEST);

 //   kMat[0] = 565.146179;
 //   kMat[1] = 0;
 //   kMat[2] = 314.276642;
 //   kMat[3] = 0;
 //   kMat[4] = 567.260010;
 //   kMat[5] = 238.061874;
 //   kMat[6] = 0;
 //   kMat[7] = 0;
 //   kMat[8] = 1;

ip[0].x = 537.00;   ip[0].y = 118.00;
ip[1].x = 647.00;   ip[1].y = 118.00;
ip[2].x = 647.00;   ip[2].y = 229.00;
ip[3].x = 537.00;   ip[3].y = 229.00;

op[0].x = -objA;    op[0].y = -objA;
op[1].x = -objA;    op[1].y = objA;
op[2].x = objA;     op[2].y = objA;
op[3].x = objA;     op[3].y = -objA;

glRotatef(90,1,0,0);

cvFindExtrinsicCameraParams2(OP, IP, &K,NULL,&RV, &T,0);

cvRodrigues2(&RV, &R, 0);
const GLfloat M[16]={CV_MAT_ELEM( R , GLfloat, 0, 0),CV_MAT_ELEM( R , GLfloat, 1, 0),CV_MAT_ELEM( R , GLfloat, 2, 0),0,
    CV_MAT_ELEM( R , GLfloat, 0, 1),CV_MAT_ELEM( R , GLfloat, 1, 1),CV_MAT_ELEM( R , GLfloat, 2, 1),0,
    CV_MAT_ELEM( R , GLfloat, 0, 2),CV_MAT_ELEM( R , GLfloat, 1, 2),CV_MAT_ELEM( R , GLfloat, 2, 2),0,
    CV_MAT_ELEM( T , GLfloat, 0, 0)/128,-CV_MAT_ELEM( T , GLfloat, 1, 0)/128,-CV_MAT_ELEM( T , GLfloat, 2, 0)/128,1};
glMultMatrixf(M);

//glPushMatrix();
glMaterialfv( GL_FRONT, GL_DIFFUSE,blue);
glutSolidTeapot(1);
//glPopMatrix();

glutSwapBuffers();
}

Any help is greatly appreciated.