43052
pyqt5で画像を等高線のように表示するGUIを作りたいです。画像を等高線のように表示するコードは次のように書けます。

```

    from PIL import Image, ImageOps, ImageFilter
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 画像読み込み
    img = Image.open('300.png')
    # グレースケール化
    img = ImageOps.grayscale(img)
    # ぼかし
    img = img.filter(ImageFilter.GaussianBlur(3))
    # 配列化
    data = np.asarray(img)
    # 等高線
    plt.contour(data)
    # 描画
    plt.show()
    
```

これで、  
[![image1](https://i.stack.imgur.com/NMg9x.jpg)](https://i.stack.imgur.com/NMg9x.jpg)  
のような画像が  
[![image2](https://i.stack.imgur.com/Tbbdh.png)](https://i.stack.imgur.com/Tbbdh.png)  
このように変換されます。これを踏まえて、pyqt5を使ってGUIを書いたものが次のコードになります。

```

    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5 import QtGui,QtCore, QtWidgets
    import os.path
    from PIL import Image, ImageOps, ImageFilter
    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    
    
    
    class Example(QtWidgets.QDialog):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.button1 = QtWidgets.QPushButton('実行',self)
            self.button1.clicked.connect(self.calc)
    
            self.button2 = QtWidgets.QPushButton(self)
            global img
            img = "300.png"
            self.button2.setIcon(QIcon(img))
            self.button2.setIconSize(QSize(400,300))
    
            layout=QtWidgets.QVBoxLayout()
            layout.addWidget(self.button1)
            layout.addWidget(self.button2)
    
            self.setLayout(layout)
    
        def calc(self):
            pass
            """
            image = Image.open(img)
            image = ImageOps.grayscale(image)
            image = image.filter(ImageFilter.GaussianBlur(3))
            data = np.asarray(image)
            plt.contour(data)
    
            self.figure = plt.figure()
            self.axes = self.figure.add_subplot(111)
            self.canvas = FigureCanvas(self.figure)
            self.axes.plot(data)
    
            self.button2.setIcon(self.canvas)
            """
    
    
    
    
    
    if __name__ == '__main__':
    
        app = QApplication(sys.argv)
        ex = Example()
        ex.show()
        app.exec_()
    
```

これで、次のようなGUIが出来ます。  
[![image3](https://i.stack.imgur.com/TjSf5.png)](https://i.stack.imgur.com/TjSf5.png)  
ここで、「実行」ボタンを押したときに表示されている画像が等高線表示されるようにしたいです。しかし、コードの４１行目のcalc関数の中をどのように書けばいいのか分かりません。グラフを画像データに変えることができればアイコンをその画像に置き換えることもできそうですが、画像データへの変換の仕方も分かりません。
CC BY-SA 3.0
2018-04-07T07:56:13.167
43032
2020-02-09T02:40:42.590
2018-04-07T12:44:16.530
19110
26529
question
python python3 pyqt
pyqt5で簡単な画像処理をしたい
matplotlibの場合、画像データへの書き出しは、`fig.savefig()`でできるので、取り敢えず下のコードで動作します。

```

    def calc(self):
        image = Image.open(img)
        image = ImageOps.grayscale(image)
        image = image.filter(ImageFilter.GaussianBlur(3))
        data = np.asarray(image)
        fig = plt.figure()
        plt.contour(data)
        fig.savefig("fig.png")
        self.button2.setIcon(QIcon("fig.png"))
    
```
CC BY-SA 3.0
2018-04-08T04:23:14.847
43052
2018-04-08T05:29:48.217
2018-04-08T05:29:48.217
15171
15171
43032
answer
以下のコードでは一度画像を保存することなく表示できます。

```

    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5 import QtGui,QtCore, QtWidgets
    import os.path
    from PIL import Image, ImageOps, ImageFilter
    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    
    
    
    class Example(QtWidgets.QDialog):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.button1 = QtWidgets.QPushButton('実行',self)
            self.button1.clicked.connect(self.calc)
    
            self.button2 = QtWidgets.QPushButton(self)
            global img
            img = "300.png"
            self.button2.setIcon(QIcon(img))
            self.button2.setIconSize(QSize(400,300))
    
            layout=QtWidgets.QVBoxLayout()
            layout.addWidget(self.button1)
            layout.addWidget(self.button2)
    
            self.setLayout(layout)
    
        def calc(self):
            image = Image.open(img)
            image = ImageOps.grayscale(image)
            image = image.filter(ImageFilter.GaussianBlur(3))
            data = np.asarray(image)
    
            self.figure1 = plt.figure()
            self.axes1 = self.figure1.add_subplot(111)
            self.canvas1 = FigureCanvas(self.figure1)
    
            self.axes1.contour(data)
            self.canvas1.draw()
    
            size = self.canvas1.size()
            width, height = size.width(), size.height()
            im = QImage(self.canvas1.buffer_rgba(), width, height, QImage.Format_ARGB32)
    
            qim=QPixmap.fromImage(im)
            self.button2.setIcon(QIcon(qim))
    
    if __name__ == '__main__':
    
        app = QApplication(sys.argv)
        ex = Example()
        ex.show()
        app.exec_()
    
```
CC BY-SA 4.0
2020-02-09T02:40:42.590
62892
2020-02-09T02:40:42.590
26529
43032
answer