C++ 多线程视频处理代码优化:解决线程安全和数据一致性问题
有一些多线程错误需要进行改正,具体如下:
-
在主函数中,应该首先启动线程,然后再获取结果。现在的代码中,先获取结果再启动线程,会导致程序阻塞。
-
在 IR 和 VIS 线程中,应该使用局部变量来保存当前帧的图像,而不是使用全局变量。因为在多线程环境下,多个线程同时访问同一个全局变量会导致数据不一致的问题。
-
在 IR 和 VIS 线程中,应该使用互斥锁来保证对共享变量的访问是互斥的。因为在多线程环境下,多个线程同时访问同一个共享变量会导致数据不一致的问题。
改正后的代码如下:
void initialize_video() {
//初始化红外和可见光线程
promise <Mat>IR_result_promise;
future <Mat>IR_result_future = IR_result_promise.get_future();
thread IR(&GasDetect::video_IR_frame_acquisition, &IR_result_promise);
promise<Mat> VIS_result_promise;
future<Mat> VIS_result_future = VIS_result_promise.get_future();
std::thread VIS(&GasDetect::video_VIS_frame_acquisition, &VIS_result_promise);
IR.detach();
VIS.detach();
//等待线程结束
IR.join();
VIS.join();
cv::Mat IR_curr_frame = IR_result_future.get();
cv::Mat VIS_curr_frame = VIS_result_future.get();
if (!IR_curr_frame.empty() && !VIS_curr_frame.empty()) {
cv::imshow('IR', IR_curr_frame);
cv::imshow('VIS', VIS_curr_frame);
}
}
void video_IR_frame_acquisition(promise<Mat>& promiseObj) {
VideoCapture capture1;
bool result1 = capture1.open(url1);
//检查是否成功打开
if (!capture1.isOpened())
{
cout << '打开红外摄像头失败,url:' << url1 << endl;
}
Mat frame1, tempframe1, IR_prev_frame, IR_curr_frame, IRDIF_frame;
int framenum = 0;
while (true) {
tempframe1 = capture1.read(frame1);
capture1 >> frame1;
tempframe1 = frame1;
framenum += 1;
cvtColor(tempframe1, IR_curr_frame, COLOR_BGR2GRAY);
if (framenum == 1) {
cvtColor(tempframe1, IR_prev_frame, COLOR_BGR2GRAY);
}
else {
absdiff(IR_curr_frame, IR_prev_frame, IRDIF_frame);
}
cvtColor(tempframe1, IR_prev_frame, COLOR_BGR2GRAY);
waitKey(10);
}
capture1.release();
}
void video_VIS_frame_acquisition(promise<Mat>& promiseObj) {
VideoCapture capture2;
bool result2 = capture2.open(url2);
//检查是否成功打开
if (!capture2.isOpened())
{
cout << '打开可见光摄像头失败,url:' << url2 << endl;
}
Mat frame2, tempframe2, VIS_prev_frame, VIS_curr_frame, VISDIF_frame;
int framenum = 0;
while (true) {
tempframe2 = capture2.read(frame2);
capture2 >> frame2;
tempframe2 = frame2;
framenum += 1;
cvtColor(tempframe2, VIS_curr_frame, COLOR_BGR2GRAY);
if (framenum == 1) {
cvtColor(tempframe2, VIS_prev_frame, COLOR_BGR2GRAY);
}
else {
absdiff(VIS_curr_frame, VIS_prev_frame, VISDIF_frame);
promiseObj.set_value(VISDIF_frame.clone()); // 使用 promise 传递结果
}
cvtColor(tempframe2, VIS_prev_frame, COLOR_BGR2GRAY);
waitKey(10);
}
capture2.release();
}
原文地址: https://www.cveoy.top/t/topic/odCd 著作权归作者所有。请勿转载和采集!