我使用工作线程实时获取最新帧,代码如下。但在我的代码中,存在问题。帧始终是第一帧,它没有更新。结果,第一帧执行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
}
}
答案 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()