繁体   English   中英

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

[英]Detecting an unplugged capture device (OpenCV)

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

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

遗憾的是,没有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); 
}

谢谢@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;

切入点是这样的:

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;
}

工作线程很简单。 唯一需要注意的是,您需要锁定互斥锁,以免同时调用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);
}

最后,捕获监视线程,由@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);
}

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

这仍然是一个问题。 另一种解决方案是将返回的数据与前一个数据进行比较。 对于工作相机,应始终闪烁。 如果数据相同,您可以确定,凸轮已拔下。 马丁

我认为我有一个很好的解决方法来解决这个问题。 我创建了一个带有零的辅助Mat数组,其分辨率与摄像机的输出相同。 我将它分配给Mat数组,刚刚分配从相机捕获的帧,最后我检查该数组的规范。 如果它等于零则意味着没有从相机捕获的新帧。

VideoCapture cap(0);
if(!cap.isOpened()) return -1;

Mat frame;
cap >> frame;
Mat emptyFrame = Mat::zeros(CV_CAP_PROP_FRAME_WIDTH,     , CV_32F);

for(;;)
{
   frame = emptyFrame;
   cap >> frame;
   if (norm(frame) == 0) break;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM