PySimpleGUIによるOpnenCVを用いた2値化処理ソフトの作成方法について!!

Ganzy
Ganzy

こんにちは、Ganzyです!!今回はPySimpleGUIを用いた画像処理GUIの作成方法について紹介します!!GUIはグラフィックユーザーインターフェースの略語になっており、マウス操作などによってパラメータ調整や処理の実行が可能となり非常に扱いやすくなりますのでぜひ参考にして実践いただければと思います!!

PySimpleGUIについて

PySimpleGUI」とは、GUI作成用のライブラリであり、比較的簡単に開発することが可能です。またドキュメントも充実しており初心者でも取り組みやすくなっております!!

またGUIの開発ライブラリはそのほかにも多数あり、過去記事でまとめておりますので是非参考に

2値化処理GUIのコンセプト

今回作成する2値化処理GUIのコンセプトは以下の通りです。

  • 画像ファイルを読み込んで処理を行う
  • 読み込んだ画像に対して2値化処理を行う
  • 2値化処理の閾値調整をGUI上から調整可能
  • 2値化処理を行った画像を保存する

以上の要件でGUIを作成していきます!!

2値化GUIについて紹介!!

早速ですが、作成したGUIがこちらです!!レナ画像*に対して2値化処理をした結果が出力されていることがわかるかと思います!!またSAVEボタンを押せば2値化処理後の画像を保存することができるようになっております!!*レナ画像は画像処理のテスト画像として一般的に用いられる画像です。

さて肝心のソースコードは以下の通りです!!行数も少なくGUIを作成できていることがわかるかと思います!!

import datetime
import io
from pathlib import Path
import cv2
import numpy as np
import PySimpleGUI as sg


original_image = [[sg.Image(filename='', key='-orginal_img-')]]
modify_image = [[sg.Image(filename='', key='-result_img-')]]

#read 
read_layout = [[sg.Text("File"), sg.InputText(key='-input_file-', enable_events=True, ),
                sg.FileBrowse('FileBrowse', key='-file-', target="-input_file-",), sg.Button('Read File', key='-read_file-')],
                [sg.Button('Save',key='-save-'),sg.Button('Update',key='-Update-'),sg.Cancel()],
                [sg.Text("Threshold")],
                [sg.Slider((0, 255), 0, 1, orientation='h', key='-THRESH SLIDER-')]]

layout= [[sg.Frame(title='Read',layout=read_layout)],
             [sg.Frame(title='Original',layout=original_image),sg.Frame(title='Results',layout=modify_image),]]


# flag
READ_File = False

sg.theme('Dark Blue 3')

window = sg.Window('Threshold', layout,
                   location=(10, 10),alpha_channel=1.0,
                   no_titlebar=False,grab_anywhere=False).Finalize()

while True:

    event, values = window.read(timeout=20)

    if event in (None, 'Cancel'):
        break

    elif event == '-read_file-':

        read_path = Path(values['-input_file-'])
        read_img = cv2.imread(str(read_path), cv2.IMREAD_GRAYSCALE)
        read_display_img = cv2.resize(read_img,(320,320))
        copy_img = read_display_img.copy()
        
        read_display_img= cv2.imencode('.png', read_display_img)[1].tobytes()
        copy_img= cv2.imencode('.png', copy_img)[1].tobytes()
        
        window['-orginal_img-'].update(data=read_display_img)
        window['-result_img-'].update(data=copy_img)
        window['-THRESH SLIDER-'].update(128)
        READ_File = True

    if READ_File:    
        if event == '-save-':
            out_path = f'{read_path.stem}_result.png'
            cv2.imwrite(out_path, th_img)


        elif event == '-Update-':
            img_median = cv2.medianBlur(src=read_img, ksize=3)
            _, th_img  = cv2.threshold(img_median, int(values['-THRESH SLIDER-']), 255, cv2.THRESH_BINARY) 
            th_display_img= cv2.resize(th_img,(320,320))
            th_display_img= cv2.imencode('.png',th_display_img)[1].tobytes()
            window['-result_img-'].update(data=th_display_img)

