Search code examples
pythonopencvopenglpygletpyopengl

How to quickly refresh images on screen with Python/OS-X and improve upon opencv's imshow()


I'm working on a Python (2.7.13) program that reads images from the webcam (refreshed on a separate thread), does a perspective transform, and puts the live video in a window on the screen, using opencv (3.2.0-dev). I get very low FPS (13) updating a 720x1280 output image with cv2.imshow(). If I remove the call to cv2.imshow() and keep the rest of the loop the same, it goes up to 75 FPS. What should I use in place of cv2.imshow() to get a reduce this image refresh bottleneck? I'm using a 2016 MacBook Pro with dedicated graphics card.

Do I need PyOpenGL for this, and if so are there any clear examples documented? I tried Pygame's blit function and did not see an improvement in FPS. I considered Pyglet which uses OpenGL, but I was not familiar with the paradigm of events used by Pyglet, and wasn't ready to rewrite my code if it turns out there's a more appropriate way to do it, as Pyglet seems to be mainly for games and some sources say it's not well maintained.


Solution

  • The imshow() feature is not really intended for real-time or streaming video display. You can easily run at frame rate using OpenGL, but there's quite a bit of effort involved. Have a look at PySDL which gives you a higher level API to OpenGL but is still designed for frame rate performance.