Reputation: 130
I am working on some legacy OpenCV code (old C style, too big to convert to C++ style) and using threading to try to speed things up. Displaying is done in its own thread with a buffered image protected by a mutex. Threads are implemented using C++11 std::threads.
When on a system that has OpenCV built with the standard GTK gui, everything works great (>10 hours of testing on the current version). When working on a system that has Qt as the gui (setup during OpenCV build), the call to cvShowImage blocks, however, the other threads keep on going.
The architecture is something like this:
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);
}
}
}
}
Note that run_
, newImage_
, and newResult_
are all atomic.
Does anybody have any idea as to why this is happening and how to fix it?
Upvotes: 2
Views: 291
Reputation: 130
So it turns out that ALL highgui elements must be created and used in the same thread. That includes window creation, image showing, waitkey, window destruction. So in this case the cvNamedWindow
line needed to go into the TrackerBase::displayLoop()
function (ideally inside of the first if
).
Upvotes: 1