5

I'm capturing the webcam image with OpenCV. That works fine. But if I want to close the OpenCV when a button is pressed, it does not work (tried both cvDestroyWindow("NameOfWindow")and cvDestroyAllWindows()). The window stays open and the application is still running.

The OpenCV was initialized on separate thread from the main GUI.

I'm using the Juce Framework with C++ on my Mac. But the same problem occurs also on Windows with Qt and Windows Forms, when the OpenCV Window has it's own cvNamedWindow.

Here is the basic code of the VST plugin editor class:

PluginEditor.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) {   
}   
sn3ek
  • 1,929
  • 3
  • 22
  • 32
  • Does `cvDestroyAllWindows();` when it's triggered by a simple button press? – Dan Cecile Aug 21 '11 at 17:58
  • 1
    Are you calling `cvDestroy` within the same thread which spawned the window (i.e. called `cvNamedWindow`)? – Jacob Aug 21 '11 at 18:02
  • @Dan Cecile yes I tried this but it does not work. – sn3ek Aug 21 '11 at 18:05
  • @Jacob I have a thread where my opencv stuff is stored and called. Is this a problem? – sn3ek Aug 21 '11 at 18:06
  • @sn3ek: Yes, I have experienced problems with controlling a window across threads. – Jacob Aug 21 '11 at 18:11
  • @Jacob How can I deal with it? I need to close the opencv window. But how? – sn3ek Aug 21 '11 at 18:15
  • 1
    @sn3ek: You'll have to send a message to the thread that's running OpenCV, and have that thread make the call to `cvDestroy`. (For example, in Qt, you can just send a signal to an object running on the other thread.) – Dan Cecile Aug 21 '11 at 18:25
  • @Dan Cecile But it also does not work without a thread. First I implemented it without a thread and just made the call cvNamedWindow("Window"); and then cvDestroyAllWindows(); but it didn't destroy the window... – sn3ek Aug 21 '11 at 18:59
  • @sn3ek OK, just to be sure, what kind of error do you get after calling `cvDestroy`? – Dan Cecile Aug 21 '11 at 19:26
  • @Dan Cecile I didn't get an error. Nothing happens. The window stays open and the application is still running. – sn3ek Aug 21 '11 at 19:48

1 Answers1

6

The piece you may be missing is a call to the cvStartWindowThread function.

On Linux, using the GTK HighGUI, this example reproduced your problem, until I put in the call to 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;
}

If cvStartWindowThread doesn't help, try doing an extra call to cvWaitKey after your cvDestroy call.

To run the example, compile it with GCC:

g++ destroy_window.cpp -o destroy_window -lopencv_core -lopencv_highgui
Dan Cecile
  • 2,403
  • 19
  • 21
  • I tried your code as console application in Xcode4 and it works fine. But if I try to execute the same code in my Juce VST Plugin the window seems to recognize the destroy method but the opencv window freezes and nothing happens. I threw some log messages after the destroy method but they won't appear in my log file, so it seems, that the verification code after `//Verify that the window is closed` won't be executed. – sn3ek Aug 21 '11 at 22:05
  • @sn3ek I have to say that sounds like a multithreading deadlock; the `cvDestroyWindow` started executing, but it just waits for another thread before continuing. Are you able to use a debugger to pause the program before `cvDestroyWindow` gets called, and check what other threads are running? – Dan Cecile Aug 21 '11 at 22:22
  • I need to correct my comment. The Code `cvDestroyWindow()` will executed. I tried it with a few log messages. But the window won't disappear, but the rest of my plugin was closed well and I can reopen the plugin working well with a new opencv window. It's weird! – sn3ek Aug 21 '11 at 23:14
  • @sn3ek Can you post the full code for a Juce VST Plugin example in your question? – Dan Cecile Aug 21 '11 at 23:29
  • I've added the basis Juce VST Plugin folder in my question as zip file. This is just the basic structure nothing by me. – sn3ek Aug 21 '11 at 23:47
  • @sn3ek It's important to see how Juce GUI elements, the OpenCV library, and extra threads all interact with each other. It might be some small detail that's causing the problem. Can you modify the example I've posted in my answer so that it works as a Juce VST Plugin, and post the code as text inside your question? – Dan Cecile Aug 21 '11 at 23:55
  • It's the same code. I just removed the console output, but the rest is the same. Just copy and paste the opencv code into the PluginEditor.cpp and include `` and `` and that's it. – sn3ek Aug 22 '11 at 00:34
  • I have added some code. Don't know if it helps. This is the class where I added my OpenCV code for testing purposes. – sn3ek Aug 22 '11 at 00:48
  • @sn3ek let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2722/discussion-between-dan-cecile-and-sn3ek) – Dan Cecile Aug 22 '11 at 01:47