使用Qt构建OpenCV时,cvShowImage在次线程中阻塞 我正在研究一些传统OpenCV代码(旧C样式,太大而不能转换为C++样式),并使用线程来加快速度。显示是在自己的线程中完成的,带有一个受互斥锁保护的缓冲图像。线程是使用C++11 std::Threads实现的

使用Qt构建OpenCV时,cvShowImage在次线程中阻塞 我正在研究一些传统OpenCV代码(旧C样式,太大而不能转换为C++样式),并使用线程来加快速度。显示是在自己的线程中完成的,带有一个受互斥锁保护的缓冲图像。线程是使用C++11 std::Threads实现的,c++,multithreading,qt,opencv,C++,Multithreading,Qt,Opencv,在使用标准GTK gui构建OpenCV的系统上,一切都很好(在当前版本上的测试时间超过10小时)。在使用Qt作为gui(在OpenCV构建期间设置)的系统上工作时,对cvShowImage的调用会阻塞,但是,其他线程会继续进行 架构是这样的: main(){ cvNamedWindow("Image", CV_WINDOW_NORMAL | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED); std::thread imageAcquisition

在使用标准GTK gui构建OpenCV的系统上,一切都很好(在当前版本上的测试时间超过10小时)。在使用Qt作为gui(在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);
            }
        }
    }
}
main(){
cvNamedWindow(“图像”,CV_窗口|正常| CV_窗口|保留| CV_图形|扩展);
std::thread imageAcquisition(&TrackerBase::getImageLoop,this);
std::thread displayThread(&TrackerBase::displayLoop,this);
while(运行){
如果(新图像){
newImage=假;
{
std::锁和保护锁(img\U互斥锁);
cvCopyImage(img_uu、img_u处理_uu);
}
//执行处理时,将图像转储到img_结果中,同时锁定img_结果互斥体_
{
std::lock\u guard lock(进程互斥锁);
过程();
}
newResult=真;
}
}
}
//从相机中抓取图像,将其转储到img_u中,同时锁定img_u互斥体_
void TrackerBase::getImageLoop(){
while(运行){
如果(!getImage()){
newImage=真;
}
}
}
void TrackerBase::displayLoop(){
如果(显示){
while(运行){
如果(新结果){
{
std::锁\保护锁(img \结果\互斥锁);
cvCopy(img\U结果、img\U结果显示);
}
cvShowImage(“图像”,图像结果显示);
newResult=假;
cvWaitKey(10);
}
}
}
}
请注意,
run
newImage
newResult
都是原子的


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

因此,所有的highgui元素都必须在同一个线程中创建和使用。这包括窗口创建、图像显示、等待键、窗口销毁。因此在本例中,
cvNamedWindow
行需要进入
TrackerBase::displayLoop()
函数(理想情况下在第一个
if
函数的内部)