Qt, paint image, will this cause memory issue? - c++

//Case 1:
QImage* tImg = new QImage("Some Image Here");
painter->drawImage(x, y, *tImg );
...
delete tImg;
//Case 2:
QImage* tImg = new QImage("Some Image Here");
{
QImage aImg(*tImg);
painter->drawImage(x, y, aImg );
}
...
delete tImg;
I am trying to load several images in a worker thread and draw them out int the main thread. But I am not sure is it ok to delete the image in the worker thread after drawing them out.
//Case 3:
...
//In worker thread
QImage* tImg = new QImage("Some Image Here");
mutex.lock();
matrix.insert(tImg); // matrix is a QList
mutex.unlock();
...
//In main thread
mutex.lock();
foreach(QImage* tImg, matrix)
{
painter->drawImage(x, y, *tImg);
}
mutex.unlock();
...
//In worker thread
mutex.lock();
matrix.remove(tImg);
delete tImg;
mutex.unlock();
Will the above code causing issues? Since the drawImage function is a "pass by const reference". Will this causing any memory issue?
What if delete tImg is on another thread? Will it be safe if I use mutex to make sure the delete tImg only called after painter->drawImage(x, y, *tImg );

The manual memory management is unnecessary. You should leverage Qt to do it for you. You can pass the image through a signal-slot connection, and use the fact that the value will be automatically copied, and any access to it will be automatically synchronized by Qt.
Here's how you could do it, very simply, letting the compiler do all the hard work of resource management for you:
// https://github.com/KubaO/stackoverflown/tree/master/questions/imageloader-36265788
#include <QtWidgets>
#include <QtConcurrent>
First, let's have a class with a signal that is the image source. It has a signal that provides the image, of a const reference type, since any copying will be done automatically by Qt if necessary to cross thread boundaries.
class ImageSource : public QObject {
Q_OBJECT
public:
Q_SIGNAL void hasImage(const QImage & image);
A method generates the image, and emits the signal. As long as automatic connections are used with the hasImage signal, this method can be run in any thread - safely. In our case, we always run this method from the worker thread, but we could run it from the main thread, too - the only difference would be in performance.
/// This method is thread-safe (ignoring the UB of incrementing a shared int)
void generate() {
static auto counter = 0;
QImage img(128, 128, QImage::Format_ARGB32);
img.fill(Qt::white);
QPainter p(&img);
p.drawText(img.rect(), Qt::AlignCenter, QString::number(counter++));
p.end();
emit hasImage(img);
}
};
We'll need an instance of that class, and something to show the image on - say, a QLabel:
int main(int argc, char ** argv) {
QApplication app{argc, argv};
ImageSource source;
QLabel label;
label.show();
We can now connect the hasImage to a functor that sets the label's size and sets the image on it. It then immediately runs the image generator again in a worker thread from the global pool. That's handled automatically by QtConcurrent::run.
The functor runs in the main thread: this is assured by providing the context parameter to the connect: connect(--, --, context, --). The functor runs in label.thread(), just as we wish.
QObject::connect(&source, &ImageSource::hasImage, &label, [&](const QImage & image){
label.setFixedSize(image.size());
label.setPixmap(QPixmap::fromImage(image));
QtConcurrent::run(&source, &ImageSource::generate);
});
Since the connection is automatic, the effect of calling the hasImage signal results in posting of the slot call to the receiving object (label) thread's event queue - here, the queue of the main thread. The event loop picks up the slot call, and executes it. So, even through hasImage has been called in a worker thread, the image is automatically copied and delivered to our functor in the main thread.
Finally, we generate the first image to start the process.
QtConcurrent::run(&source, &ImageSource::generate); // generate the first image
return app.exec();
}
The #include at the end is needed to provide the implementation of the signal hasImage signal, and the metadata describing the ImageSource class. It is generated by moc.
#include "main.moc"
This is complete code, you can paste it into a new project, compile and run; or download the complete project from the github link.
It shows a label that gets its pixmap updated at a rate of approximately 1000/s, on my machine. The application is fully responsive: you can freely move the window, and quit it at any time.
See this answer for another example of a threaded image loader.

Related

QT Multi-threading & Updating GUI