window.close()

ソースコード解説

さてソースコードについて要点を解説していきたいと思います!!

まずGUIのレイアウトを作成している箇所の説明になります。PySimpleGUIでは各枠を作成する必要があります!!

original_image = [[sg.Image(filename='', key='-orginal_img-')]]
modify_image = [[sg.Image(filename='', key='-result_img-')]]

#read 
read_layout = [[sg.Text("File"), sg.InputText(key='-input_file-', enable_events=True, ),
                sg.FileBrowse('FileBrowse', key='-file-', target="-input_file-",), sg.Button('Read File', key='-read_file-')],
                [sg.Button('Save',key='-save-'),sg.Button('Update',key='-Update-'),sg.Cancel()],
                [sg.Text("Threshold")],
                [sg.Slider((0, 255), 0, 1, orientation='h', key='-THRESH SLIDER-')]]

layout= [[sg.Frame(title='Read',layout=read_layout)],
             [sg.Frame(title='Original',layout=original_image),sg.Frame(title='Results',layout=modify_image),]]


sg.theme('Dark Blue 3')

window = sg.Window('Threshold', layout,
                   location=(10, 10),alpha_channel=1.0,
                   no_titlebar=False,grab_anywhere=False).Finalize()

代表的なコードは以下の通りです!!

  • sg.Image()→画像表示用
  • sg.Text()→テキストを記載
  • Sg.Button→ボタンを作成

またレイアウトは、[] ,を活用して決定します。イメージとしては[]に囲んでいる箇所が横に並んでレイアウトされます!

例えば、[sg.Image() , sg.Image()]とすると画像表示用の枠が横に並ぶようにレイアウトされます。

一方で、 [sg.Image()] , [sg.Image()] とすると画像が縦に並ぶようにレイアウトされます!!

またsg.()内にKey=~~とかいております。ここが実は重要でKey=によって枠に名称を定義することで、後からアクセスして表示する画像や値を更新したり、定義した枠の値を使ったりすることができます!!

そして最後sg.frame()内に定義したsg.~を配置することで最終的なレイアウト決定します。レイアウトは上記と同様な法則で決められます。

次に2値化処理を実行している箇所について説明します。

elif event == '-Update-':
            img_median = cv2.medianBlur(src=read_img, ksize=3)
            _, th_img  = cv2.threshold(img_median, int(values['-THRESH SLIDER-']), 255, cv2.THRESH_BINARY) 
            th_display_img= cv2.resize(th_img,(320,320))
            th_display_img= cv2.imencode('.png',th_display_img)[1].tobytes()
            window['-result_img-'].update(data=th_display_img)

2値化処理はGUI上で「Update」ボタンをクリックすることで2値化処理が実行されます。

elif event=”-Update-“と書くことでUpdateボタンをクリックしたときにelif以下の処理実行します。

2値化処理では一般的な「cv2.threshold」で実施していますが、Values[‘-THRESH SLIDER-‘]とすることでGUI上のスライダーの値を使って2値化することができます!!

またwindow[‘-result_img-‘].update()によって処理した画像をGUI上に表示することができます!!

まとめ

PysimpleGUIを用いた2値化処理GUIについて紹介していきました。PySimpleGUIでは、行数もすくなく直感的にGUIを作成することができるのでめちゃくちゃおすすめです!!

ぜひGUIを作成してみたい方は是非参考にして自分好みのGUIを作成してみてください!!またそのほかの画像処理に関する記事も多数書いているのでこちらも興味があればぜひ!!

作成するにあたり参考にさせていただいたサイト↓

PysimpleGUIを用いたOpenCV画像処理表示 - Qiita
####はじめにPysimpleGUIを使った画像処理表示のデモを作成したので、覚えとして記載します。####作成したデモ(1)OpenCVでカメラから画像を受け取りリアルタイムで、ヒストグラ…

コメント

タイトルとURLをコピーしました