LoginSignup
6
16

More than 5 years have passed since last update.

OpenCV/numpyで扱う画像データをQt Widget上に表示する

Last updated at Posted at 2017-02-25

ということで、表題通り、OpenCV/numpyなどで扱ってる画像データをQt(pyqt5)のウィジェット上に表示する方法。
そんなに難しくもないのだけど、メモとして投稿してみる。

ここでは、Pythonから使えるQtラッパーであるPyQt5を使った例。
C++とかでも記述方法が変わるだけで要点は同じである。

まずは、イメージの配列(メモリ上に展開されている)を、QPixmapに変換。
下記ソースを見てもらえれば分かるように、ARGB形式のデータである必要がある。なので、もしGrayscaleやRGB形式のデータであれば、OpenCVのcvtColor()などで、事前にARGB形態に変換しておく必要がある。

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

で、表示するためには、何らかのQWidget上に、このQPixmapを描画する必要がある。
なので、QWidgetを拡張して1つ、クラスを作っておくと便利である。
このクラスでは、ウィジェットが描画されるタイミングで呼び出されるpaintEvent()を拡張して、その中でイメージを描画するようにしてみた。さらなる高速描画が必要なら、OpenGLなどの利用も検討かな。
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()

ということで、以上!
matplotlib使うよりスピードはダンチだし、OpenCVのimshow()みたいな簡易的な感じでもないし、pygame使うよりはちゃんとしたGUI形態に出来る。用途に応じて使い分けましょう。

6
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
16