我已经使用工作线程实时获取最新帧,代码如下。但是在我的代码中,有一个问题。该帧一直是第一帧,它没有更新。结果,第一帧做了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 没有开箱即用的信号量实现。 但是您可以自己滚动一个。
关于c++ - videoCapture 中的互斥锁和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33389748/