VideoCapture中的互斥锁和线程

时间:2015-10-28 11:24:02

标签: c++ multithreading opencv

我使用工作线程实时获取最新帧,代码如下。但在我的代码中,存在问题。帧始终是第一帧,它没有更新。结果,第一帧执行remap(),重映射结果帧执行下一循环重映射...我不知道为什么帧没有更新。如果我删除行remap()或将此行替换为dilate(frame,frame ..),则帧会一直更新。此外,如果我将帧复制到图像并使用图像进行重映射(),帧可以更新。但是为什么在这种情况下帧无法更新。有人可以帮助我吗?谢谢。

std::mutex mtxCam;
void task(VideoCapture cap, Mat& frame) {
     while (true) {
         mtxCam.lock();
         cap >> frame;
         mtxCam.unlock();  
     }
}
int main() {
    Mat frame, image;
    VideoCapture cap;
    cap.open(0);
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 1600);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
    cap >> frame;
    thread t(task, cap, frame);
    while (true) {
       initUndistortRectifyMap(
        cameraMatrix,  // computed camera matrix
        distCoeffs,    // computed distortion matrix
        Mat(),     // optional rectification (none) 
        Mat(),     // camera matrix to generate undistorted
        Size(1920 * 1.3, 1080 * 1.3),
        //            image.size(),  // size of undistorted
        CV_32FC1,      // type of output map
        map1, map2);   // the x and y mapping functions
      mtxCam.lock();
      remap(frame, frame, map1, map2, cv::INTER_LINEAR);
      frame.copyTo(image);
      mtxCam.unlock();
      ...//image processing loop
    }
}

1 个答案:

答案 0 :(得分:1)

这里有两个问题:

1)您传递单帧,然后每次将视频捕获映射到同一帧,而不会在处理完帧后将其清除。

2)您需要信号机制(信号量),而不是锁定机制(互斥)。

这些方面的东西:

while (true) {
         frame.clear();
         cap >> frame;
         semCam.Give();
     }

  semCam.Take();
  remap(frame, frame, map1, map2, cv::INTER_LINEAR);
  frame.copyTo(image);

您正在处理生产者 - 消费者问题。 因此,线程1生成帧,Thread2使用帧进行图像处理。

Thread1将帧插入队列,向thread2发出信号,表示帧已准备好进行处理,并等待thread2发出帧已经处理过的信号。

算法:

  

线程1

FrameProcessed.Wait()
FrameQueue.insert()
FrameQueueReadyForProcessing.Give()

  

线程2

FrameQueueReadyForProcessing.Wait()
ConsumeFrames(FrameQueue.Pop()) FrameProcessed.Give()

遗憾的是,C ++ 11没有开箱即用的信号量实现。 但你可以推出自己的一个。

https://gist.github.com/yohhoy/2156481