1
votes

I'm writing a GUI using python and pyQt to read in data packets through UDP socket, processing it through OpenCV, then finally showing it as real time images using Qt. I created a UDP socket outside the while loop, while using the sock.recvfrom method to read in data packets inside the while loop. Within the same while loop, i processed the data and put it into OpenCV format and use OpenCV imshow() method to show the real time video for experimenting. Everything's great and working smooth, but when i try to show the video through QLabel using QImage and QPixmap, things went bizarre. If OpenCV imshow() exist, the code works fine with additional QPixmap shown in the QLabel on top of the OpenCV cv2.imshow() window. However, if i take out the OpenCV imshow(), the UI will freeze and nothing showed leading "python not responding". I've not yet come up with a good reason why this is happening, and i also tried keeping/changing cv2.waitkey() time without succeeding. Any help would be appreciated.

import socket
import cv2
from PyQt4 import QtCore, QtGui, uic

while True:
    data, addr = self.sock.recvfrom(10240)

    # after some processing on data to get im_data ...
    self.im_data_color_resized = cv2.resize(im_data, (0, 0), interpolation = True)

    # using OpenCV to show the video (the entire code works with cv2.imshow but not without it)
    cv2.imshow('Real Time Image', self.im_data_color_resized)
    cv2.waitKey(10)

    # using QLabel to show the video
    qtimage = cv2.cvtColor(self.im_data_color_resized, cv2.COLOR_BGR2RGB)
    height, width, bpc = qtimage.shape

    bpl = bpc * width
    qimage = QtGui.QImage(qtimage.data, width, height, bpl, QtGui.QImage.Format_RGB888)

    self.imageViewer_label.setPixmap(QtGui.QPixmap.fromImage(qimage))
1
You probably need to double check your question... It seems you got confused with imshow and imread. Also you can markup the code (your function names)Miki
Thanks Miki, you are right! I updated my question. Some reason i got confused with the two when I was writing but i do mean imshow().Lawrence Tzuang
You're in a loop...I think you just need to refresh the event queue calling (the pyQt equivalent of) QApplication::processEvents(); after the setPixmap. Probably the cv2.waitKey functions does something like that internallyMiki
You are right! I added QtGui.QApplication.processEvents() right after setPixmap() and it worked! Thanks!Lawrence Tzuang
Glad it helped. Posted an answer then ;)Miki

1 Answers

2
votes

You need to refresh the event queue, so that your GUI can be updated. Add QtGui.QApplication.processEvents() after the setPixamp function.

It works with cv2.waitKey() because it internally already refreshes the painting events allowing the Qt GUI to be refreshed. But I recommend not to rely on this hack, and explicitly refresh the Qt events with processEvents.

You may also want to put this processing loop in its own thread to leave the GUI/Main thread responsive.