I'm currently updating an existing codebase designed to be used with a GTK GUI to QT, so that it can implement multi threading, as the functions take hours to complete.
This codebase makes frequent calls to a function display(std::string), for the purpose of updating a text display widget. I redefined this function for the new QT version:
In Display.cpp:
void display(std::string output)
{
//
MainWindow * gui = MainWindow::getMainWinPtr(); //Gets instance of GUI
gui->DisplayInGUI(output); //Sends string to new QT display function
}
In MainWindow.cpp:
void MainWindow::DisplayInGUI(std::string output)
{
//converts output to qstring and displays in text edit widget
}
void MainWindow::mainFunction(){
//calls function in existing codebase, which itself is frequently calling display()
}
void MainWindow::on_mainFunctionButton_released()
{
QFuture<void> future = QtConcurrent::run(this,&MainWindow::mainFunction);
}
If I run the main function in a new thread, display(std::string) won't update the GUI until the thread completes. I understand why; the GUI can only be updated in the main thread. Everything else functions as intended.
What I want to implement, but I'm not sure how, is having display(std:string) send a signal back to the main thread to call MainWindow::DisplayInGUI(output_text) with the string that was passed to the display() function. I believe this is the correct way to do it, but correct me if I'm wrong. I want to avoid changing the existing codebase at all costs.
EDIT: I should add that for some dumb reasons entirely out of my control, I am forced to use C++98 (yeah, I know)
You must schedule the code that does UI calls to run in the main thread. I use a simple and easy to use wrapper for that:
#include <QApplication>
#include <QtGlobal>
#include <utility>
template<typename F>
void runInMainThread(F&& fun)
{
QObject tmp;
QObject::connect(&tmp, &QObject::destroyed, qApp, std::forward<F>(fun),
Qt::QueuedConnection);
}
You can now run code (using a lambda in this example, but any other callable will work) in the main thread like this:
runInMainThread([] { /* code */ });
In your case:
void display(std::string output)
{
runInMainThread([output = std::move(output)] {
MainWindow* gui = MainWindow::getMainWinPtr();
gui->DisplayInGUI(output);
});
}
Or you can leave display() as is and instead wrap the calls to it:
runInMainThread([str] { display(std::move(str)); );
The std::move is just an optimization to avoid another copy of the string since you should not pass the string by reference in this case (it would be a dangling reference once the string object goes out of scope.)
This is not a high performance inter-thread communication mechanism. Every call will result in the construction of a temporary QObject and a temporary signal/slot connection. For periodic UI updates, it's good enough and it allows you to run any code in the main thread without having to manually set up signal/slot connections for the various UI update operations. But for thousands of UI calls per second, it's probably not very efficient.
First of all: there's no way to make the getMainWinPtr method thread-safe, so this pseudo-singleton hack should probably go away. You can pass around some application-global context to all the objects that do application-global things like provide user feedback. Say, have a MyApplication : QObject (don't derive from QApplication, it's unnecessary). This can be passed around when new objects are created, and you'd then control the relative lifetime of the involved objects directly in the main() function:
void main(int argc, char **argv) {
QApplication app(argc, argv);
MainWindow win;
MyApplication foo;
win.setApplication(&foo);
// it is now guaranteed by the semantics of the language that
// the main window outlives `MyApplication`, and thus `MyApplication` is free to assume
// that the window exists and it's OK to call its methods
...
return app.exec();
}
Of course MyApplication must take care that the worker threads are stopped before its destructor returns.
To communicate asynchronous changes to QObject living in (non-overloaded) QThreads (including the main thread), leverage the built-in inter-thread communication inherent in Qt's design: the events, and the slot calls that traverse thread boundaries.
So, given the DisplayInGUI method, you need a thread-safe way of invoking it:
std::string newOutput = ...;
QMetaObject::invokeMethod(mainWindow, [mainWindow, newOutput]{
mainWindow->displayInGUI(newOutput);
});
This takes care of the thread-safety aspect. Now we have another problem: the main window can get hammered with those updates much faster than the screen refresh rate, so there's no point in the thread notifying the main window more often than some reasonable rate, it'll just waste resources.
This is best handled by making the DisplayInGUI method thread-safe, and leveraging the timing APIs in Qt:
class MainWindow : public QWidget {
Q_OBJECT
...
static constexpr m_updatePeriod = 1000/25; // in ms
QMutex m_displayMutex;
QBasicTimer m_displayRefreshTimer;
std::string m_newDisplayText;
bool m_pendingRefresh;
...
void timerEvent(QTimerEvent *event) override {
if (event->timerId() == m_displayRefreshTimer.timerId()) {
QMutexLocker lock(&m_displayMutex);
std::string text = std::move(m_newDisplayText);
m_pendingRefresh = false;
lock.release();
widget->setText(QString::fromStdString(text));
}
QWidget::timerEvent(event);
}
void DisplayInGUI(const std::string &str) {
// Note pass-by-reference, not pass-by-value. Pass by value gives us no benefit here.
QMutexLocker lock(&m_displayMutex);
m_newDisplayText = str;
if (m_pendingRefresh) return;
m_pendingRefresh = true;
lock.release();
QMetaObject::invokeMethod(this, &MainWindow::DisplayInGui_impl);
}
private:
Q_SLOT void DisplayInGui_impl() {
if (!m_displayRefreshTimer.isActive())
m_displayRefreshTimer.start(this, m_updatePeriod);
}
};
In a more complex situation you'd likely want to factor out the cross-thread property setting to some "adjunct" class that would perform such operations without the boilerplate.
You could take advantage of the fact that QTimer::singleShot has an overload which, when called with a zero time interval, allows you to effectively schedule a task to be run on a specified thread during that thread's next idle slot...
void QTimer::singleShot(int msec, const QObject *context, Functor functor);
So your MainWindow::mainFunction could be something along the lines of...
void MainWindow::mainFunction ()
{
...
std::string output = get_ouput_from_somewhere();
QTimer::singleShot(0, QApplication::instance(),
[output]()
{
display(output);
});
...
}

QT - Mainwindow doesn't update unless it's closed

I'm trying to update the main window by calling updateGUI function in a thread every 500 ms. The window is displayed but not updated with the new values unless I close the window. When I do so, a new window is opened with the new value. I found this question but it didn't answer my question. I knew that (as stated in qt documentation)
QApplication::exec enters the main event loop and waits until
exit() is called.
I tried to use processEvents() but the main window is opened and closed repeatedly and very fast that I can't even see it. Here is my code:
float distanceToObject;
bool objectDetected;
Modes currentMode;
void timerStart(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]()
{
while (true)
{
auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
int updateGUI(void)
{
int argc = 0;
char **argv = NULL;
QApplication a(argc, argv);
MainWindow w;
// Set text of a label
w.setDistance(QString::number(distanceToObject));
// Also update objectDetected and currentMode values
w.show();
//a.processEvents();
return a.exec();
}
void sendMsg(void)
{
// Send heartbeat signal to another device
}
void receiveMsg(void)
{
// Read messages from the other device and update the variables
// These two values change continuously
objectDetected = true;
distanceToObject = 5.4;
}
void decide(void)
{
// The core function of the program. Takes relatively long time
// Run a decision-making algorithm which makes decisions based on the values received from the other device.
// Update some variables according to the made decisions
currentMode = Auto;
// Execute functions according to the made decisions.
setMode(currentMode);
}
int main(void)
{
timerStart(updateGUI, 500);
timerStart(sendMsg, 1000);
timerStart(receiveMsg, 10);
timerStart(decide, 500);
}
How can I update the main window with the variables' values correctly?
Your thread does not update the MainWindow, but it does create an entirely new QApplication and MainWindow on every iteration. Your thread should be stuck inside QApplication::exec until you quit the application (e.g. by closing the window). Only then should your thread's loop make further progress.
In general, you must be very careful when doing updates from outside the main thread, since typically GUI operations must be performed inside the main thread.
Think about using QThread, which already comes with its own event loop, which you can use to notify/update your window using a respective slot.
Without further details about what you are actually trying to achieve, it is not possible to give you further direction. I, at least, recommend that you create your QApplication and MainWindow inside the main thread (e.g. main). Then it depends what you are trying to 'update'. If you need to progress some data, then you can do that within your second thread and send the results to your MainWindow instance using signal-slot. If you need to draw onto the window, then this either has to be done in the main thread directly, or you might find a way to render into a separate buffer (i.e. QImage) from within your thread and then send this buffer to the main thread for drawing it into the window.
I try to sketch how something like this can be done. Notice, however, that this it neither complete nor compilable, but merely an outline.
First, you have your MainWindow and add to it a signal, that notifies all observers to start doing their work (will become clear in a moment). Furthermore, you add slots that will be invoked whenever one of your values changes. Those slots run in the main thread (and are members of the MainWindow) and thus can update the window however they need to:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
// constructors and stuff
void startWorking()
{
emit startWorkers();
}
public slots:
void onModeChanged(Modes m)
{
// update your window with new mode
}
void onDistanceChanged(float distance)
{
// update your window with new distance
}
signals:
void startWorkers();
};
Next, you build a Worker class, that encapsulates all the 'background work' you like to do (basically what your thread did in your original code):
class Worker : public QObject
{
Q_OBJECT
public:
// constructors and stuff
public slots:
void doWork()
{
while(!done)
{
// do stuff ...
Modes m = // change mode
emit modeModified(m);
// do stuff ...
float distance = // compute distance
emit distanceModified(distance);
// do stuff ...
}
}
signals:
void modeModified(Modes m);
void distanceModified(float distance);
};
Note, that Worker must inherit QObject and that your doWork method must be a public slot. Furthermore, you add a signal for each of the values you like your MainWindow to be informed about. No implementation for them is needed, since it is generated by the Qt MOC (Meta Object Compiler). Whenever one of the respective values changes, simply emit the corresponding signal and pass the new value.
Lastly, you put everything together:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow window;
// create a worker object
Worker* worker = new Worker;
// connect signals and slots between worker and main window
QObject::connect(worker, &Worker::modeModified,
&window, &MainWindow::onModeChanged);
QObject::connect(worker, &Worker::distanceModified,
&window, &MainWindow::onDistanceChanged);
QObject::connect(&window, &MainWindow::startWorkers,
worker, &Worker::doWork);
// create a new thread
QThread* thread = new QThread;
// send worker to work inside this new thread
worker->moveToThread(thread);
thread->start();
// show window and start doing work
window.show();
window.startWorking();
// start main loop
int result = app.exec();
// join worker thread and perform cleanup
return result;
}
Alright, let's go through it. First, you create your QApplication and MainWindow inside your main thread. Next, create an instance of your Worker object (could create multiple here). Then you connect the signals of the worker to the slots of the window and vice versa. Once these connections are established, whenever you emit a signal, the connected slot is invoked by Qt (and passed values are transmitted). Notice, that this connection works across thread boundaries. Whenever a signal is emitted from a thread different then the receiving object's thread, Qt will send a message, which is processed in the receiving object's thread.
Then you tell Qt that you want your worker to live inside another thread using QObject::moveToThread. See here for a very detailed explanation of how to correctly use QThread and objects inside it.
The rest is then simple. show your window and start processing. Here different ways are possible. I just call the startWorking method here, which then emits the startWorkers signal, which is connect to the worker's doWork method, such that doWork will start executing after this signal is received by the other thread.
You then call QApplication::exec which runs the main thread's event loop, where all these signals are processed by Qt. Once your application is closed (e.g. by calling quit or closing the main window) the exec method returns and you are back in main. Notice, that you need to correctly close the thread (e.g. by sending an addition signal that stops the while loop) and join it. You also should delete all the allocated objects (worker, thread). I omitted this here for simplicity of the code example.
Answering your Question
I have many functions, e.g., updateClips and mavReceive that should be called periodically and run independently from each other. I should create a different Worker class for each function, as each has different signals, and a QThread object for each of these functions, right? I don't need startTimer() anymore? If yes, how can I control the calling interval for each function (used to be done in startTimer()
from the comment:
The answer greatly depends on what exactly you mean by "should be called periodically". Who is supposed to call them? The user? Or should they just be executed periodically?
So in principle, you can have multiple workers in one thread. However, if they are supposed to do work all the time (spin in a while loop) it does not make sense, since one is running and all others are blocked. In that case you would have one thread for each worker.
If I understand you correctly, you are interested in updating something periodically (e.g. every 500ms). In that case I highly recommend using the QTimer. You can set an interval and then start it. The timer will then periodically emit the timeout signal, which you can connect to whatever function (more precisely slot) you want to have executed.
An updated version of the Worker could look like this:
class Worker : public QObject
{
Q_OBJECT
public:
Worker()
{
QObject::connect(&modeTimer_, &QTimer::timeout,
this, &Worker::onModeTimerTimeout);
QObject::connect(&distanceTimer_, &QTimer::timeout,
this, &Worker::onDistanceTimerTimeout);
modeTimer_.start(500); // emit timeout() every 500ms
distanceTimer_.start(100); // emit timeout() every 100ms
}
public slots:
void onModeTimerTimeout()
{
// recompute mode
Modes m = // ...
emit modeModified(m);
}
void onDistanceTimerTimeout()
{
// recompute distance
float distance = // ...
emit distanceModified(distance);
}
signals:
void modeModified(Modes m);
void distanceModified(float distance);
private:
QTimer modeTimer_;
QTimer distanceTimer_;
};
Notice, the connections established in the constructor. Whenever one of the timers times out, the connected slot is invoked. This slot then may compute whatever it needs to and afterwards send the result back to the MainWindow in the main thread using the same signal as before.
So, as you see, you can have multiple timers / re-computations / update signals within one Worker (and thus, one thread). However, the crucial point for an implementation is, how long the computations take. If they take very long (e.g. nearly as long as the intervals) then you should think about using multiple threads to speed up the computation (meaning: perform one computation in each thread). As I slowly seem to get a clearer picture of what you want to achieve, I am wondering whether it is only about these periodic updates that you 'misused' the thread for in your question. If this is indeed the case, then you do not need that thread and Worker at all. Then simply add the timers to your MainWindow and connect their timeout signal to the respective slot of the MainWindow directly.

QImage on QThreadPool fails

I am trying to load multiple QImage objects from files using a threadpool. I have created my own QRunnable subclass to load the image from a file and copy it into a buffer:
class ImageLoader : public QRunnable
{
public:
ImageLoader(const QString &filename, char **buffer, int *size) :
QRunnable(),
filename(filename),
buffer(buffer),
size(size)
{}
// QRunnable interface
void run() {
QImage image(filename);
(*size) = image.byteCount();
(*buffer) = new char[(*size)];
memcpy_s(*buffer), (*size), image.constBits(), image.byteCount());
}
private:
const QString filename;
char **buffer;
int *size;
};
The code works fine if executed on the main thread, but as soon as I run the runnable on a QThreadPool, I get a huge bunch of errors, that basically all say the same:
QObject::moveToThread: Current thread (0x2a023ae6550) is not the object's thread (0x2a023ae65c0).
Cannot move to target thread (0x2a023aca0f0)
The first 2 addresses change each message, I assume they represent the different threads of the pool. Whats interesting:
The first and the second are never the same, however, they are all of the same "group", i.e. the first address of the first error can become the second address of the second error etc...
The third address always stays the same, it's the address of the main (gui) thread.
Any Ideas why that happens or how to fix it? I read the documentation of QImage but wasn't able to find anything about threads in there, except:
Because QImage is a QPaintDevice subclass, QPainter can be used to draw directly onto images. When using QPainter on a QImage, the painting can be performed in another thread than the current GUI thread.
Is solved the problem myself:
The path I passed to the QImage was invalid. I don't know how this was able to produce such an error, but after I fixed the path, it works just fine!

