0

I am having trouble with displaying opencv Video on a Qlabel.

I'm new using opencv and qt, and these week I was trying to make a tiny exercise using a qt button event to display a video capture from opencv to a qlabel of my widget. But weirdly the program says "The program has unexpectedly finished", when I run the code attached below. Please help me cuz for me nothing seems to be wrong. Thanks for your time and greetings from Costa Rica.

P.S. When I simply try to run the openCv code without any gui, I mean just using the code inside the buttonClicked event and cvShowImage("Video", frame); to display the video the program run good but strip an error and several warnings like this.

HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12
libpng warning: Application built with libpng-1.2.49 but running with 1.5.12

Attached code

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <cv.h>
#include <highgui.h>
using namespace std;
using namespace cv;

IplImage* imgTracking=0;

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

    ui->setupUi(this);    
}

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

void MainWindow::on_pushButton_clicked()
{
    CvCapture *cap; cap = cvCaptureFromCAM(1);
    IplImage *frame; frame = cvQueryFrame(cap);
    bool play = true;
    while(frame && play){
        cvWaitKey(10); IplImage *img = cvCloneImage(frame);
        if (img->origin) {
            cvFlip(img);
            img->origin= 0;
        }
        QImage qimg;
        qimg = IplImage2QImage(img);
        //cvShowImage("Video", frame);
        ui->labVideo->setPixmap(QPixmap::fromImage(qimg));
        cvReleaseImage(&img);
        frame = cvQueryFrame(cap);
    }
    cvReleaseCapture(&cap);
}

QImage MainWindow::IplImage2QImage(const IplImage *iplImage)
{
    int height = iplImage->height;
    int width = iplImage->width;

    const uchar *qImageBuffer =(const uchar*)iplImage->imageData;
    QImage img(qImageBuffer, width, height, QImage::Format_RGB888);

    return img.rgbSwapped();
}

  • You should run your program in a debugger. And your IplImage2QImage method does *not* work correctly for all images (see "step size"). And also, you should use C++ API of OpenCV. – ypnos Nov 08 '13 at 01:34
  • Like ypnos said: Your IplImage2QImage Method is not correct. Such a Method has to work on all sort of Images from simple uint8 grayscale with one channel up to full RGBA Images. There are several Examples in the Web and on SO. – Mailerdaimon Nov 08 '13 at 07:23

1 Answers1

0

It is so wrong. When you use Qt you shouldn't use cvWaitKey and have own loop. This function is just addition in openCv for testing or when you don't have ui freamework. When you use Qt you have UI framework and openCV should be used to image processing only (this is the purpose of this library)!

Replace this loop with QTimer and let QEventLoop do its job. CvCapture *cap must be field of class.

void MainWindow::on_timerTimeout()
{
    IplImage *frame = cvQueryFrame(cap);
    if (!frame) {
       stopPlay();
       return;
    }
    IplImage *img = cvCloneImage(frame);
    if (img->origin) {
        cvFlip(img);
        img->origin= 0;
    }
    QImage qimg = IplImage2QImage(img);
    ui->labVideo->setPixmap(QPixmap::fromImage(qimg)); // possible replace with signal emit newFrame(QPixmap::fromImage(qimg));
    cvReleaseImage(&img);
}

void MainWindow::stopPlay() {
    timer->stop();
    cvReleaseCapture(&cap);
}

void MainWindow::on_pushButton_clicked() {
    timer->start();
    cap = cvCaptureFromCAM(1);
}
Marek R
  • 32,568
  • 6
  • 55
  • 140
  • I make a QTimer that controls the loop but Still fails, "The program has unexpectedly finished." – user2967139 Nov 09 '13 at 00:40
  • run it with debugger and when it fails you should be able to see logs and call stack (add this information to question). – Marek R Nov 09 '13 at 09:56