有一些多线程错误需要进行改正,具体如下:

  1. 在主函数中,应该首先启动线程,然后再获取结果。现在的代码中,先获取结果再启动线程,会导致程序阻塞。

  2. 在 IR 和 VIS 线程中,应该使用局部变量来保存当前帧的图像,而不是使用全局变量。因为在多线程环境下,多个线程同时访问同一个全局变量会导致数据不一致的问题。

  3. 在 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();
}
C++ 多线程视频处理代码优化:解决线程安全和数据一致性问题

原文地址: https://www.cveoy.top/t/topic/odCd 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录