[PYTHON] Display image data handled by OpenCV / numpy on Qt Widget

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.

Recommended Posts

Display image data handled by OpenCV / numpy on Qt Widget
I want to display an image on Jupyter Notebook using OpenCV (mac)
Read the image posted by flask so that it can be handled by opencv