Qt: непрерывный захват изображений с камеры заполняет память

Я пытаюсь захватывать изображения непрерывно, чтобы я мог отправить их, используя UDP. Я делаю это для реализации программы потокового видео.

Приведенный ниже код захватывает изображения непрерывно и присваивает изображения QGraphicsScene, чтобы я мог проверить, воспроизводятся ли изображения как видео. Но когда я запускаю программу, мой компьютер зависает через пару секунд, хотя я удаляю указатели. Как я могу исправить эту проблему?

#include "mainwindow.h"#include "ui_mainwindow.h"#include <QThread>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(this);
ui->graphicsView->setScene(scene);
cam = new QCamera;
cam->setCaptureMode(QCamera::CaptureStillImage);

viewfinder = new QCameraViewfinder;
viewfinder->show();
QCameraImageCapture *cap = new QCameraImageCapture(cam);
cap->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);

cam->setViewfinder(viewfinder);QObject::connect(cap, &QCameraImageCapture::imageCaptured, [=] (int id, QImage img) {

while(true){
QByteArray *buf = new QByteArray;
QBuffer *buffer=new QBuffer(buf);
buffer->open(QIODevice::WriteOnly);
img.save(buffer, "BMP");
QPixmap *pixmap = new QPixmap();
pixmap->loadFromData(buffer->buffer());
scene->addPixmap(*pixmap);
delete buf;
delete buffer;
delete pixmap;

QThread::sleep(0.0416);
cap->capture();

}

});

QObject::connect(cap, &QCameraImageCapture::readyForCaptureChanged, [=] (bool state) {
if(state == true) {
cam->searchAndLock();
cap->capture();
cam->unlock();
}
});
cam->start();
}

MainWindow::~MainWindow()
{
delete ui;
}

0

Решение

Я не знаком с QCamera и связанные классы, кроме lambda вы подключаете QCameraImageCapture::imageCaptured сигнал не выглядит правильно. Этот сигнал испускается, когда один кадр готов для предварительного просмотра. В вашем lambdaОднако у вас есть …

while(true){
QByteArray *buf = new QByteArray;
QBuffer *buffer=new QBuffer(buf);
buffer->open(QIODevice::WriteOnly);
img.save(buffer, "BMP");
QPixmap *pixmap = new QPixmap();
pixmap->loadFromData(buffer->buffer());
scene->addPixmap(*pixmap);
delete buf;
delete buffer;
delete pixmap;

QThread::sleep(0.0416);
cap->capture();
}

Тот while цикл никогда не выходит и заблокирует Qt цикл обработки событий. Также обратите внимание, что фрагмент кода …

QByteArray *buf = new QByteArray;
QBuffer *buffer=new QBuffer(buf);
buffer->open(QIODevice::WriteOnly);
img.save(buffer, "BMP");
QPixmap *pixmap = new QPixmap();
pixmap->loadFromData(buffer->buffer());
scene->addPixmap(*pixmap);
delete buf;
delete buffer;
delete pixmap;

является излишним и (если я не ошибаюсь) в основном составляет …

scene->addPixmap(QPixmap::fromImage(img));

Так что я думаю, что ваш lambda должно быть больше похоже (не проверено) …

[=](int id, QImage img)
{
scene->addPixmap(QPixmap::fromImage(img));
}
0

Другие решения

Вы должны использовать imageAvailable () вместо сигнала imageCaptured.

Вот пример:

connect(cap, &QCameraImageCapture::imageAvailable, [=] (int id, QVideoFrame v ) {

if (v.isValid()) {
if(v.map(QAbstractVideoBuffer::ReadOnly)) {

QByteArray bitsVideo( (char *) v.bits(), v.mappedBytes() );

//call to your send raw data function (over UDP) :
//datagram will contain frame details e.g : [ width, hight, byteperline, format, rawdata ]

sendDataOverUDP( v.width(), v.height(),
v.bytesperLine(),
QVideoFrame::imageFormatFromPixelFormat(v.pixelFormat()),
bitsVideo );}
}
});

Другая сторона, сервер или другие клиенты будут создавать изображение из необработанных данных, полученных следующим образом:

    void onDataImageReceived( int width, int height,
int bytePerLine,
QImage::Format fmt,
QByteArray bitsVideo )
{

QImage img ((uchar *)bitsVideo.data(), width, height, bytesPerLine, fmt);
//do something with img ...

}
0

По вопросам рекламы [email protected]