Skip to content

Instantly share code, notes, and snippets.

@suvirbhargav
Created August 25, 2020 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suvirbhargav/af7f3ef77072e52a8b15b0c4fff9c7c6 to your computer and use it in GitHub Desktop.
Save suvirbhargav/af7f3ef77072e52a8b15b0c4fff9c7c6 to your computer and use it in GitHub Desktop.
Using webcam video as texture in OpenGL + some modification to run it with current opencv on Linux.
// Original gist was here: https://gist.github.com/Ashwinning/baeb0835624fedc2e5b809d42417b70e
// Modified from "Video Texture" code
// Copyright (C) 2009 Arsalan Malik (arsalank2@hotmail.com)
//
// On Mac OS X, compile with:
// g++ -o VideoTexture VideoTexture.cpp -framework OpenGL -framework Glut -I
// /usr/local/include/opencv/ $(pkg-config --libs opencv)
//////////////////////////////////////////////////////////////////////////////
// On Linux,
// g++ -o example-opengl example-opengl.cpp -I/usr/include/opencv4
// `pkg-config opencv4 --libs` -lGL -lGLU -lglut -lglfw -lGL -lX11 -lpthread -lXrandr -lXi -ldl
//////////////////////////////////////////////////////////////////////////////
// Open CV includes
//#include <cv.h>
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/videoio/videoio_c.h>
//#include <highgui.h>
// Standard includes
#include <stdio.h>
#include <string.h>
#include <assert.h>
// OpenGL/Glut includes
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
// Timing includes
#include <sys/time.h>
#define KEY_ESCAPE 27
//CvCapture *g_Capture;
cv::VideoCapture g_Capture;
GLint g_hWindow;
// Frame size
int frame_width = 640;
int frame_height = 480;
// current frames per second, slightly smoothed over time
double fps;
// show mirror image
bool mirror = true;
// Return current time in seconds
double current_time_in_seconds();
// Initialize glut window
GLvoid init_glut();
// Glut display callback, draws a single rectangle using video buffer as
// texture
GLvoid display();
// Glut reshape callback
GLvoid reshape(GLint w, GLint h);
// Glut keyboard callback
GLvoid key_press(unsigned char key, GLint x, GLint y);
// Glut idle callback, fetches next video frame
GLvoid idle();
double current_time_in_seconds()
{
timeval timer;
gettimeofday(&timer, NULL);
double seconds = 1e-6 * timer.tv_usec + timer.tv_sec;
return seconds;
}
GLvoid init_glut()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
// Set up callbacks
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(key_press);
glutIdleFunc(idle);
}
GLvoid display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
// These are necessary if using glTexImage2D instead of gluBuild2DMipmaps
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
// Set Projection Matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, frame_width, frame_height, 0);
// Switch to Model View Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(frame_width, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(frame_width, frame_height);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, frame_height);
glEnd();
glFlush();
glutSwapBuffers();
}
GLvoid reshape(GLint w, GLint h)
{
glViewport(0, 0, w, h);
}
GLvoid key_press(unsigned char key, int x, int y)
{
switch (key)
{
case 'f':
printf("fps: %g\n", fps);
break;
case 'm':
mirror = !mirror;
break;
case KEY_ESCAPE:
//cvReleaseCapture(&g_Capture);
glutDestroyWindow(g_hWindow);
exit(0);
break;
}
glutPostRedisplay();
}
GLvoid idle()
{
// start timer
double start_seconds = current_time_in_seconds();
// Capture next frame, this will almost always be the limiting factor in the
// framerate, my webcam only gets ~15 fps
//IplImage *image; // = cvQueryFrame(g_Capture);
cv::Mat image;
//frame = cvQueryFrame( capture ); //assegna frame
g_Capture.read(image);
// Of course there are faster ways to do this with just opengl but this is to
// demonstrate filtering the video before making the texture
if (mirror)
{
// cvFlip(image, NULL, 1);
flip(image, image, +1);
}
// Image is memory aligned which means we there may be extra space at the end
// of each row. gluBuild2DMipmaps needs contiguous data, so we buffer it here
char *buffer = new char[image.cols * image.rows * image.channels()];
int step = image.step; //widthStep;
int height = image.rows;
int width = image.cols;
int channels = image.channels();
char *data = (char *)image.data; //imageData;
// memcpy version below seems slightly faster
//for(int i=0;i<height;i++)
//for(int j=0;j<width;j++)
//for(int k=0;k<channels;k++)
//{
// buffer[i*width*channels+j*channels+k] = data[i*step+j*channels+k];
//}
for (int i = 0; i < height; i++)
{
memcpy(&buffer[i * width * channels], &(data[i * step]), width * channels);
}
// Create Texture
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB,
image.cols,
image.rows,
0,
GL_BGR,
GL_UNSIGNED_BYTE,
buffer);
// Clean up buffer
delete[] buffer;
// Update display
glutPostRedisplay();
double stop_seconds = current_time_in_seconds();
fps = 0.9 * fps + 0.1 * 1.0 / (stop_seconds - start_seconds);
}
int main(int argc, char *argv[])
{
// Create OpenCV camera capture
// If multiple cameras are installed, this takes "first" one
//g_Capture = cvCaptureFromCAM(0);
//assert(g_Capture);
g_Capture.open(0); // open the default camera
if (!g_Capture.isOpened())
{
//std::cout << "Capture not open successfully 0" << std::endl;
printf("Capture not open successfully");
getchar();
//return -1;
}
// capture properties
//frame_height = (int)cvGetCaptureProperty(g_Capture, CV_CAP_PROP_FRAME_HEIGHT);
//frame_width = (int)cvGetCaptureProperty(g_Capture, CV_CAP_PROP_FRAME_WIDTH);
//setting the dimensions of webcam frame
frame_width = g_Capture.get(cv::CAP_PROP_FRAME_WIDTH);
frame_height = g_Capture.get(cv::CAP_PROP_FRAME_HEIGHT);
// Create GLUT Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(frame_width, frame_height);
g_hWindow = glutCreateWindow("Video Texture");
// Initialize OpenGL
init_glut();
glutMainLoop();
return 0;
}
@mohsenkondori
Copy link

Thanks for code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment