c++ - 当使用 Qt 构建 OpenCV 时,cvShowImage 在辅助线程中阻塞

标签 c++ multithreading qt opencv

我正在处理一些遗留的 OpenCV 代码(旧的 C 风格,太大而无法转换为 C++ 风格)并使用线程来尝试加快速度。显示是在其自己的线程中完成的,带有受互斥锁保护的缓冲图像。线程是使用 C++11 std::threads 实现的。

在使用标准 GTK gui 构建 OpenCV 的系统上,一切运行良好(在当前版本上进行了超过 10 小时的测试)。当在以 Qt 作为图形用户界面的系统上工作时(在 OpenCV 构建期间设置),对 cvShowImage 的调用会阻塞,但是,其他线程会继续运行。

架构是这样的:

main(){
    cvNamedWindow("Image", CV_WINDOW_NORMAL | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED);

    std::thread imageAcquisition(&TrackerBase::getImageLoop, this);
    std::thread displayThread(&TrackerBase::displayLoop, this); 

    while (run_) {
        if (newImage_) {
            newImage_ = false;
            {
                std::lock_guard<std::mutex> lock(img_mutex_);
                cvCopyImage(img_, img_process_);
            }
            // do processing, will dump an image into img_result_ while locking img_result_mutex_
            {
                std::lock_guard<std::mutex> lock(process_mutex_);
                process();
            }
            newResult_ = true;
        }
    }
}

//Grab an image from a camera, dumps it in img_ while locking img_mutex_
void TrackerBase::getImageLoop(){
    while(run_){
        if (!getImage()) {
            newImage_ = true;
        }
    }
}

void TrackerBase::displayLoop(){
    if(display_) {
        while (run_) {
            if(newResult_) {
                {
                    std::lock_guard<std::mutex> lock(img_result_mutex_);
                    cvCopy(img_result_, img_result_display_);
                }
                cvShowImage("Image", img_result_display_);
                newResult_ = false;
                cvWaitKey(10);
            }
        }
    }
}

请注意,run_newImage_newResult_ 都是原子的。

有人知道为什么会发生这种情况以及如何解决吗?

最佳答案

所以事实证明,必须在同一个线程中创建和使用ALL highgui 元素。这包括窗口创建、图像显示、等待键、窗口销毁。所以在这种情况下,cvNamedWindow 行需要进入 TrackerBase::displayLoop() 函数(最好在第一个 if 内部)。

关于c++ - 当使用 Qt 构建 OpenCV 时,cvShowImage 在辅助线程中阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36043874/

相关文章:

c++ - 类外静态函数的声明不是定义

c++ - 如何使用gnu autotool构建qt项目

python - 在 Python 中使用线程时需要注意的注意事项?

c - 调用fork时是否复制线程?

qt - Qt qmake工具dry run模式如何实现

c++ - + 头文件,在定义 block 中包含文件或仅在文件顶部

c++ - Qt : Display byte from QByteArray

c - 不阻塞 main() 的 pthread_join() 版本 : POSIX

c++ - 从 GridLayout 中删除单元格

c++ - 用QT播放视频