So, as the title suggests, how to display image data handled by OpenCV / numpy etc. on the widget of Qt (pyqt5). It's not that difficult, but I'll post it as a memo.
Here is an example using PyQt5, a Qt wrapper that can be used from Python. The main points are the same in C ++, except that the description method changes.
First, convert the image array (expanded in memory) to QPixmap
.
As you can see from the source below, the data must be in ARGB format. So, if it is Grayscale or RGB format data, it is necessary to convert it to ARGB format in advance with cvtColor ()
of OpenCV.
import PyQt5.QtCore as QtCore
import PyQt5.QtGui as QtGui
import PyQt5.QtWidgets as QtWidgets
def create_QPixmap(image):
qimage = QtGui.QImage(image.data, image.shape[1], image.shape[0], image.shape[1] * 4, QtGui.QImage.Format_ARGB32_Premultiplied)
pixmap = QtGui.QPixmap.fromImage(image)
return pixmap
So, in order to display it, it is necessary to draw this QPixmap
on some QWidget
.
Therefore, it is convenient to extend QWidget
and create one class.
In this class, I extended paintEvent ()
, which is called when the widget is drawn, to draw the image in it. If you need higher speed drawing, maybe you should consider using OpenGL.
The point is to use QtGui.QPainter
.
class ImageWidget(QtWidgets.QWidget):
def __init__(self, image):
super(ImageWidget, self).__init__()
self.image = image
def paintEvent(self, event):
painter = QtGui.QPainter(self)
if self.image is None:
painter.setPen(QtCore.Qt.black)
painter.setBrush(QtCore.Qt.black)
painter.drawRect(0, 0, self.width(), self.height())
return
pixmap = create_QPixmap(self.image)
painter.drawPixmap(0, 0, self.image.shape[1], self.image.shape[0], pixmap)
def set_image(self, image):
self.image = image
self.update()
That's it!
It's faster than using matplotlib
, it's not as simple as OpenCV's ʻimshow (), and it can be a more decent GUI than using
pygame`. Let's use it properly according to the purpose.