4

I have two cameras that I need to display video from at the same time, either in separate windows or in the same window. However, using the following code, only one of the camera feeds (camera(1)) displays. Could someone point out what needs to be changed in my code, or link to other code that would achieve the desired effect?

N.B. This is NOT for stereo vision.

int main()
{

    //initialize and allocate memory to load the video stream from camera 
    CvCapture *capture1 = cvCaptureFromCAM(0);

    if( !capture1 ) return 1;

    //create a window with the title "Video1"
    cvNamedWindow("Video1");

    while(true) {
        //grab and retrieve each frames of the video sequentially 
        IplImage* frame1 = cvQueryFrame( capture1 );

        if( !frame1 ) break;

        //show the retrieved frame in the "Video1" window
        cvShowImage( "Video1", frame1 );

        //wait for 40 milliseconds
        int c = cvWaitKey(40);

        //exit the loop if user press "Esc" key  (ASCII value of "Esc" is 27) 
        if((char)c==27 ) break;
    }

    //initialize and allocate memory to load the video stream from camera 
    CvCapture *capture2 = cvCaptureFromCAM(1);

    if( !capture2 ) return 1;

    //create a window with the title "Video2"
    cvNamedWindow("Video2");

    while(true) {
        //grab and retrieve each frames of the video sequentially 
        IplImage* frame2 = cvQueryFrame( capture2 );

        if( !frame2 ) break;        

        //show the retrieved frame in the "Video2" window
        cvShowImage( "Video2", frame2 );

        //wait for 40 milliseconds
        int c = cvWaitKey(40);

        //exit the loop if user press "Esc" key  (ASCII value of "Esc" is 27) 
        if((char)c==27 ) break;
    }

    //destroy the opened window
    cvDestroyWindow("Video1"); 
    cvDestroyWindow("Video2");   
    //release memory
    cvReleaseCapture( &capture1 );
    cvReleaseCapture( &capture2 );

    return 0;  

    //VideoCapture1();
    //VideoCapture2();


}
JM92
  • 1,063
  • 3
  • 13
  • 22
  • 1
    The second loop never gets executed because the program stays stuck in the while(true) of the first loop. You also tagged it c++ but are not using proper c++ interfaces. You are using cvFunction() instead of cv::function() and using obsolete IplImage structures rather than Mat. – dvhamme Dec 18 '12 at 10:01

3 Answers3

11

Just to clarify, are you using C or C++? If you are using C++, please use C++ interfaces of OpenCV.

Example below works for me:

#include <opencv2/opencv.hpp>

int main()
{
    //initialize and allocate memory to load the video stream from camera 
    cv::VideoCapture camera0(0);
    cv::VideoCapture camera1(1);

    if( !camera0.isOpened() ) return 1;
    if( !camera1.isOpened() ) return 1;

    while(true) {
        //grab and retrieve each frames of the video sequentially 
        cv::Mat3b frame0;
        camera0 >> frame0;
        cv::Mat3b frame1;
        camera1 >> frame1;

        cv::imshow("Video0", frame0);
        cv::imshow("Video1", frame1);

        //wait for 40 milliseconds
        int c = cvWaitKey(40);

        //exit the loop if user press "Esc" key  (ASCII value of "Esc" is 27) 
        if(27 == char(c)) break;
    }

    return 0;
}
Rasim
  • 1,276
  • 1
  • 11
  • 24
  • I also tried to capture from 2 camaras simultaneously. I did pretty much the same like you, but it didn't work. The first camera opens correctly, but it fails always on the second camera. isOpened() returns always false. Both cameras work, but never at the same time. – WoJo Oct 13 '13 at 15:27
  • 2
    the problem seems to be related to the USB bandwidth, If I connect the cameras to two different USB root hubs it works fine. see: http://stackoverflow.com/questions/11222813/2-usb-cameras-not-working-with-opencv – WoJo Oct 13 '13 at 15:52
  • Yes// connect camera with two different USB port. – Abc Jan 08 '17 at 00:33
3

Try this:

    CvCapture *capture1 = cvCaptureFromCAM(0);
    CvCapture *capture2 = cvCaptureFromCAM(1);

    if( !capture1 ) return 1;
    if (!capture2) return 1 ; 
    cvNamedWindow("Video1");
    cvNamedWindow("Video2") ;

    while(true) {
        //grab and retrieve each frames of the video sequentially 
        IplImage* frame1 = cvQueryFrame( capture1 );
        IplImage* frame2 = cvQueryFrame( capture2 );

        if( !frame1 || !frame2 ) break;

        cvShowImage( "Video1", frame1 );
        cvShowImage( "Video2", frame2 );

        //wait for 40 milliseconds
        int c = cvWaitKey(40);

        //exit the loop if user press "Esc" key  (ASCII value of "Esc" is 27) 
        if((char)c==27 ) break;
    }
tomriddle_1234
  • 3,145
  • 6
  • 41
  • 71
  • Nope, that didn't work. Now it's not displaying either video feed. – JM92 Dec 18 '12 at 03:53
  • @JM92, you should use latest C++ interface, there were issues in the previous video drivers in OpenCV, this also relates to your OS and your camera type. – tomriddle_1234 Dec 18 '12 at 22:00
2

put the declaration of frame1 and frame2 outside the while loop

I've had the same problem creating a WebCam class. Worked fine for a single instance with the declaration of frame and capture inside but multiple instances required the constructor to be passed both the frame and capture pointers.

openCV seemingly can not multi-thread some important facilities

BTW, with X11, to get multi-threading to work with cvWaitKey() you need to link in libX11.so.6 and call XInitThreads(); as the first instruction in main()

hope this helps Dave laine.