OpenCV VideoCapture仅在第一次调用glutDisplayFunc回调时返回一个空帧

时间:2014-01-25 17:44:29

标签: c++ opengl opencv webcam glut

我一直在尝试使用OpenCV和freeglut。

该程序涉及从WebCam捕获图像,使用OpenCV处理图像,以及根据处理后的图像使用OpenGL绘制3D对象。

当我只使用OpenCV例程时,它完全正常。

当主循环由GLUT控制时出现问题。当我尝试从 glutDisplayFunc()注册的回调中抓取一个帧时,返回的图像为空。

然而,奇怪的是,当我从 glutIdleFunc()注册的回调中抓取一个帧时,它成功返回一个帧。

在涂鸦后,我发现在第一次调用 display()时无法捕捉到某个帧,并在第二次调用后工作。

目前我的代码正在查询 idle()函数内的一个框架。

关于这样的背景,我有几个问题。

  1. 为什么会发生这种情况?是否因为在VideoCapture获得对网络摄像头的完全访问权限之前,程序在 display()内停止了?或者这纯粹是硬件问题?
  2. 这样安全吗?我完全可以从 idle()中抓取一个框架,但这种方法可以安全使用吗?
  3. 如果不是这样,是否有解决方法?如果这种做法不安全,请有人通过另一种处理此问题的方式通知我?
  4. 该程序基于OS X版本10.9.1构建,正在使用的库是

    • OpenCV 2.4.7.0
    • freeglut 2.0.1

    以下是我的代码的简化版本:

    #include <opencv2/opencv.hpp>
    #include <GL/freeglut.h>
    #include <iostream>
    
    cv::VideoCapture capture;
    cv::Mat render;
    
    void display()
    {
      std::cerr << "Grabbing frame in display()" << std::endl;
    
      capture >> render; // This does not work on first call
    
      if(render.empty()) {
        std::cerr << "Error: Grabbing empty frame in display()" << std::endl;
      }
    }
    
    void idle()
    {
      std::cerr << "Grabbing frame in idle()" << std::endl;
    
      capture >> render; // This always works
    
      if(render.empty()) {
        std::cerr << "Error: Grabbing empty frame in idle()" << std::endl;
      }
    
      glutPostRedisplay();
    }
    
    int main(int argc, char* argv[])
    {
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_RGBA);
      glutInitWindowSize(640, 480);
      int debug_window = glutCreateWindow("Debug");
      glutDisplayFunc(display);
      glutIdleFunc(idle);
    
      capture.open(0);
    
      if(!capture.isOpened()) {
        std::cerr << "Error: Failed to open camera" << std::endl;
        exit(1);
      }
    
      glutMainLoop();
    
      return 0;
    }
    

1 个答案:

答案 0 :(得分:2)

已知问题。

一些草率网络摄像头驱动程序返回第1帧,热身或其他东西。

尝试捕获1帧,之前进入空闲循环