I am trying to use 2 USB webcams with OpenCV. I can get a visual with one webcam but I haven't done with two webcams. Can anybody help me?


I use this code for a webcam.

void WebCam()
{
    char Vid[] = "WebCam";

    IplImage * frm;
    CvCapture * capture;

    capture = cvCaptureFromCAM(-1); // the parameter for a cam

    if( capture ) {
        cvNamedWindow (Vid);

        do {
            frm = cvQueryFrame( capture );

            if( frm )
                cvShowImage (Vid, frm);

            int k = cvWaitKey( 50 );
            if (k == 27 || k == '\r') // Press ESC and Enter 
                break;                     // for out

        } while( frm );

        cvDestroyWindow( Vid ); // Destroy the window
        cvReleaseCapture( &capture );
    }
    else
        puts( "Can not Open the Webcam" );
}

Thanks a lot.

Recommended Answers

All 14 Replies

By passing -1 to the cvCaptureFromCAM() function, you're telling OpenCV that you don't care what camera is being used, so it uses the first camera it can open.
If you want to use 2 cams, you might have to open them explicitly.

capture_cam0 = cvCaptureFromCAM(0); 
capture_cam1 = cvCaptureFromCAM(1);

Then just create 2 windows, check both if captures are open and release both captures etc.

Is it need to different model webcam or same model?

Haven't tried it before, because I don't have two webcams :) But I don't see why they should be the same model or brand

But I don't understand. How can I show the webcams simultaneously?

I've tried that code

{
    char Vid[] = "WebCam", Vid2[] = "WebCamTwo";

    IplImage * frmOne, *frmTwo;
    CvCapture * capture;
    CvCapture * capture2;

    capture = cvCaptureFromCAM( 0 );
    capture2 = cvCaptureFromCAM( 1 );

    if( !capture ) {
        cout << "UnCaptured One" << endl;
        exit( 1 );
    }
    cvNamedWindow( Vid );

    if( !capture2 ) {
        cout << "Uncaptured Two" << endl;
        exit( 1 );
    }
    cvNamedWindow( Vid2 );

        do {
            frmOne = cvQueryFrame( capture );
            frmTwo = cvQueryFrame( capture2 );

            if( frmOne )
                cvShowImage (Vid, frmOne);

            if( frmTwo )
                cvShowImage (Vid2, frmTwo);

            int k = cvWaitKey( 100 );
            if (k == 27 || k == '\r')
                break;

        } while( frmOne && frmTwo);

        cvDestroyWindow( Vid ); // Pencereyi Yok et
        cvDestroyWindow( Vid2 );
        cvReleaseCapture( &capture );
        cvReleaseCapture( &capture2 );
}

the output is "Uncaptured Two"


So what is the problem?

> capture2 = cvCaptureFromCAM( 1 );
It means this returned NULL.
It also means there was probably a problem with the call.
It also means that there's also probably an error function you can call to find out more about why it returned NULL.
If you RTFM for this function, and look at the "return result" section, see what it has to say about what "NULL" means as a result.

If I could found out, I haven't posted here. I used same model webcams, Can it be a problem?

Try this:

cout << cvcamGetCamerasCount();;

what does it output?

Try this:

cout << cvcamGetCamerasCount();;

what does it output?

The output is 2 but I can't open the second webcam.

I am using same model and brand. What is the problem I don't understand.

#include <iostream>

using namespace std;

#include "cvcam.h"
#include "cv.h"
#include "highgui.h"

#include <windows.h>


CRITICAL_SECTION crSec;


void process (CvCapture * capture, const char * Vid)
{

    IplImage * frm;
        do {
            EnterCriticalSection( &crSec );

            frm = cvQueryFrame( capture );

            if( frm )
                cvShowImage (Vid, frm);

            int k = cvWaitKey( 25 );
            if (k == 27 || k == '\r')
                break;

            LeaveCriticalSection( &crSec );

        } while( frm );
}

DWORD WINAPI threadFunc(LPVOID param)
{
    void ** vParam = reinterpret_cast<void **>( param );

    CvCapture * capture = reinterpret_cast<CvCapture *>( vParam[ 0 ] );
    const char * Vid = reinterpret_cast<const char *>( vParam[ 1 ] );

    process (capture, Vid);

    return EXIT_SUCCESS;
}




