PDA

View Full Version : [Pls Help] Texture video from camera input, add...



wearlab
03-19-2010, 12:51 PM
Hi all,

I'm beginner at OpenGL,

I want to display the video from a camera capture in the OpenGL window, then draw some contours or fonts in this window, and these contours or fonts will move or rotate all the time.

I have 2 problems about this:

(1) I've tried to use the OpenCV to get the camera capture, Iplimage it and texture it in the OpenGL window, it works but still have a problem of the Iplimage should be 2^X (like 256, 515) dimension, then it calls some distortion.
(2) When add some objects (eg. a plane) in the above (1) OpenGL window, I found when I try to rotate the plane, the camera video texture also rotate together with it, but I just want the object(the plane) rotate, the camera video act as the background.

I use Ubuntu 9.10, Eclipse, Opencv, Glut to do this.

Please help, here are the codes, thanks!!!


#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include "ml.h"
#include "cvaux.h"
#include <iostream>
#include <stdlib.h>
#include<stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include<time.h>
#include<stdlib.h>
#include <GL/gl.h>
#include <GL/glut.h>

IplImage *ipl_src_camera = NULL;
IplImage *ipl_src_camera_resize = NULL;

IplImage *frame = NULL;
CvCapture* capture = NULL;
int nFrmNum = 0;

GLuint texture_list_camera;

void texture_load_from_camera() {
/*
* when using the camera direct rendering,
* should shut down the DEPTH_TEST function;
*/
glDisable(GL_DEPTH_TEST);

ipl_src_camera_resize = cvCreateImage(cvSize(256, 256), IPL_DEPTH_8U, 3);
capture = cvCaptureFromCAM(0);
cvNamedWindow("CV window");
while (frame = cvQueryFrame(capture)) {
nFrmNum++;
if (nFrmNum == 1) {
ipl_src_camera = cvCreateImage(cvSize(frame->width, frame->height),IPL_DEPTH_8U, 3);
} else {
cvCopy(frame, ipl_src_camera, 0);
cvResize(ipl_src_camera, ipl_src_camera_resize);

cvFlip(ipl_src_camera_resize, NULL, 0);
cvShowImage("CV window", ipl_src_camera_resize);

printf("load texture from camera\n");
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture_list_camera);

glPixelStorei(GL_UNPACK_ALIGNMENT, texture_list_camera);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
ipl_src_camera_resize->width,
ipl_src_camera_resize->height, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, ipl_src_camera_resize->imageData);

//draw the plan to display the camera video;
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();

// draw another smaller plane on the camera video background
glRotatef(-_angle, 1.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-0.5f, -1.0f, 0.0f);
glVertex3f(1.0f, -0.5f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(-0.3f, 0.2f, 0.0f);
glEnd();
}
if (cvWaitKey(2) >= 0) {
cvReleaseImage(&amp;ipl_src_camera);
cvReleaseImage(&amp;ipl_src_camera_resize);
cvDestroyWindow("CV window");
break;
}
}

void handle_resizeWindow(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float) w / (float) h, 1.0, 200.0);
}

void handle_keyPress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}
//Called every 25 milliseconds
void handle_update(int value) {
_angle += 0.2f;
if (_angle > 360) {
_angle -= 360;
}
glutPostRedisplay();
glutTimerFunc(25, handle_update, 0);
}
void handle_display() {
static int time_base = 0, frame = 0;
frame++;
// Get the number of milliseconds since "glutInit" has been called.
int time = glutGet(GLUT_ELAPSED_TIME);
if (time - time_base > 1000) {
sprintf(&amp;title[44], " (%3.2f FPS)", frame * 1000.0f
/ (time - time_base));
glutSetWindowTitle(title);
time_base = time;
frame = 0;
}

}
void glInit(int argc, char** argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutCreateWindow(title);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
}

int main(int argc, char** argv) {

glInit(argc, argv);
glutKeyboardFunc(handle_keyPress);
glutReshapeFunc(handle_resizeWindow);
glutTimerFunc(25, handle_update, 0);
glutDisplayFunc(handle_display);

texture_load_from_camera();

glutMainLoop();
return 0;
}[/B]

Ehsan Kamrani
03-19-2010, 02:33 PM
1)If your OpenGL implementation supports ARB_texture_non_power_of_two then you can load and render non power of 2 textures.
2)You bind the texture before drawing the plane object. If you rotate your plane, your texture coordinate are also rotated--So the texture also rotates ). Maybe you can use the texture matrix and transform it using the inverse rotation of your rotation matrix, so you can see a fixed texture on a rotating plane. I need to test it though.


You should also move your drawing code to the handle_display() function.

wearlab
03-19-2010, 09:27 PM
Thank you so much for your answer,
I've tried to move the drawing code to the handle_display() function before, and use glutDisplayFunc(handle_display) to call it, but it won't work anyway, and I've no idea why...

You means while the front texture(font or picture) moving, the window background texture(camera video) moving in the converse way?
Actually, I want to use it to track Augmented Reality(AR) markers and the front texture will move and rotate with the marker, may be it's a good way, I'll try it and ARB texture.

Thanks!


1)If your OpenGL implementation supports ARB_texture_non_power_of_two then you can load and render non power of 2 textures.
2)You bind the texture before drawing the plane object. If you rotate your plane, your texture coordinate are also rotated--So the texture also rotates ). Maybe you can use the texture matrix and transform it using the inverse rotation of your rotation matrix, so you can see a fixed texture on a rotating plane. I need to test it though.


You should also move your drawing code to the handle_display() function.

Ehsan Kamrani
03-20-2010, 12:15 AM
1)It's because:
a.You don't switch to the modelview matrix at the beginning of your handle_display() function and don't apply the identity matrix after it.
b.You don't pass the name of handle_display to glutPostRedisplay()
c.You don't add the glutSwapBuffers() function at the end of your handle_display() function.
Try to download a simple GLUT example and study it.

2)If you just want to translate/rotate your front object with its texture(for example font), then you don't need to rotate/translate your background plane. I thought you want to rotate your plane without rotating its texture!


void handle_display()
{
//Clear the depth and color buffers
//Apply Identity matrix
//Apply View matrix ( for example gluLookAt() )
//Bind camera texture
//Render your plane
//Bind font texture
//Rotate/translate/scale
//Draw another plane
//glutSwapBuffers();
}

As you see you simply don't transform your background plane (which consists of the camera texture).