c++ - videoCapture 中的互斥锁和线程

标签 c++ multithreading opencv

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

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) 您传递一个帧,然后视频捕获每次都映射到同一帧,而不会在处理该帧后清除它。

2) 你需要一个信号机制(semaphore),而不是一个锁机制(mutex)。

沿着这些线的东西:

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

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

您在这里处理的是生产者-消费者问题。 因此,线程 1 生成帧,线程 2 使用帧进行图像处理。

线程 1 将帧插入队列,向线程 2 发送帧已准备好进行处理的信号,并等待线程 2 发出帧已处理完毕的信号。

算法:

Thread 1

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

Thread 2

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

不幸的是,C++11 没有开箱即用的信号量实现。 但是您可以自己滚动一个。

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

关于c++ - videoCapture 中的互斥锁和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33389748/

相关文章:

python - 使用来自另一个 Python 进程的数据更新小部件,而不阻塞它

Android:同时录制和流式传输

python - OpenCV:对象检测

c++ - OpenCV imread 外来字符

c++ - 返回类型为char*的成员函数在while循环后返回包含不同字符串的地址

c++ - 读取文本文件并创建迷宫

c++ - 四元数到方向 vector

c++ - 取消订阅主题并订阅新的运行时 (C++) (ROS)

c - 服务器架构之谜,C编程

java - HashMap 迭代/删除获取 java.util.ConcurrentModificationException