int main()
{
    char VidLeft[] = "WebCamLeft";
    char VidRight[] = "WebcamRight";

    HANDLE threadHandle;
    HANDLE threadHandle2;
    DWORD threadID;
    DWORD threadID2;

    CvCapture * capture;
    CvCapture * capture2;

    capture = cvCaptureFromCAM( 0 );
    capture2 = cvCaptureFromCAM( 0 );
    cout << cvcamGetCamerasCount();

    void * vParam[ 2 ] = {capture, VidLeft};
    void * param = vParam;
    void * vParam2[ 2 ] = {capture2, VidRight};
    void * param2 = vParam2;

    if( capture ) {
        cvNamedWindow( VidLeft );
        threadHandle = CreateThread (NULL, 0, 
                                        threadFunc, 
                                        param, 0, 
                                        &threadID);
    }

    if( capture2 ) {
        cout << "heyyo" << endl;
        cvNamedWindow( VidRight );
        threadHandle2 = CreateThread (NULL, 0, 
                                        threadFunc, 
                                        param2, 0, 
                                        &threadID2);
    }

        cvDestroyWindow( VidLeft ); 
        cvReleaseCapture( &capture );

        cvDestroyWindow( VidRight );
        cvReleaseCapture( &capture2 );
}

I tried this code and doesn't work again.

Are you just making stuff up without bothering to read the manuals?

The threads of a single process can use a critical section object for mutual-exclusion synchronization. The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call InitializeCriticalSection or InitializeCriticalSectionAndSpinCount to initialize the object.

Do you do this - nope

> cvDestroyWindow( VidLeft );
> cvReleaseCapture( &capture );
Did you bother to wait for the threads to exit, before deleting all the resources those threads depend on - nope.
The rug is pulled from underneath the threads before they even begin.


How about starting with a tutorial?
http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html

@Salem
You were right and thanks your advice but I tried this code

#include <iostream>

using namespace std;

#include "cvcam.h"
#include "cv.h"
#include "highgui.h"

#include <windows.h>


CRITICAL_SECTION crSec;


void process (CvCapture * capture, const char * Vid)
{

    IplImage * frm;
        do {
            EnterCriticalSection( &crSec );

            frm = cvQueryFrame( capture );

            if( frm )
                cvShowImage (Vid, frm);

            int k = cvWaitKey( 25 );
            if (k == 27 || k == '\r')
                break;

            LeaveCriticalSection( &crSec );

        } while( frm );
}

DWORD WINAPI threadFunc(LPVOID param)
{
    void ** vParam = reinterpret_cast<void **>( param );

    CvCapture * capture = reinterpret_cast<CvCapture *>( vParam[ 0 ] );
    const char * Vid = reinterpret_cast<const char *>( vParam[ 1 ] );

    process (capture, Vid);

    return EXIT_SUCCESS;
}




int main()
{
    char VidLeft[] = "WebCamLeft";
    char VidRight[] = "WebcamRight";

    HANDLE threadHandle;
    HANDLE threadHandle2;
    DWORD threadID;
    DWORD threadID2;

    CvCapture * capture;
    CvCapture * capture2;

    capture = cvCaptureFromCAM( 0 );
    capture2 = cvCaptureFromCAM( 0 );
    cout << cvcamGetCamerasCount();

    void * vParam[ 2 ] = {capture, VidLeft};
    void * param = vParam;
    void * vParam2[ 2 ] = {capture2, VidRight};
    void * param2 = vParam2;

    InitializeCriticalSection( &crSec );

    if( capture ) {
        cvNamedWindow( VidLeft );
        threadHandle = CreateThread (NULL, 0, threadFunc, param, 0, &threadID);
    }

    if( capture2 ) {
        cout << "heyyo" << endl;
        cvNamedWindow( VidRight );
        threadHandle2 = CreateThread (NULL, 0, threadFunc, param2, 0, 
                                         &threadID2);
    }

        DWORD ncount = 2;
        HANDLE lpHandles[2] = {threadHandle, threadHandle2};

        WaitForMultipleObjects (ncount, lpHandles, TRUE, INFINITE);

        DeleteCriticalSection( &crSec );

        cvDestroyWindow( VidLeft ); // Pencereyi Yok et
        cvReleaseCapture( &capture );

        cvDestroyWindow( VidRight ); // Pencereyi Yok et
        cvReleaseCapture( &capture2 );
}

@stonerain,

I am working on the face recognition using two webcam, by OpenCv, so kindly please, if possible can you help me because am very new in OpenCv
am waiting your replay

commented: I can rent you a time machine if you want. -1

I think if you ar using 2 same brand and model divices on windows xp, windows wil see it as one. But on windows 7 I think it's fixed. So what operating system are you using?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.