Sign in to follow this  
binary_bandit

Webcam processing

Recommended Posts

binary_bandit    132
Hiya, I was wondering what a simple way to processing webcam, basically i would like to scan the incoming image for a change in intenstiy value (a torch being turned on), i do most of my game development in opengl. Ive seen OpenML, although i cant find many tutorials or books on this (any pointers?) Ive considered directshow but would like to use on linux also so i think this is prehaps a bad idea (plus it wouldnt work!), and thats why i would like to hack this in OpenML. plus what would be the best algorthim to detect this? a spiral search from the center? or comparing images? cheers! Dave

Share this post


Link to post
Share on other sites
iliak    278
Here's my code to use webcam video stream as an OpenGL's texture.


cWebcam.h

#ifndef CWEBCAM_H
#define CWEBCAM_H

#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#include <Vfw.h>
#include <GL/gl.h>



namespace bradock
{



//
// Recupere l'image de la webcam est en fait une texture
//
class cWebcam
{
public:
cWebcam(void);
~cWebcam(void);

int Init(void);
void Free(void);

protected:
static LRESULT WINAPI CallBack( HWND, LPVIDEOHDR);


private:
HWND hWndCam; // Handle vers la webcam
BOOL CamOn; // True si la webcam est branchee
int cam_width, // Dimension de l'image de la webcam
cam_height;
int tex_width, // Dimension de l'image de la webcam
tex_height;
int Update; // Taux de raffraichissement de l'image
int Treshold; // Detection de mouvement

GLuint gl_grey, // ID textures OpenGL
gl_bgr;

unsigned char *bgr; // The actual bgr picture from the camera
unsigned char *greyscale; // Greyscale
unsigned char *delta_buffer; // Contains the difference between frames
unsigned char *back_buffer[2]; // Used to compare previous frames

};





}
#endif





cWebcamp.cpp



#include "cWebcam.h"

#include "cDebug.h"
#include "cRender.h"






//
// Constructeur
//
cWebcam::cWebcam(void)
{
hWndCam = NULL;
CamOn = false;
cam_width = 160;
cam_height = 120;
tex_width = 256;
tex_height = 256;
Update = 250;
Treshold = 120;
gl_grey = 0;
gl_bgr = 0;
bgr = NULL;
greyscale = NULL;
delta_buffer = NULL;
back_buffer[0] = NULL;
back_buffer[1] = NULL;

}


//
// Destructeur
//
cWebcam::~cWebcam(void)
{
Free();
}



//
// On libere tout
//
void cWebcam::Free(void)
{
// Fermeture de la fenetre de capture
if (hWndCam)
{
capSetCallbackOnFrame(hWndCam, NULL);
DestroyWindow(hWndCam);
hWndCam = NULL;
}

if (bgr)
{
delete[] bgr;
bgr = NULL;
}

if (greyscale)
{
delete[] greyscale;
greyscale = NULL;
}

if (delta_buffer)
{
delete[] delta_buffer;
delta_buffer = NULL;
}

if (back_buffer[0])
{
delete[] back_buffer[0];
back_buffer[0] = NULL;
}

if (back_buffer[1])
{
delete[] back_buffer[1];
back_buffer[1] = NULL;
}

CamOn = false;
}






//
// Initialise la connexion a la webcam
//
int cWebcam::Init(void)
{
cRender *render = cRender::GetInstance();
cDebug *debug = cDebug::GetInstance();
BITMAPINFO capwnd;


// On recupere le Handle de la fenetre de Bradock
HWND hWnd = render->GetWindowHandle();

// Creation de la fenetre de capture
hWndCam = capCreateCaptureWindow(
"BradockCam",
WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
0, 0,
1, 1,
hWnd,
0);
if (!hWndCam)
{
debug->Print(Error, __FUNCTION__, "Failed to create a capture window for the webcam !");
Free();
return 0;
}


// On s'approprie la webcam
CamOn = capDriverConnect(hWndCam, 1);
if (!CamOn)
{
debug->Print(Error, __FUNCTION__, "Capture driver cannot be connected to the capture window.");
Free();
return 0;
}

// On definit le callback a chaque frame
capSetCallbackOnFrame(hWndCam, CallBack);

// On donne le 'this'
capSetUserData(hWndCam, this);

// Definition du taux de rafraichissement
capPreviewRate(hWndCam, Update);

// Desactive le mode preview
capPreview(hWndCam, false);

// Definition du format de l'image que l'on desire recevoir
memset(&capwnd,0,sizeof(BITMAPINFO));
capwnd.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
capwnd.bmiHeader.biWidth = cam_width;
capwnd.bmiHeader.biHeight = cam_height;
capwnd.bmiHeader.biPlanes = 1;
capwnd.bmiHeader.biBitCount = 24;
capwnd.bmiHeader.biCompression = BI_RGB;
capwnd.bmiHeader.biSizeImage = cam_width * cam_height * 3;
capwnd.bmiHeader.biXPelsPerMeter = 100;
capwnd.bmiHeader.biYPelsPerMeter = 100;

if ( ! capSetVideoFormat(hWndCam, &capwnd, sizeof(capwnd)))
{
debug->Print(Error, __FUNCTION__, "Requested bitmap format refused by the webcam (%ix%i), maybe requested webcam' screen size is wrong (try 1/3 resolution like 160x120...) !", cam_width, cam_height);
Free();
return 0;
}

// Creation des textures
glGenTextures(1, &gl_bgr);
glBindTexture(GL_TEXTURE_2D, gl_bgr);
glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_width, tex_height, 0, GL_BGR_EXT,GL_UNSIGNED_BYTE, bgr);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

// GREYSCALE texture
glGenTextures(1, &gl_grey);
glBindTexture(GL_TEXTURE_2D, gl_grey);
glTexImage2D(GL_TEXTURE_2D, 0, 1, tex_width, tex_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, greyscale);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


// Allocation des buffers
bgr = new u_char[tex_width * tex_height * 3];
greyscale = new u_char[tex_width * tex_height];
delta_buffer = new u_char[tex_width * tex_height];
back_buffer[0] = new u_char[tex_width * tex_height];
back_buffer[1] = new u_char[tex_width * tex_height];

memset(bgr, 0, sizeof(u_char) * tex_width * tex_height * 3);
memset(greyscale, 0, sizeof(u_char) * tex_width * tex_height);
memset(delta_buffer, 0, sizeof(u_char) * tex_width * tex_height);
memset(back_buffer[0], 0, sizeof(u_char) * tex_width * tex_height);
memset(back_buffer[1], 0, sizeof(u_char) * tex_width * tex_height);


return gl_bgr;
};


//
// Notre fonction de callback
//
LRESULT WINAPI cWebcam::CallBack(HWND hwnd, LPVIDEOHDR videohdr)
{
// On recupere notre this
cWebcam *pThis = (cWebcam *)capGetUserData(hwnd);

int size = pThis->cam_width;

// Sauvegarde de l'image ligne par ligne
for(int i=0; i<pThis->cam_height; i++)
{
memcpy( &pThis->bgr[i*(size*3)],
&videohdr->lpData[i*(pThis->cam_width*3)],
pThis->cam_width * 3);
}


// On refait la texture
glBindTexture(GL_TEXTURE_2D, pThis->gl_bgr);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0, pThis->tex_width, pThis->tex_height, GL_BGR_EXT, GL_UNSIGNED_BYTE, pThis->bgr);


return true;
}





Hope this will help you
PS: sorry french comments :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this