视频捕获中的Mutex和线程

Mutex and thread in videoCapture

本文关键字:Mutex 线程 视频      更新时间:2023-10-16

我使用了一个工作线程来实时获取最新的帧,代码如下。但在我的代码中,存在一个问题。该帧一直是第一帧,它没有更新。因此,第一帧执行remap(),而重新映射结果帧执行下一个循环重新映射。。。我不知道为什么框架没有更新。如果我删除了remap()行或将该行替换为expate(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) 您需要一个信号机制(信号量),而不是一个锁定机制(互斥锁)。

大致如下:

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发送已处理帧的信号。

算法:

线程1

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

线程2

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

不幸的是,C++11没有现成的信号量实现。但你可以自己滚一个。

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