PDA

View Full Version : Show webcam through Qt - progam doesn't respond to any user input



Saul
6th July 2011, 17:44
Hi all,
I try to get the output of my webcam with opencv and display it through qt. Therefore I convert the IplImage into a QImage and call the function setPixmap() to draw the image onto a QLabel. Afterwards I repaint the QLabel to update it. Generally the output works fine but the program isn't responsive to any command. I can't close it by push esc or clicking on the "X" to close the window. My last option is to break the program by "ctrl-alt-del".

Does anybody has a hint or know where the problem lie?
I would be very excited for any help.
Thanks in advance and kind regards,
Saul

Thats my whole code:

// main.cpp

#include "webcam.h"
#include <QtGui/QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Webcam w;
w.show();
return a.exec();
}

// webcam.h

#ifndef WEBCAM_H
#define WEBCAM_H

#include <QtGui/QMainWindow>
#include "ui_webcam.h"
#include "cv.h"
#include "highgui.h"

class Webcam : public QMainWindow
{
Q_OBJECT

public:
Webcam(QWidget *parent = 0, Qt::WFlags flags = 0);
~Webcam();

private:
Ui::WebcamClass ui;

public slots:
void showWebcam();
};

#endif // WEBCAM_H

// webcam.cpp

#include "webcam.h"

Webcam::Webcam(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags)
{
ui.setupUi(this);

connect(ui.actionStart, SIGNAL(triggered()), this, SLOT(showWebcam()));
}

Webcam::~Webcam() { }

void Webcam::showWebcam()
{
IplImage *image;
CvCapture *capture;
capture = cvCaptureFromCAM(0);

int esc = 0;
while(true)
{
image = cvQueryFrame(capture);

cvCvtColor(image, image,CV_BGR2RGB);
QImage qimg((const uchar *)image->imageData, image->width, image->height, QImage::Format_RGB888);
ui.label->setPixmap(QPixmap::fromImage(qimg));
ui.label->repaint();

esc = cvWaitKey(10);
if (esc == 27) break;
}
cvReleaseCapture(&capture);
}

d_stranz
6th July 2011, 17:54
In your showWebcam() method, you never give the Qt event loop the chance to process any other events, so that is why your GUI is unresponsive. You need to insert a call to QCoreApplication:: processEvents() somewhere in your loop.

I am guessing that is the reason why you call label->repaint() instead of label->update() - since update() puts a paint event on the event stack and your loop never lets the stack get processed, the label never gets painted.

After adding the QCoreApplication:: processEvents() call, change the label->repaint() to a label->update() and it should all work fine (and make the label a "good player" in the Qt world again).

Saul
6th July 2011, 19:06
Hi d_stranz,
thank you very much for your response! I changed my code as you wrote. Hope it is correct now. At least it works and I'am really happy =)
Cheers,
Saul

By the way: the program will not execute the break command if I press ESC.


void Webcam::showWebcam()
{
IplImage *image;
CvCapture *capture;
capture = cvCaptureFromCAM(0);

int esc = 0;
while(true)
{
image = cvQueryFrame(capture);

cvCvtColor(image, image,CV_BGR2RGB);
QImage qimg((const uchar *)image->imageData, image->width, image->height, QImage::Format_RGB888);
ui.label->setPixmap(QPixmap::fromImage(qimg));
ui.label->update();

QCoreApplication::processEvents();

esc = cvWaitKey(10);
if (esc == 27) break;
}
cvReleaseCapture(&capture);
}

Saul
11th July 2011, 19:59
Hi, its me again.
I just want to ask, if it's conform to use QCoreApplication:: processEvents(); directly in my loop? Or is it unsuitable to use it this way?
I'm a little bit self-conscious in this way, yet. Would be very thankful for a "Yes" or a "NO" =)

Are there any other possibilities to realize a webcam output?
Ok, the first one I tried is the QLabel. Think it could be done with Phonon::VideoPlayer, too.
Are there even more possibilities?
Kind regards,
Saul

d_stranz
11th July 2011, 20:25
It is OK to use QCoreApplication:: processEvents() in a loop.

On the other hand, if you are forced to do that in order to get a responsive application, it is generally a sign that your application design could be improved.

Usually, it is better to try to implement a signal / slot or multithreaded design so that compute-intensive work gets done in a different thread from the GUI, and communicates to the GUI thread using signals (something like "frameReady").

You might be able to use Phonon, but I am not familiar with it so someone else will have to answer that question.

Saul
13th July 2011, 19:05
OK, thanks again d_stranz!
I will do my best. Bought a Qt book and found a chapter about threads yesterday. Armed and ready for the fight now :D

But I have just one last Question and Problem. If I close the Program the webcam is still running. My function to break the loop by push the button ESC does not work.

stampede
13th July 2011, 19:10
I've posted a simple Qt + OpenCv example here (http://www.qtcentre.org/threads/43056-Qt-OpenCV-simple-example), you may want to check it out. You don't need any separate threads or processEvents() calls to get responsive ui during webcam capture and simple image processing, just use QTimer.