LihO
LihO

Reputation: 42083

Unable to read frames from VideoCapture from secondary webcam with OpenCV

Code:

Simple example that works perfectly with primary webcam (device 0):

VideoCapture cap(0);

if (!cap.isOpened()) {
     std::cout << "Unable to read stream from specified device." << std::endl;
     return;
}

while (true)
{
    // retrieve the frame:
    Mat frame;
    if (!cap.read(frame)) {
        std::cout << "Unable to retrieve frame from video stream." << std::endl;
        break;
    }
    // display it:
    imshow("MyVideo", frame);

    // check if Esc has been pressed:
    if (waitKey(1) == 27) {
        break;
    }
    // else continue:
}

cap.release();

Problem:

I have a second webcam, which I'd like to use. However, when I replace VideoCapture cap(0); with VideoCapture cap(1);, the stream is being opened correctly (or at least cap.isOpened() returns true) but the cap.read(frame) call returns false and I'm unable to find out why.

What I've tried:

HW, OS, SW details:

My HW: HP ProBook 4510s with built-in webcam that always works perfectly
+ external webcam CANYON CNR-FWCII3, refered by OS as "USB Video Device" (the troublesome one) OS, SW: Windows 8.1 Pro x86, Visual Studio 2012 Pro, OpenCV 2.4.8 ~ using vc11 build

Questions:

  1. Am I missing something?
  2. Is there anything else that I could do?
  3. Is there at least any way how to retrieve some additional information about what the problem might actually be?

... OpenCV's API seems quite poor in this case and everywhere where people seemed to be facing the similar issue, there was someone claiming it to be "OS / HW depnendant" as an excuse.

Any help will be appreciated.

Upvotes: 7

Views: 15468

Answers (3)

Kathonly
Kathonly

Reputation: 1

the fix in my case is disconect any camera conected to a sub hub! even if is only one! use your pc's usb port directly.

Upvotes: 0

Saurav Bhaumick
Saurav Bhaumick

Reputation: 1

easiest way to solve is to read once before checking for success. This code snippet works for me. //

cap.read(frame);
if(!cap.read(frame)){

// ...

Upvotes: 0

LihO
LihO

Reputation: 42083

After some time I've found out that it is always only the first call of read that fails and skipping the first frame started to work fine although the true reason of this behavior remained unknown.

Later James Barnett (see comments above) has pointed out that the reason might be that it takes a while till the camera gets ready for capturing and my current solution looks the following way (C++11's sleep):

#include <chrono>
#include <thread>
...

VideoCapture cap(1);

// give camera some extra time to get ready:
std::this_thread::sleep_for(std::chrono::milliseconds(200));

if (!cap.isOpened()) {
     std::cout << "Unable to read stream from specified device." << std::endl;
     return;
}

while (true)
{
    // retrieve the frame:
    Mat frame;
    if (!cap.read(frame)) {
        std::cout << "Unable to retrieve frame from video stream." << std::endl;
        continue;
    }

    // display it:
    imshow("LiveStream", frame);

    // stop if Esc has been pressed:
    if (waitKey(1) == 27) {
        break;
    }
}

cap.release();

Hopefully some future visitors will find it helpful :)

Upvotes: 5

Related Questions