[英]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.