パソコン上で、PyQt5により温度カラーバーを表示させます。「PycharmでQtプログラムの開発」で、パソコン上でPython 統合開発環境「Pycharm」を使用して、Qt Designerで作成したGUIを実行させましたが、python3でPyQt5を使って、サーモグラフィのように温度の高低を色で表現した温度カラーバーを表示します。

温度カラーバーの表示

温度カラーバーをサーモグラフィのような色(値が低い順に 青→水色→緑→黄色→赤 となるような色)に変換するには、次のような色相環(Hue)を使います。

温度カラーバー

各RGB値の変化を線形にした場合、水色と黄色の領域が狭くなり、またグラデーションもあまり綺麗に見えないため、シグモイド関数を適用します。計算結果は、RGBそれぞれの色が8ビットで出力されます。詳細については「サーモグラフィ風の色変化をシグモイド関数で再現する」を参考にしました。

表示画面をQt Designerで作成

温度カラーバーを横方向に表示させ、シグモイド関数のパラメータをコンポボックスで選択し、プッシュボタンを押すと計算したカラーコードを温度カラーバーに表示します。Qt Designerで作成した表示画面を次に示します。

Qt Designerで作成したGUIコード「thermography.ui」は、「pyuic5」を使用してPyQt5「thermography.py」に変換します。

温度カラーバー表示ソフトの作成

作成した温度カラーバー表示ソフト「thermomain.py」を次に示します。

  • 25行目から31行目が、シグモイド関数を使ってRGB値に変換するロジックです。RGB値の戻り値を計算するときに「256」を乗算しています。
  • 45行目から52行目まではコンボボックスにアイテムの名称を登録しています。
  • 54行目は、プッシュボタンが押されたときに呼び出されるコールバック関数を指定します。ラムダ式「lambda:」によりコールバック関数にパラメータを渡します。今回は文字列「Hello world」を渡します。
  • 67行目で1000本のラインを引きます。ラインの色は65行目のpen関数で指定します。
  • QGraphicsSceneのシーンにラインを書き込みこれをQGraphicsViewに追加します

thermomain.py

import sys
import os

from PyQt5.QtCore import (QLineF, QPointF, QRectF, Qt)
from PyQt5.QtWidgets import (QApplication, QWidget, QComboBox, QDialog,
                             QDialogButtonBox, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout,
                             QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QSpinBox, QTextEdit, QGraphicsLineItem,
                             QVBoxLayout, QGraphicsView, QGraphicsScene, QGraphicsItem, QGraphicsPixmapItem)
from PyQt5.QtGui import (QIcon, QPixmap, QBrush, QPen, QColor)
from thermography import Ui_Dialog
import numpy as np

gain = 30
comp_offset_x = [0.2, 0.5, 0.7]
comp_offset_green = [0.2, 0.5, 0.7]

view = 0
scene = 0


def sigmoid(x, gain=1, offset_x=0):
    return ((np.tanh(((x + offset_x) * gain) / 2) + 1) / 2)


def colorBarRGB(x, offset_x, offset_green):
    x = (x * 2) - 1
    red = sigmoid(x, gain, -1 * offset_x)
    blue = 1 - sigmoid(x, gain, offset_x)
    green = sigmoid(x, gain, offset_green) + (1 - sigmoid(x, gain, -1 * offset_green))
    green = green - 1.0
    return (red * 256, green * 256, blue * 256)


class Test(QWidget):
    def __init__(self):
        # super() でスーパークラスのインスタンスメソッドを呼び出す
        #        super(MainWindow, self).__init__(parent)
        super().__init__()

        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.view = self.ui.graphicsView
        self.scene = QGraphicsScene()

        # アイテムの名前設定
        self.ui.comboBox.addItem("{}".format(comp_offset_x[0]))
        self.ui.comboBox.addItem("{}".format(comp_offset_x[1]))
        self.ui.comboBox.addItem("{}".format(comp_offset_x[2]))

        self.ui.comboBox_2.addItem("{}".format(comp_offset_green[0]))
        self.ui.comboBox_2.addItem("{}".format(comp_offset_green[1]))
        self.ui.comboBox_2.addItem("{}".format(comp_offset_green[2]))

        self.ui.pushButton.clicked.connect(lambda: self.buttonClicked("Hello world"))

    def buttonClicked(self, str):
        print("{} {} {}".format(str, self.ui.comboBox.currentIndex(), self.ui.comboBox_2.currentIndex()))

        offset_x = comp_offset_x[self.ui.comboBox.currentIndex()]
        offset_green = comp_offset_green[self.ui.comboBox_2.currentIndex()]
        data = [colorBarRGB(x * 0.001, offset_x, offset_green) for x in range(1000)]

        for i in range(1000):
            # QPenの設定
            pen = QPen(QColor(data[i][0], data[i][1], data[i][2]), 1, Qt.SolidLine, Qt.RoundCap,
                       Qt.RoundJoin)
            self.scene.addLine(i, 0, i, 40, pen)

        self.view.setScene(self.scene)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Test()
    window.show()
    sys.exit(app.exec_())

温度カラーバー表示ソフトの実行

パソコン上で温度カラーバー表示ソフトを実行し、コンポボックスをそれぞれ「0.2」「0.7」に設定し、設定ボタンを押すと、次の温度カラーバーが表示されます。

温度カラーバー