Efficient rendering of multiple raw-image streams
-
Dear Qt friends
I am no expert, but more or less familiar with Qt. But for my current task I don't find the solution. And I already spend several days on browsing through documentations/examples etc. and tried a lot.
The application I want to develop: I have attached N=1..20 industrial cameras to my computer, each producing 25 frames/sec at a resolution of 2048x2048 (they provide raw uncoded images in RGB format). I am capturing the cameras in a background thread. And now I simply want to put the N images on each frame (at 25 FPS) on screen side-by-side in a tile/mosaic manner. Since I wrote the capturing background thread, I can adapt the data format or other things.
My current attempt is to setup a QGraphicsScene and QGraphicsView. But unfortunately, as it seems, on each frame update, I have to takeover each image by
(a) copying it into a QImage via QImage constructor,
(b) copy-scale it to 1/Nth of the screen-size via QImage::scaledToHeight() / QImage::scaledToWidth(),
(c) copy it into a QPixmap via QPixmap::convertFromImage()
(d) copy it into the scene via QGraphicsPixmapItem::setPixmap()This is terribly slow and inefficient! I thought, there should be a way, to register a QImage to QGraphicsScene/QGraphicsView, so that it is always shown as I want it (in a tile besides others or full-screen, the whole image or only a zoomed part of it). And I thought, updating such a QImage with a newly captured camera frame should be easy, but I see no way for loading a new image into an existing QImage. Even better would be, to get access to the image memory inside QImage - in that way, I could convert the data directly from camera-native format into Qt-native format, without any unnecessary copying.
I am very happy about any feedback! Is my approach feasible? Are there other better ways? Do I have to change only a little detail or my complete thinking? Thanks a lot.
Best wishes,
Philipp -
maybe use opengl textures and custom OpenGL widget to simply draw them.
You could simply read frames from camera into this textures.
To refresh view you will have to periodicly call update() on that widget.
-
For Graphics View I would subclass QGraphicsItem and reimplement paint method. In every subclass you can add a QImage member and draw it in paint function. Also you can directly manipulate QImage pixels with QImage::bits and then QGraphicsItem::update to show them
-
Thank's a lot! Yes, the later approach of cincirin works quite well. Acutally, some collegues of mine also mentioned, I should use OpenGl (as proposed by 8majkel8). But, since I am performing only simple 2D operations, I liked to omit OpenGl. Thank's again.
Best wishes,
Philipp