我有三个同时执行的周期性实时任务,每个任务都在不同的处理器(核心)上使用OpenCV进行视频捕获。
为了在三个任务之间进行同步,我使用了cv::Mat
数组,并且每次交换索引时都使用以避免数据争用。感谢my previous post关于缓冲区读/写同步的答案,我可以提出以下解决方案:
cv::Mat frame[3];
int frame_index_write = 0;
int frame_index_read = 1;
int frame_index_read_ = 2;
int SwapIndex(int *fi){
return *fi = (*fi + 1) % 3;
}
现在,第一个任务捕获一个捕获并将其存储在缓冲区中,并向其他任务广播一个信号,以便他们可以获取捕获的帧:
while (1)
{
capture.grab();
capture.retrieve(frame[frame_index_write], CHANNEL);
SwapIndex(&frame_index_write);
pthread_cond_broadcast(&synch_condition); /* After capturing the frame
signal the displaying tasks*/
}
第二个任务获取捕获的帧并显示它:
while (1)
{
pthread_cond_wait(&synch_condition, &frame_rw); /*wait for the capturing
func to send a signal*/
if (frame[frame_index_read].data)
{
cv::imshow(CAPTURED_IMAGE_WINDOW_NAME, frame[frame_index_read]);
SwapIndex(&frame_index_read);
cv::waitKey(1);
}
else{
std::cout << "Frame reading error" << std::endl;
}
}
第三个任务获取捕获的帧并在显示它之前应用边缘检测过程:
while (1)
{
pthread_cond_wait(&synch_condition, &frame_rw); /*wait for the capturing
func to send a signal*/
if (frame[frame_index_read_].data)
{
cv::cvtColor(frame[frame_index_read_], gray_capture, cv::COLOR_BGR2GRAY);
cv::blur(gray_capture, detected_edges, cv::Size(3, 3));
cv::Canny(detected_edges, detected_edges, 0, 100, 3);
cv::imshow(EDGE_IMAGE_WINDOW_NAME, detected_edges);
SwapIndex(&frame_index_read_);
cv::waitKey(1);
}
else{
std::cout << "Frame reading error" << std::endl;
}
}
我的代码似乎运行正常,结果也符合预期,但是当我在终端上停止执行时,得到以下输出,指示错误:
VIDIOC_DQBUF:参数无效
OpenCV错误:cvarrToMat中的错误参数(未知数组类型),文件/build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/core/src/matrix.cpp,第943行 抛出'cv :: Exception'实例后终止调用 what():/build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/core/src/matrix.cpp:943:错误:(-5)函数cvarrToMat中的未知数组类型
有没有办法处理这种错误?
完整的代码位于Github
在这个主题上的任何帮助将不胜感激。