Repaint splash screen from thread / disable assertion

Problem
I want to use a QTimer to update a derived QSplashScreen that draws a progress bar (using paint commands, not a widget) to estimate when the program will start running.
By necessity, this happens prior to the exec call of the QCoreApplication. I've gotten this to work (in release mode only) on both X11 and Windows, by putting a timer in a second thread, and calling a function in the splash screen which updates the progress and repaints the widget. However, this doesn't work in debug mode as it produces the following error:
"ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread."
I'm not really worried about this assertion as the code doesn't crash in release and it's just a splash screen, however I need to be able to run the program in debug so I'd like to either a) refactor the code so it doesn't trigger the assertion, or b) dissable this particular assertion.
Tried:
Using update() instead of repaint(). This doesn't cause an assertion, but it also doesn't repaint because the main thread is too busy loading in the shared libraries, etc, and the timer events don't get processed until I'm ready to call finish on the splash screen.
starting QTimer in main loop. Same result as above.
Using a QT::QueuedConnection. Same result.
Main
#include <QApplication>
#include <QtGui>
#include <QTimer>
#include <QThread>
#include "mySplashScreen.h"
#include "myMainWindow.h" // contains a configure function which takes a
// LONG time to load.
int main( int argc, char* argv[] )
{
// estimate the load time
int previousLoadTime_ms = 10000;
QApplication a(argc, argv);
MySplashScreen* splash = new MySplashScreen(QPixmap(":/splashScreen"));
// progress timer. Has to be in a different thread since the
// qApplication isn't started.
QThread* timerThread = new QThread;
QTimer* timer = new QTimer(0); // _not_ this!
timer->setInterval(previousLoadTime_ms / 100.0);
timer->moveToThread(timerThread);
QObject::connect(timer, &QTimer::timeout, [&]
{
qApp->processEvents(); splash->incrementProgress(1);
});
QObject::connect(timerThread, SIGNAL(started()), timer, SLOT(start()));
timerThread->start();
splash->show();
a.processEvents();
myMainWindow w;
QTimer::singleShot(0, [&]
{
// This will be called as soon as the exec() loop starts.
w.configure(); // this is a really slow initialization function
w.show();
splash->finish(&w);
timerThread->quit();
});
return a.exec();
}
Splash Screen
#include <QSplashScreen>
class MySplashScreen : public QSplashScreen
{
Q_OBJECT
public:
MySplashScreen(const QPixmap& pixmap = QPixmap(), Qt::WindowFlags f = 0)
: QSplashScreen(pixmap, f)
{
m_pixmap = pixmap;
}
virtual void drawContents(QPainter *painter) override
{
QSplashScreen::drawContents(painter);
// draw progress bar
}
public slots:
virtual void incrementProgress(int percentage)
{
m_progress += percentage;
repaint();
}
protected:
int m_progress = 0;
private:
QPixmap m_pixmap;
};
MyMainWindow
#include <QMainWindow>
class myMainWindow : public QMainWindow
{
public:
void configure()
{
// Create and configure a bunch of widgets.
// This takes a long time.
}
}
The problems are because the design is backwards. The GUI thread should not be doing any loading. The general approach to GUI threads is: do no work in the GUI thread. You should spawn a worker thread to load what you need loaded. It can post events (or invoke slots using a queued connection) to the GUI thread and its splash screen.
Of course, the worker thread should not create any GUI objects - it can't instantiate anything deriving from QWidget. It can, though, instantiate other things, so if you need any expensive-to-obtain data, prepare it in the worker thread, and then cheaply build a QWidget in the GUI thread once that data is available.
If your delays are due to library loading, then do load all the libraries in a worker thread, explicitly, and ensure that all of their pages are resident in memory - for example by reading the entire .DLL after you're loaded it as a library.
The MyMainWindow::configure() could be called in a worker thread, as long as it doesn't invoke any QWidget methods nor constructors. It can do GUI work, just not visible on screen. For example, you can load QImage instances from disk, or do painting on QImages.
This answer provides several approaches to executing a functor in a different thread, GCD-style.
If you are constructing widgets that are expensive to construct, or construct many of them, it's possible to make sure that the event loop can run between the instantiation of each widget. For example:
class MainWindow : public QMainWindow {
Q_OBJECT
QTimer m_configureTimer;
int m_configureState = 0;
Q_SLOT void configure() {
switch (m_configureState ++) {
case 0:
// instantiate one widget from library A
break;
case 1:
// instantiate one widget from library B
...
break;
case 2:
// instantiate more widgets from A and B
...
break;
default:
m_configureTimer.stop();
break;
}
}
public:
MainWindow(QWidget * parent = 0) : QMainWindow(parent) {
connect(&m_configureTimer, SIGNAL(timeout()), SLOT(configure()));
m_configureTimer.start(0);
//...
}
};

