检测未插入的捕获设备(OpenCV)

Cou*_*sen 7 c++ opencv

我试图检测我的捕捉相机是否被拔掉.我的假设是调用cvQueryFrame将返回NULL,但它会继续返回最后一个有效帧.

有谁知道如何使用OpenCV检测相机插拔事件?这看起来很简陋......我错过了什么?

kar*_*lip 6

遗憾的是,没有API函数可以做到这一点.

但是,我的建议是你创建另一个简单地调用cvCaptureFromCAM()的线程并检查它的结果(在循环内).如果相机断开连接,则应返回NULL.

我会粘贴一些代码来说明我的想法:

// This code should be executed on another thread!
while (1)
{
  CvCapture* capture = NULL;
  capture = cvCaptureFromCAM(-1); // or whatever parameter you are already using
  if (!capture)
  {
    std::cout << "!!! Camera got disconnected !!!!" << std::endl;
    break;
  }

  // I'm not sure if releasing it will have any affect on the other thread
  cvReleaseCapture(&capture); 
}
Run Code Online (Sandbox Code Playgroud)


Cou*_*sen 5

谢谢@karlphillip指出我正确的方向.cvCaptureFromCAM在单独的线程中运行调用有效.当相机拔下插头时,返回值为NULL.

但是,似乎此功能不是线程安全的.但是,锁定同时调用的简单互斥锁cvCaptureFromCAM似乎可以解决问题.我用过boost::thread这个例子,但是人们可以轻松地调整它.

在全球范围内:

// Create a mutex used to prevent simultaneous calls to cvCaptureFromCAM
boost::shared_mutex mtxCapture;

// Flag to notify when we're done.
// NOTE: not bothering w/mutex for this example for simplicity's sake
bool done = false;
Run Code Online (Sandbox Code Playgroud)

切入点是这样的:

int main()
{
  // Create the work and the capture monitoring threads
  boost::thread workThread(&Work);
  boost::thread camMonitorThread(&CamMonitor);

  while (! done)
  {
    // Do whatever
  }

  // Wait for threads to close themselves
  workThread.join();
  camMonitorThread.join();

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

工作线程很简单.唯一需要注意的是,您需要锁定互斥锁,这样才能同时进行调用cvCaptureFromCAM.

// Work Thread
void Work()
{
  Capture * capture = NULL;

  mtxCapture.lock();              // Lock calls to cvCaptureFromCAM   
  capture = cvCaptureFromCAM(-1); // Get the capture object
  mtxCapture.unlock();            // Release lock on calls to cvCaptureFromCAM

  //TODO: check capture != NULL...
  while (! done)
  {
    // Do work
  }

  // Release capture
  cvReleaseCapture(&capture);
}
Run Code Online (Sandbox Code Playgroud)

最后,捕获监控线程,由@karlphillip建议,除了锁定调用cvCaptureFromCAM.在我的测试中,调用cvReleaseCapture非常慢.我cvWaitKey在循环结束时拨打电话,因为我不想听到不断检查.

void CamMonitor()
{
  while (! done)
  {
    CvCapture * capture = NULL;

    mtxCapture.lock();              // Lock calls to cvCaptureFromCAM   
    capture = cvCaptureFromCAM(-1); // Get the capture object
    mtxCapture.unlock();           // Release lock on calls to cvCaptureFromCAM

    if (capture == NULL)
        done = true;                // NOTE: not a thread-safe write...
    else
        cvReleaseCapture(&capture);

    // Wait a while, we don't need to be constantly checking.
    cvWaitKey(2500);
}
Run Code Online (Sandbox Code Playgroud)

我可能最终会实现一个就绪状态标志,它可以检测相机是否重新插入.但这超出了本例的范围.希望有人觉得这很有用.再次感谢,@ karlphillip.