【问题标题】:Trying to close OpenCV window has no effect尝试关闭 OpenCV 窗口没有效果
【发布时间】:2011-08-21 17:45:41
【问题描述】:

我正在使用 OpenCV 捕获网络摄像头图像。这很好用。但是如果我想在按下按钮时关闭 OpenCV,它就不起作用(尝试了 cvDestroyWindow("NameOfWindow")cvDestroyAllWindows())。窗口保持打开状态,应用程序仍在运行。

OpenCV 是在与主 GUI 不同的线程上初始化的。

我在我的 Mac 上使用带有 C++ 的 Juce 框架。但是同样的问题也发生在带有 Qt 和 Windows 窗体的 Windows 上,当 OpenCV 窗口有它自己的 cvNamedWindow 时。

这里是VST插件编辑器类的基本代码:

插件编辑器.cpp

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

#include "PluginProcessor.h"
#include "PluginEditor.h"

//
TestAudioProcessorEditor::TestAudioProcessorEditor (TestAudioProcessor* ownerFilter)
: AudioProcessorEditor (ownerFilter)
{   

    // This is where our plugin's editor size is set.
    setSize (500, 500);

    // open the tracker
    openTracker();
}   

// code for opencv handling
TestAudioProcessorEditor::openTracker() {

    // KEY LINE: Start the window thread
    cvStartWindowThread();

    // Create a window in which the captured images will be presented
    cvNamedWindow( "Webcam", CV_WINDOW_AUTOSIZE );  

    cvWaitKey(0);

    cvDestroyWindow( "Webcam" );
    // window should disappear!
}


TestAudioProcessorEditor::~TestAudioProcessorEditor()
{

}

// paint stuff on the vst plugin surface
void TestAudioProcessorEditor::paint (Graphics& g) {   
}   

【问题讨论】:

  • cvDestroyAllWindows();被一个简单的按钮按下触发时,它会不会?
  • 您是否在产生窗口的同一线程中调用cvDestroy(即称为cvNamedWindow)?
  • @Dan Cecile 是的,我试过了,但它不起作用。
  • @Jacob 我有一个线程来存储和调用我的 opencv 内容。这是个问题吗?
  • @sn3ek:您必须向运行 OpenCV 的线程发送消息,并让该线程调用 cvDestroy。 (例如,在 Qt 中,您可以只向在另一个线程上运行的对象发送信号。)

标签: c++ multithreading opencv


【解决方案1】:

您可能缺少的部分是对cvStartWindowThread 函数的调用。

在 Linux 上,使用 GTK HighGUI,此示例重现了您的问题,直到我调用 cvStartWindowThread

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"

#include <iostream>
using namespace std;

int main( int argc, char** argv )
{
    // KEY LINE: Start the window thread
    cvStartWindowThread();

    // Open a window
    cvNamedWindow("original", 0);

    // Wait until a key gets pressed inside the window
    cvWaitKey(0);

    // Close the window
    cvDestroyWindow("original");

    // Verify that the window is closed
    cout<<"The window should be closed now. (Press ENTER to continue.)"<<endl;
    string line;
    getline(cin, line);
    cout<<"Exiting..."<<endl;
}

如果cvStartWindowThread 没有帮助,请尝试在您拨打cvDestroy 之后再拨打cvWaitKey

要运行该示例,请使用 GCC 编译它:

g++ destroy_window.cpp -o destroy_window -lopencv_core -lopencv_highgui

【讨论】:

  • 我在 Xcode4 中尝试将您的代码作为控制台应用程序,它工作正常。但是,如果我尝试在我的 Juce VST 插件中执行相同的代码,该窗口似乎可以识别销毁方法,但 opencv 窗口冻结并且没有任何反应。我在destroy方法之后抛出了一些日志消息,但它们不会出现在我的日志文件中,所以看起来//Verify that the window is closed之后的验证码不会被执行。
  • @sn3ek 我不得不说这听起来像是多线程死锁; cvDestroyWindow 开始执行,但它只是在继续之前等待另一个线程。您是否可以在调用cvDestroyWindow 之前使用调试器暂停程序,并检查正在运行的其他线程?
  • 我需要更正我的评论。代码cvDestroyWindow() 将被执行。我尝试了一些日志消息。但是窗口不会消失,但是我的插件的其余部分都关闭了,我可以重新打开插件,使用新的 opencv 窗口运行良好。这很奇怪!
  • @sn3ek 您能否在您的问题中发布 Juce VST 插件示例的完整代码?
  • 我在我的问题中添加了基本的 Juce VST 插件文件夹作为 zip 文件。这只是我的基本结构。
猜你喜欢
  • 1970-01-01
  • 2021-02-22
  • 2011-07-06
  • 2015-12-03
  • 2013-04-08
  • 1970-01-01
  • 2011-01-20
  • 2012-02-09
  • 1970-01-01
相关资源
最近更新 更多