Memory leak in OpenCV function: cvQueryFrame()

I have a problem with IplImage* returned from cvQueryFrame... Its memory is never released by library. And documentation says:
The returned image should not be released or modified by the user.
Well... how do I get my memory back? The program eats memory until it crashes. I would like to release allocated memory for each IplImage* after frame processing finishes. Code is this:
// In `process` thread:
CvCapture* camera;
camera = cvCreateCameraCapture(1);
assert(camera);
while(true)
{
main = cvQueryFrame(camera);
// Do something useful with images
emit sendImage(main); // Send Image to the UI thread
}
UPDATE:
This is QThread subclass:
#include <QThread>
class ImageFetcher : public QThread
{
Q_OBJECT
public:
explicit ImageFetcher(QObject *parent = 0);
signals:
void run();
public slots:
};
Implementattion:
void ImageFetcher::run()
{
CvCapture* camera = cvCreateCameraCapture(0);
IplImage* image;
while(true)
{
image = cvQueryFrame(camera);
// process image
}
// exec();
}
main():
int main(int argc, char *argv[])
{
QApplication a(argc,argv);
ImageFetcher thread;
thread.start();
return a.exec();
}
As far as I could test, there's no leak in v2.3.1 for Linux.
Here is what happens: an image is allocated by cvQueryFrame() when this function is called by the first time, and then this image is reused on all subsequent calls to cvQueryFrame(). No new images are created after the first call, and the image is only freed at cvReleaseCapture().
So you see, if you are experiencing a memory leak (how did you find it, exactly?) and a crash, it is most probably caused by some other part of your code. If sendImage() is not synchronized (i.e. non-blocking) passing main image directly could cause problems. I don't know what you are doing in this function, so I'll assume the problem is inside it.
One test you could do, is copy the main frame and then pass that copy to sendImage() instead, then release it when you no longer need it.