Improving performance of multiple live videos

714 views
Skip to first unread message

Gabriel Rosenhouse

unread,
Mar 22, 2013, 1:44:47 PM3/22/13
to pyqt...@googlegroups.com
Hello,

I have several live video streams (from scientific cameras) that I'd like to display simultaneously in one window.  I coded up a small test program, based on the ImageItem.py example that comes with pyqtgraph, but I find, unsurprisingly, that frame-rates are inversely proportional to the number of live video windows.  I have pasted some sample code below.

Is there a way for me to improve frame rates?  perhaps by running the QTimers on separate threads?

I'm new to pyqtgraph, and to Python generally, so I'd welcome any feedback on how I can improve my code.

Thank you!

-Gabriel


# Example code for multiple video display
# -*- coding: utf-8 -*-
# based on pyqtgraph\examples\ImageItem.py
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
import pyqtgraph as pg
import pyqtgraph.ptime as ptime

app = QtGui.QApplication([])
win = pg.GraphicsLayoutWidget()
win.show()
win.setWindowTitle('multi-video display')
win.setGeometry(200,200,1000,700)

class VideoView:
    def __init__(self, r,c):
        self.view = win.addViewBox(row=r, col=c)
        self.view.setAspectLocked(True)
        self.img = pg.ImageItem(border='k')
        self.view.addItem(self.img)
        self.view.setRange(QtCore.QRectF(0, 0, 600, 600))
        self.data = np.random.normal(size=(15, 600, 600), loc=1024, scale=64).astype(np.uint16)
        self.i = 0
        self.updateTime = ptime.time()
        self.fps = 0

    def updateData(self):
        self.img.setImage(self.data[self.i])
        self.i = (self.i+1) % self.data.shape[0]

        QtCore.QTimer.singleShot(1, self.updateData)
        now = ptime.time()
        fps1 = 1.0 / (now-self.updateTime)
        self.updateTime = now
        self.fps = self.fps * 0.9 + fps1 * 0.1
        if self.i == 0:
            print "%0.1f fps" % self.fps

coords = [[x,y] for x in range(0,2) for y in range(0,2)]
views = []
for (x,y) in coords:
    views.append(VideoView(x,y))
for v in views:
    v.updateData()

## Start Qt event loop unless running in interactive mode.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()



Luke Campagnola

unread,
Mar 22, 2013, 3:31:39 PM3/22/13
to pyqt...@googlegroups.com
On Fri, Mar 22, 2013 at 1:44 PM, Gabriel Rosenhouse <rosen...@gmail.com> wrote:
I have several live video streams (from scientific cameras) that I'd like to display simultaneously in one window.  I coded up a small test program, based on the ImageItem.py example that comes with pyqtgraph, but I find, unsurprisingly, that frame-rates are inversely proportional to the number of live video windows.  I have pasted some sample code below.

Is there a way for me to improve frame rates?  perhaps by running the QTimers on separate threads?


Hi Gabriel,

This is a good question. I've spent a lot of time trying to optimize ImageItem and I think it's pretty much as fast as it can get. The major places that consume CPU cycles are 1) converting from the original data format to QImage (this is handled by functions.makeARGB and .makeQImage) and 2) calling QPainter.drawImage(). 

There's nothing in your code I see that could speed things up, but drawing performance is highly dependent on the version of Qt you have and your platform. I would recommend trying different graphics systems (see QApplication.setGraphicsSystem) as well as pyqtgraph.RawImageWidget--see the VideoSpeedTest example. If you start it from the example loader (python -m pyqtgraph.examples), then you can specify which graphics system you want to use. You can use that to test the performance of a variety of different settings. 

Ultimately, the best way to speed things up is to offload more work to the GPU. Using the opengl graphics system can help, as well as calling pyqtgraph.setConfigOptions(useOpenGL=True). Note, though, that Qt's opengl implementation is pretty buggy in my experience. Eventually I will be reimplementing most drawing to make use of the GPU, hopefully with fewer bugs than what Qt has provided..

Luke

Gabriel Rosenhouse

unread,
Mar 22, 2013, 3:43:33 PM3/22/13
to pyqt...@googlegroups.com
Thanks Luke.  I'll look into the RawImageWidget and OpenGL stuff.

Gabriel
Reply all
Reply to author
Forward
0 new messages