Multiple cameras and using set() for adjusting frame's witdth and height result in libv4l2 error

asked 2014-11-13 16:04:53 -0600

rbaleksandar gravatar image

Hello!

I have two Logitec Pro 9000 webcams connected to my 64bit Debian notebook. I want to do some stereo-vision and so far it is working great (stereoCalibrate etc.). As you know if the data output is too great (resolution and framerate) you get (especially when using USB cameras) the infamous error:

libv4l2: error turning on stream: No space left on device
VIDIOC_STREAMON: No space left on device
ERROR: Could not read from video stream

I have discovered that for some reason that

cv::VideoCapture::set(CV_CAP_PROP_FRAME_HEIGHT, some_value)

and

cv::VideoCapture::set(CV_CAP_PROP_FRAME_WIDTH, some_value)

don't seem to be working. If I run 2 VideoCapture-s simultaneously I see that the default resolution for these two cameras is 640x480, which I see when I call the cv::VideoCapture::get() equivalent of those two methods I mentioned above. I have to limit the framerate to 15 in order to avoid that libv4l2 related error. Below I have two versions of a very simple program where I set my framerate to 15 and in the second version I also set the exact same resolution that I get when I call cv::VideoCapture::get(CV_CAP_PROP_FRAME_WIDTH/HEIGHT) in the first version:

  • Version 1 (working, no manual setup of the resolution, only framerate):

    VideoCapture cap1(1);
    VideoCapture cap2(2);
    
    if(!cap1.isOpened())
    {
      cout << "Cannot open the video cam [1]" << endl;
      return -1;
    }
    
    if(!cap2.isOpened())
    {
      cout << "Cannot open the video cam [2]" << endl;
      return -1;
    }
    
    cap1.set(CV_CAP_PROP_FPS, 15);
    cap2.set(CV_CAP_PROP_FPS, 15);
    
    double dWidth1 = cap1.get(CV_CAP_PROP_FRAME_WIDTH);
    double dHeight1 = cap1.get(CV_CAP_PROP_FRAME_HEIGHT);
    double dWidth2 = cap2.get(CV_CAP_PROP_FRAME_WIDTH);
    double dHeight2 = cap2.get(CV_CAP_PROP_FRAME_HEIGHT);
    
    cout << "cam[1] Frame size: " << dWidth1 << " x " << dHeight1 << endl;
    cout << "cam[2] Frame size: " << dWidth2 << " x " << dHeight2 << endl;
    namedWindow("cam[1]",CV_WINDOW_AUTOSIZE);
    namedWindow("cam[2]",CV_WINDOW_AUTOSIZE);
    
    while(1)    
    {    
      Mat frame1, frame2;    
      bool bSuccess1 = cap1.read(frame1);    
      bool bSuccess2 = cap2.read(frame2);
    
      if (!bSuccess1)
      {
        cout << "Cannot read a frame from video stream [1]" << endl;
        break;
      }
    
      if (!bSuccess2)
      {
        cout << "Cannot read a frame from video stream [2]" << endl;
        break;
      }
    
      cv::addText(frame1, "cam[1]", Point2f(10,25), cv::fontQt("FONT_HERSHEY_SCRIPT_SIMPLEX", 15, cv::Scalar(255,0,0)));
      cv::addText(frame2, "cam[2]", Point2f(10,25), cv::fontQt("FONT_HERSHEY_SCRIPT_SIMPLEX", 15, cv::Scalar(255,0,0)));
      imshow("cam[1]", frame1);
      imshow("cam[2]", frame2);
    
      if(waitKey(30) == 27)
      {
        cout << "ESC key is pressed by user" << endl;
        break;
      }
    }
    
  • Version 2 (not working, manual setup framerate, manual setup of the resolution results in error I've mentioned at the beginning of my question once I try to capture from the second camera):

    VideoCapture cap1(1);
    VideoCapture cap2(2);
    
    if(!cap1.isOpened())
    {
      cout << "Cannot open the video cam [1]" << endl;
      return -1;
    }
    
    if(!cap2.isOpened())
    {
      cout << "Cannot open the video cam [2]" << endl;
      return -1;
    }
    
    cap1.set(CV_CAP_PROP_FPS, 15);
    cap2.set(CV_CAP_PROP_FPS, 15);
    
    // Values taken from output of Version 1
    cap1.set(CV_CAP_PROP_FRAME_WIDTH, 640);
    cap1.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
    cap2.set(CV_CAP_PROP_FRAME_WIDTH, 640);
    cap2.set(CV_CAP_PROP_FRAME_HEIGHT, 480);    
    
    double dWidth1 = cap1.get(CV_CAP_PROP_FRAME_WIDTH);
    double dHeight1 = cap1.get(CV_CAP_PROP_FRAME_HEIGHT);
    double dWidth2 = cap2.get(CV_CAP_PROP_FRAME_WIDTH ...
(more)
edit retag flag offensive close merge delete