Утечка памяти в функции OpenCV: cvQueryFrame () - PullRequest
0 голосов
/ 21 февраля 2012

У меня проблема с IplImage*, возвращаемым из cvQueryFrame ... Его память никогда не освобождается библиотекой.И документация гласит:

Возвращенное изображение не должно быть выпущено или изменено пользователем.

Хорошо ... как мне вернуть мою память?Программа ест память, пока не падает.Я хотел бы освободить выделенную память для каждого IplImage* после завершения обработки кадра.Код такой:

// 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
}

ОБНОВЛЕНИЕ: Это QThread подкласс:

#include <QThread>
class ImageFetcher : public QThread
{
    Q_OBJECT
public:
    explicit ImageFetcher(QObject *parent = 0);
signals:
    void run();
public slots:
};

Реализация:

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();
}

1 Ответ

1 голос
/ 22 февраля 2012

Насколько я мог проверить, нет утечки в v2.3.1 для Linux.

Вот что происходит: изображение выделяется cvQueryFrame(), когда эта функция вызывается в первый раз, а затем это изображение повторно используется при всех последующих вызовах cvQueryFrame(). Новые изображения не создаются после первого вызова, и изображение освобождается только при cvReleaseCapture().

Итак, вы видите, если вы испытываете утечку памяти (как вы ее точно нашли) и сбой, это, скорее всего, вызвано какой-то другой частью вашего кода. Если sendImage() не синхронизирован (то есть неблокируется), передача main напрямую может вызвать проблемы. Я не знаю, что вы делаете в этой функции, поэтому я предполагаю, что проблема в ней.

Один тест, который вы можете сделать, это скопировать кадр main, а затем вместо этого передать эту копию в sendImage(), а затем отпустить ее, когда она вам больше не нужна.

...