Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Live camera image using OpenCV showing in Qlabel crashes due to out of memory error



  • Hi all,

    I am using QT Qpixmap to show the image captured from the camera using the OpenCV frame. I am doing following steps

    1. Capture image using OpenCV
    2. Convert the OpenCV image to QImage
    3. Convert QImage to Qpixmap
    4. Show it on Qlabel

    The problem I am facing is the memory start increasing at great speed and after few time the application crashed with out of memory

    I have gone through the code several time to check any object being created again and again.

    Using QT 5 with MinGW 7

    Any help will be appreciated.



  • Thank you all guys. Your suggestions and expert opinion helped a lot with solving the problem. QT forum is always so helpful.

    After trying many things here is the conclusion and code is now working perfectly fine

    I removed the tic toc part

    time(&start);
    timer = double(getTickCount());
    tic();
    It was working but crashing then just to make sure that QImage is not NULL I removed the img = QImage(); // releasing memory

    with

    if(!img.isNull())
    img = QImage();
    Its working perfectly fine now.



  • @Imran-Hassan said in Live camera image using OpenCV showing in Qlabel crashes due to out of memory error:

    The problem I am facing is the memory start increasing at great speed and after few time the application crashed with out of memory

    Not that I'll discover something special, but clearly you're leaking memory...

    You're not stated the OS you're running, but from using MinGW I guess it's some Windows variant. If you could use Linux somehow, you could use Valgrind to help spot those memory issues

    I have gone through the code several time to check any object being created again and again.

    You may want to share some code snippets in any case



  • I am using windows so I can not know where memory is being leaked.

    I am using thread. Here is the code

    void MainWindow::mainfucntion(){
    std::thread producer_t(&MainWindow::RunDefaultCamera,this);

    for(;;){

            time(&start);
            timer = double(getTickCount());
            tic();
    
            if(!bufferQueue.empty()){
              lock_guard<std::mutex> lock(fmutex);
                readFrame = bufferQueue.front();
                qDebug() << "1 : " << bufferQueue.size();
                bufferQueue.pop_front();
                qDebug() << "2 : " << bufferQueue.size();
            }
            else{
                if(keepRunning == true)
                {
                    if(threadEnable==false)
                    {
                       std::thread producer_t(&MainWindow::RunDefaultCamera,this);
                    }
                    continue;
                }
                else{
                    producer_t.join();
                    return -1;
                }
            }
    

    // cap >> readFrame;
    cv::resize(readFrame, readFrame, size);

    img = QImage((uchar*) readFrame.data, readFrame.cols, readFrame.rows, readFrame.step, QImage::Format_BGR888);
    image = QPixmap::fromImage(img);
    // QPixmap image = QPixmap(img);

            ui->lblDisplayVideo->setPixmap(image);
    

    }

    Thread function is here

    void RunDefaultCamera()
    {
    while(capture.isOpened())
    {

            qDebug() << "thread is running";
            capture >> ImageMat;
            bufferQueue.push_back(ImageMat);
            
            if(!ImageMat.empty())
            {
                frameCounter++;
    
                lock_guard<std::mutex> lock(fmutex);
                if (int(bufferQueue.size()) >= bufferSize)
                {
                    bufferQueue.clear();
                }
                else
                {
                    bufferQueue.push_back(ImageMat);
                 }
    
            }
            sleep(100);
    //        ui->listInfo->addItem(QString::number(bufferQueue.size()));
            qDebug() << bufferQueue.size();
    

    }
    capture.release();
    }



  • @Imran-Hassan said in Live camera image using OpenCV showing in Qlabel crashes due to out of memory error:

    using windows so I can not know where memory is being leaked.

    you may want to take a look at using Heob with Qt Creator...


  • Lifetime Qt Champion

    @Imran-Hassan said in Live camera image using OpenCV showing in Qlabel crashes due to out of memory error:

    ui->lblDisplayVideo->setPixmap(image);

    You must not do this outside the main thread.

    img = QImage((uchar*) readFrame.data, readFrame.cols, readFrame.rows, readFrame.step, QImage::Format_BGR888);

    where do you free this memory? Please take a look at the documentation



  • @Christian-Ehrlicher said in Live camera image using OpenCV showing in Qlabel crashes due to out of memory error:

    ui->lblDisplayVideo->setPixmap(image);
    You must not do this outside the main thread.

    Actually its in for loop and we have to do it. We have to continuously update the screen with new image.

    mg = QImage((uchar*) readFrame.data, readFrame.cols, readFrame.rows, readFrame.step, QImage::Format_BGR888);

    where do you free this memory?

    I was not releasing the memory ,,, I added the statement and I am now releasing the memory with null pointer like
    img = QImage();

    But still facing the same problem.


  • Moderators

    @Imran-Hassan

    since when is reassigning a pointer to nullptr equal to freeing memory, if it's not created on the stack?
    You could argue since c++11, but you're not using those classes.

    And It won't matter anyway, because QImage inertially has nothing ti do with that data, using that constructor.

    Explicitly delete the QImage, than call delete [] on that char array than creating a new QImage

    Actually its in for loop and we have to do it. We have to continuously update the screen with new image.

    No you don't have to, it's just - for you - the most convenient way to do it right now.



  • Hey guys, if readFrame is a cv::Mat then he doesn't need to free the memory bacause it has its own memory managing mechanism.
    But the whole mainfucntion is very weird, I don't know where it is ...
    It looks like a main() function, but it has this and ui, so it seems like a member function of MainWindow, which is even weirder to have for(;;) in that...



  • Thank you all guys. Your suggestions and expert opinion helped a lot with solving the problem. QT forum is always so helpful.

    After trying many things here is the conclusion and code is now working perfectly fine

    I removed the tic toc part

    time(&start);
    timer = double(getTickCount());
    tic();
    It was working but crashing then just to make sure that QImage is not NULL I removed the img = QImage(); // releasing memory

    with

    if(!img.isNull())
    img = QImage();
    Its working perfectly fine now.