Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用opencv:VideoCapture的内存泄漏_C++_Qt_Opencv_Memory Leaks - Fatal编程技术网

C++ 使用opencv:VideoCapture的内存泄漏

C++ 使用opencv:VideoCapture的内存泄漏,c++,qt,opencv,memory-leaks,C++,Qt,Opencv,Memory Leaks,我用QtCreator 2.4.1(Qt4.8.4)和OpenCV 2.4.2开发了一个应用程序,可以从文件夹中读取图像并显示它们 它使用cv::VideoCapture和qgraphicscene/QGraphicsView。它运行得很好,但是我遇到了内存泄漏:如果我在任务管理器中查看消耗的内存,每次读取新映像时,内存都会增加,最终崩溃 我的主窗口是用Qt设计器创建的,它是一个继承QMainWindow的类。上面有一个QGraphicsView视图\u src,还有一个按钮:buttonSta

我用QtCreator 2.4.1(Qt4.8.4)和OpenCV 2.4.2开发了一个应用程序,可以从文件夹中读取图像并显示它们

它使用cv::VideoCapture和qgraphicscene/QGraphicsView。它运行得很好,但是我遇到了内存泄漏:如果我在任务管理器中查看消耗的内存,每次读取新映像时,内存都会增加,最终崩溃

我的主窗口是用Qt设计器创建的,它是一个继承QMainWindow的类。上面有一个
QGraphicsView视图\u src
,还有一个按钮:
buttonStart

下面是代码示例:类声明:

using namespace std;
using namespace cv;

namespace Ui {
    class FenetrePrinc;
}

class FenetrePrinc : public QMainWindow {
    Q_OBJECT
public:
    explicit FenetrePrinc(QWidget *parent = 0);
    ~FenetrePrinc();

public slots:
    virtual void start();
    virtual void tick();
    virtual void stop_timer();

private:
    Ui::FenetrePrinc *ui;

    QString filename;
    QGraphicsScene *scene_src;
    QGraphicsItem *img_src;

    VideoCapture sequence;

    Mat src;
};
类别定义:

FenetrePrinc::FenetrePrinc(QWidget *parent) : QMainWindow(parent), ui(new Ui::FenetrePrinc){

    ui->setupUi(this);
    scene_src = new QGraphicsScene();
    timer = new QTimer(this);

    img_src = scene_src->addPixmap(QPixmap("vide.jpg"));
    ui->view_src->setScene(scene_src);

    connect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(start()));
}

FenetrePrinc::~FenetrePrinc(){
    delete scene_src;
    delete img_src;
    delete ui;
}

void FenetrePrinc::start(){
    if(src.empty())
        sequence.open(filename.toStdString());

    connect(timer, SIGNAL(timeout()), this, SLOT(tick()));
    timer->start(1000/24);   //24 frames per second

    disconnect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(start()));
    connect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(stop_timer()));
}

void FenetrePrinc::tick(){
    sequence >> src;

    if(src.empty())
    {
        sequence.release();
        stop_timer();
        return;
    }

    scene_src->removeItem(img_src);
    img_src = scene_src->addPixmap(convert16uc1(src));

    src.release();
}

void FenetrePrinc::stop_timer(){
    timer->stop();
    disconnect(timer, SIGNAL(timeout()), this, SLOT(tick()));

    disconnect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(stop_timer()));
    connect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(start()));
}
我不明白为什么每次读取一个图像时,内存使用量都会不断增加,每次读取图像时,我都会释放它,一旦完成,就会释放序列。但也许我错过了什么

编辑:函数
QPixmap convert16uc1(Mat img)
是内存泄漏的原因。我必须使用这个函数,因为我处理的是16位灰度图像,Qt无法读取。我打开图像,用OpenCV执行图像处理,用Qt显示图像

该功能的代码如下所示:

QPixmap FenetrePrinc::convert16uc1(const cv::Mat& source)
{
  quint16* pSource = (quint16*) source.data;
  int pixelCounts = source.cols * source.rows;

  QImage dest(source.cols, source.rows, QImage::Format_RGB32);

  char* pDest = (char*) dest.bits();

  for (int i = 0; i < pixelCounts; i++)
  {
    quint8 value = (quint8) ((*(pSource)) >> 8);
    *(pDest++) = value;  // B
    *(pDest++) = value;  // G
    *(pDest++) = value;  // R
    *(pDest++) = 0;      // Alpha
    pSource++;
  }
  return QPixmap::fromImage(dest);
}
QPixmap-fenetrepinc::convert16uc1(const-cv::Mat&source)
{
quint16*pSource=(quint16*)source.data;
int pixelCounts=source.cols*source.rows;
QImage dest(source.cols、source.rows、QImage::Format_RGB32);
char*pDest=(char*)dest.bits();
对于(int i=0;i>8);
*(pDest++)=值;//B
*(pDest++)=值;//G
*(pDest++)=值;//R
*(pDest++)=0;//α
pSource++;
}
返回QPixmap::fromImage(dest);
}

很可能是
convert16uc1

如果您无法在此处发布convert16uc1,请尝试使用imwrite在opencv中临时保存图像,并在Qt中加载图像。如果内存泄漏消失。分析
convert16uc1


或者不要调用convert16uc1(src),而是使用之前在Qt中加载的一些其他常量映像调用
addPixmap

阅读本文,我找到了问题的原因和解决方法

从Qt文档中:

无效QGraphicscene::removeItem(QGraphicsSitem*项)

从场景中删除项目及其所有子项。项目的所有权将传递给调用者(即,QGraphicscene在销毁时将不再删除项目)

另请参见addItem()

调用QGraphicscene::removeItem(QGraphicsSitem*item)`后,QGraphicscene在销毁时将不再删除该项

修复:在
removietem(img\u src)
之后调用
delete img\u src
:在函数中
fenetrepinc::tick()


请尝试使用更新的opencv版本,2.4.2太旧了。如果您不使用Qt显示图像(只读取图像,不显示),它是否也会泄漏内存?能否发布您的
convert16uc1
函数?您必须释放Qt pixmap元素吗?根据,请在
添加pixmap
@berak之前尝试使用
场景\u src->clear()
:我在Qt上也大量使用stoll 2.4.2。来自相机和硬盘的图像。没有内存泄漏。这不是OpenCV,当然也不是Qt。是的,如果我将
scene\u src->addPixmap(convert16uc1(srt))
更改为
scene\u src->addPixmap(QPixmap(“vide.jpg”)
我就不再有内存泄漏了。我已经编辑了我的问题以添加
convert16uc1
代码。我按照您的建议做了:我没有使用
QPixmap convert16uc1(Mat源代码)
将我的图像从OpenCV转换为Qt,而是使用ìmwrite`临时保存图像,并用Qt加载此图像。使用这种技术,我不再有内存泄漏。@zarachbaal:这只是一个测试的建议!这将是非常缓慢的转换。我会尝试你的代码,也许会找到原因。是的,我知道这不是一个真正的解决方案,我只是尝试了一下,它可以工作,但速度非常慢!我认为原因是
QPixmap::frommage(dest)。有一个重载版本可以在不复制的情况下进行转换,但它是在Qt5.3中实现的,我使用Qt4.8.4。@zarachbaal:
fromImage
几乎不是问题。QImage是在堆栈上创建的。当离开功能范围时,它将被删除。
void FenetrePrinc::tick(){
    sequence >> src;

    if(src.empty())
    {
        sequence.release();
        stop_timer();
        return;
    }

    scene_src->removeItem(img_src);
    delete img_src;
    img_src = scene_src->addPixmap(convert16uc1(src));

    src.release();
}