Friday, July 15, 2011

Playing with webcam in OpenCV 2.1

I have posted an article about capturing and processing image using webcam in OpenCV 1.0. Right now I'm trying to upgrade my program to use OpenCV 2.1. Some functions are different but basically most of them are similar.

I'm using Microsoft Visual C++ 2008 as the compiler and Windows Form Application. It's quite straight away. This is an example of the user interface:
Basically, there are many ways of doing this, the one that I choose is using event trigger approach. So the image will be shown every time there's a new event from the camera received by the system.

Here's the details, I assume that you are already familiar with C++, Visual C++ 2008, and installing OpenCV 2.1 in C++ 2008:
  1. include all the needed include files:
    #include < cv.h >
    #include < cxcore.h >
    #include < highgui.h >
  2. Declare the needed objects, to make it simple just declare them as global variables:
    // object for capturing image   
    CvCapture* capture;
    // iplimage objects   
    IplImage* image;
    IplImage* procimage;
    // image size
    double w;
    double h;
    // boolean variables for flag
    bool blnCapInProgress;
    bool blnGrabImage;
  3. Initialize the capture when the start button is clicked.
  4. // size of the image   
    w = 640;
    h = 480;
    // creating the capture object, connecting it to the camera, and set the size   
    capture = cvCreateCameraCapture(0);
    cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, w);
    cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, h);
    // initialize the images and windows   
    image = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 3);
    procimage = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
    cvNamedWindow("continuous", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("gray", CV_WINDOW_AUTOSIZE);
    // declaration of event handle  
    if(capture != NULL)
    this->label1->Text = "ok";

    if (blnCapInProgress)
    // stop the capture // the capture is stopped by removing the event handler..
    Application::Idle -= gcnew EventHandler(this, &OpenCVImage::Form1::ProcessFrame);
    buttonStart->Text = "Start Capture";
    //start the capture // the capture is stopped by adding the event handler..
    Application::Idle += gcnew EventHandler(this, &OpenCVImage::Form1::ProcessFrame);
    buttonStart->Text = "Stop";

    blnCapInProgress = !blnCapInProgress;

  5. The event handler is inside the ProcessFrame function, create a function like this:
    private: System::Void ProcessFrame(System::Object^ sender, System::EventArgs^ e) {
    // query the image from the camera
    image = cvQueryFrame(capture);
    // show the image
    if(image != NULL)
    { // image processing algorithm can be performed here
    cvCvtColor(image, procimage, CV_RGB2GRAY);
    cvShowImage("continuous", image);
    cvShowImage("gray", procimage);
    // grab the image
    cvSaveImage("image.bmp", image);
    cvShowImage("grab image", image);
    blnGrabImage = false;
  6. You can grab the image simply by setting the blnGrabImage variable to true.
  7. And what you can get is something like this... :D