PDA

View Full Version : firewire camera displaying problem from a new QTer



Ran
14th January 2008, 03:44
Hi All,

I am new to Qt and I am using Qt4 to develop an application to display video from SONY iidc camera.

Currently, I managed to show the image frames on a label's pixmap attribute. But, the speed of display is slow. Well, should be very slow - like 2frames/s. What I've actually done is:

1. read the data from the camera to a unsignech char buffer.
2. create a QImage object using that data
3. create a QPixmap object using the above QImage
4. Put is on the Label to display.



//gray image 8-bit
QImage *frameImage;
QPixmap bPixmap;
QByteArray ba;
QBuffer buffer( &ba );
// this is the data buffer from the firewire camera
pImageBuff = (unsigned char *)iidc_lockdata(hCamera, -1);
frameImage = new QImage(pImageBuff, iWidth, iHeight, QImage::Format_Indexed8);
frameImage->setNumColors(256);
for (int icol = 0; icol< 256; icol++){
frameImage->setColor(icol, colorTableData[icol]);
}
buffer.open( IO_WriteOnly );
frameImage->save( &buffer, "PNG" );
bPixmap.loadFromData(ba);
LabelCam1->setPixmap(bPixmap);
LabelCam1->repaint();


Does anyone has any idea of speeding up this displaying thing? Or using other methods?

^NyAw^
14th January 2008, 09:45
Hi,



for (int icol = 0; icol< 256; icol++){[/font]
frameImage->setColor(icol, colorTableData[icol]);[/font]


You are using indexed color, but I'm sure that you are taking gray scale images, I'm right? so why you are filling the color index for every frame?
Make a QImage pointer that will mantain the color index table and only set the image buffer to it.

The other one:


bPixmap.loadFromData(ba);
You take the image buffer, load to a QImage and finally you don't use the QImage to QPixmap conversion that maybe will be faster than loading from data(the data is in the QImage yet).

I had done this a little time ago and I used canvas instead of label. I don't know if the speed is better. You also could paint the image into a QGLWidget (file:///C:/Qt/4.3.0/doc/html/qglwidget.html).

Ran
14th January 2008, 12:55
Thank you, NyAw!



You are using indexed color, but I'm sure that you are taking gray scale images, I'm right? so why you are filling the color index for every frame? Make a QImage pointer that will mantain the color index table and only set the image buffer to it.

You are right. I am using gray scale images. I will try as you suggested!

I am using QPainter's method drawImage to paint onto the window and looks faster now (not fast enough though). QGLWidget could be an alternative too, I will have a look! Thank you again.

One more question: I found that during the period of my video show code is running, my mainwindow stops responding to event like menu click or even close. All you can do is to wait ... until video displaying part is completed. Am I doing something else wrong?

My main.cpp is very simple like this.


QApplication app(argc, argv);

firewireCamera mainWdn;

mainWdn.show();

return app.exec();

^NyAw^
14th January 2008, 14:47
Hi,

Have you any Thread?
In Qt applications there is the main Thread that is who controls the GUI, keyboard, mouse, ... the events.
So you have to create a Thread that grabbs images from the camera and then send them by SIGNALs and SLOTs mechanism to the main thread who have to paint them.

Ran
14th January 2008, 23:27
Thanks again NyAw, I think I have a main thread to control the running of the image capturing stuff. I guess that I should have something to check the status/event between each circle of capturing loop and do whatever it should do. In this way, my code could probably have some response to events. Am I on the right way?

^NyAw^
15th January 2008, 09:32
Hi,

Don't realy understand you.
The main thread is that display GUI objects, take mouse and keyboard events, etc.. If you are going to capture the images from the main thread, this will be blocked to response this events untl your code has been executed. So, if grabbing an image takes very much time, all this time the application window will be frozen.
Take a look at "mandelbrot" example in Qt examples. It makes a thread that do something and when the image is prepared to be shown, it is sended to the main thread that display it.

Ran
15th January 2008, 13:23
Yes. I am trying to change my code into multi-threaded. One thing I don't understand is how to design a thread which shows its own Widget. I try to inherit a QWidget as well as a QThread. Obviously it failed. But if I want to show videos for from multi cameras at the same time in their own widget or child-window, how could I do that?

^NyAw^
15th January 2008, 14:40
Hi,
If you read about QThread you will see that the main thread is the only one who can do graphics(draw, paint, ...). So, taking the mandlebrot example you will see that the worker thread do something(load image, transform it, apply any filter,...) and then it sends a reference of the image to the main thread that will paint it on a Widget.

So, create your own class inherited from QThread. This class is the class that will take the image of the camera and convert it to a QImage. Then, when the image will be a QImage, you can use "emit" to let the main thread take the image and paint it on a widget.