私的AI研究会 > PythonGUI3
Python プログラム作成に必要な GUI を試してみる。
標準装備の「tkinter」をラップしてより簡単にスマートな GUIが作れるらしい。
(py37) mizutu@ubuntu-vbox:~$ pip3 install PySimpleGUI Collecting PySimpleGUI Downloading PySimpleGUI-4.51.0-py3-none-any.whl (372 kB) |████████████████████████████████| 372 kB 4.0 MB/s Installing collected packages: PySimpleGUI Successfully installed PySimpleGUI-4.51.0
(py37) mizutu@ubuntu-vbox:~$ conda search -c conda-forge pysimplegui Loading channels: done # Name Version Build Channel pysimplegui 4.1.0 py_0 conda-forge pysimplegui 4.2.0 py_0 conda-forge pysimplegui 4.3.1 py_0 conda-forge pysimplegui 4.3.2 py_0 conda-forge pysimplegui 4.4.0 py_0 conda-forge pysimplegui 4.4.1 py_0 conda-forge pysimplegui 4.5.0 py_0 conda-forge pysimplegui 4.6.0 py_0 conda-forge pysimplegui 4.15.2 py_0 conda-forge pysimplegui 4.18.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.18.2 pyh9f0ad1d_0 conda-forge pysimplegui 4.19.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.20.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.21.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.22.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.24.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.25.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.26.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.27.4 pyh9f0ad1d_0 conda-forge pysimplegui 4.28.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.29.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.30.0 pyh9f0ad1d_0 conda-forge pysimplegui 4.31.0 pyhd3deb0d_0 conda-forge pysimplegui 4.32.1 pyhd3deb0d_0 conda-forge pysimplegui 4.33.0 pyhd3deb0d_0 conda-forge pysimplegui 4.34.0 pyh44b312d_0 conda-forge pysimplegui 4.38.0 pyh44b312d_0 conda-forge pysimplegui 4.40.0 pyh44b312d_0 conda-forge pysimplegui 4.40.0 pyh44b312d_1 conda-forge pysimplegui 4.44.0 pyhd8ed1ab_0 conda-forge pysimplegui 4.45.0 pyhd8ed1ab_0 conda-forge pysimplegui 4.46.0 pyhd8ed1ab_0 conda-forge pysimplegui 4.47.0 pyhd8ed1ab_0 conda-forge pysimplegui 4.48.0 pyhd8ed1ab_0 conda-forge pysimplegui 4.49.0 pyhd8ed1ab_0 conda-forge
# -*- coding: utf-8 -*- import PySimpleGUI as sg # 画面レイアウトを指定 ---- (*1) fm=('Noto Serif CJK JP',10) layout = [ [sg.Text('日給計算アプリ', font=fm)], [sg.Text('開始時間', size=(15,1), font=fm), sg.InputText('09:00')], [sg.Text('終了時間', size=(15,1), font=fm), sg.InputText('17:00')], [sg.Text('休憩時間', size=(15,1), font=fm), sg.InputText('1:00')], [sg.Text('時給', size=(15,1), font=fm), sg.InputText('1100')], [sg.Submit(button_text='計算', font=fm)]] # イベントループ --- (*2) win = sg.Window('日給計算', layout) while True: event, values = win.read() if event is None: break if event == '計算': # ここで日給を計算 sg.popup('ここで日給を計算') break
# -*- coding: utf-8 -*- import PySimpleGUI as sg # ウィンドウのテーマ sg.theme('BlueMono') fm=('Noto Sans CJK JP',10) # ウィンドウのレイアウト layout = [ [sg.Text('チェックボックス', font=fm)], [sg.Checkbox("チェックボックス1", font=fm)], # [sg.Checkbox("チェックボックス2", font=fm)] [sg.Checkbox("abcABC亜愛ボックス2", font=fm)] ] # ウィンドウオブジェクトの作成 window = sg.Window('title', layout, size=(300, 300)) # イベントのループ while True: # イベントの読み込み event, values = window.read() # ウィンドウの×ボタンクリックで終了 if event == sg.WIN_CLOSED: break # ウィンドウ終了処理 window.close()
#!/usr/bin/env python import PySimpleGUI as sg from PIL import Image, ImageTk import io import os import asci_art_transform as asci """ 参考URL; https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Img_Viewer.py """ def get_img_data(f, maxsize=(600, 450), first=False): """Generate image data using PIL """ print("open file:", f) img = Image.open(f) img.thumbnail(maxsize) if first: # tkinter is inactive the first time bio = io.BytesIO() img.save(bio, format="PNG") del img return bio.getvalue() return ImageTk.PhotoImage(img) filename = './model.jpg' # 最初のファイル image_elem = sg.Image(data=get_img_data(filename, first=True)) filename_display_elem = sg.Text(filename, size=(80, 3)) # 初期表示時はascに変換してなくてもよい # './model.jpg' をうわがいてしまってもよい # asci_image = tranfa_asci('./model.jpg', './test.png', 16) asci_image = "./test.png" asc_image_elem = sg.Image(data=get_img_data(asci_image, first=True)) # define layout, show and read the form col = [image_elem, asc_image_elem] col_read_file = [sg.InputText('ファイルを選択', key='-INPUT-TEXT-', enable_events=True, ), sg.FileBrowse('ファイルを読み込む', key='-FILE-', file_types=(('jpegファイル', '*.jpg'), ('png', '*.png'),)), sg.Button('変換')] layout = [col_read_file, [sg.Slider(range=(1,64), key='-FONT-SIZE-', default_value=16, orientation='h', )], col] window = sg.Window('アスキーアートに変換してみよう', layout, return_keyboard_events=True, location=(0, 0), use_default_focus=False) # loop reading the user input and displaying image, filename i = 0 while True: # read the form event, values = window.read() print(event, values) # perform button and keyboard operations if event is None: break elif event == '変換': print(values['-INPUT-TEXT-']) if os.path.isfile(values['-INPUT-TEXT-']): # Animationするには別スレッドにする必要 sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, message='実行中',text_color='black', background_color='white', time_between_frames=100) asci_image = asci.tranfa_asci(values['-INPUT-TEXT-'], "./test.png", int(values['-FONT-SIZE-'])) sg.popup_animated(image_source=None) print('変換終了') else: error_massage = values['-INPUT-TEXT-'] + ' は存在してません' sg.popup('エラー', error_massage) asc_image_elem.update(data=get_img_data(asci_image, first=True)) elif values['-FILE-'] != '': print('FilesBrowse') if os.path.isfile(values['-INPUT-TEXT-']): image_elem.update(data=get_img_data(values['-INPUT-TEXT-'], first=True)) window.close()
""" Colorization based on the Zhang Image Colorization Deep Learning Algorithm This header to remain with this code. The implementation of the colorization algorithm is from PyImageSearch You can learn how the algorithm works and the details of this implementation here: https://www.pyimagesearch.com/2019/02/25/black-and-white-image-colorization-with-opencv-and-deep-learning/ You will need to download the pre-trained data from this location and place in the model folder: https://www.dropbox.com/s/dx0qvhhp5hbcx7z/colorization_release_v2.caffemodel?dl=1 GUI implemented in PySimpleGUI by the PySimpleGUI group Of course, enjoy, learn , play, have fun! Copyright 2019 PySimpleGUI """ import numpy as np import cv2 import PySimpleGUI as sg import os.path version = '7 June 2020' prototxt = r'model/colorization_deploy_v2.prototxt' model = r'model/colorization_release_v2.caffemodel' points = r'model/pts_in_hull.npy' points = os.path.join(os.path.dirname(__file__), points) prototxt = os.path.join(os.path.dirname(__file__), prototxt) model = os.path.join(os.path.dirname(__file__), model) if not os.path.isfile(model): sg.popup_scrolled('Missing model file', 'You are missing the file "colorization_release_v2.caffemodel"', 'Download it and place into your "model" folder', 'You can download this file from this location:\n', r'https://www.dropbox.com/s/dx0qvhhp5hbcx7z/colorization_release_v2.caffemodel?dl=1') exit() net = cv2.dnn.readNetFromCaffe(prototxt, model) # load model from disk pts = np.load(points) # add the cluster centers as 1x1 convolutions to the model class8 = net.getLayerId("class8_ab") conv8 = net.getLayerId("conv8_313_rh") pts = pts.transpose().reshape(2, 313, 1, 1) net.getLayer(class8).blobs = [pts.astype("float32")] net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")] def colorize_image(image_filename=None, cv2_frame=None): """ Where all the magic happens. Colorizes the image provided. Can colorize either a filename OR a cv2 frame (read from a web cam most likely) :param image_filename: (str) full filename to colorize :param cv2_frame: (cv2 frame) :return: Tuple[cv2 frame, cv2 frame] both non-colorized and colorized images in cv2 format as a tuple """ # load the input image from disk, scale the pixel intensities to the range [0, 1], and then convert the image from the BGR to Lab color space image = cv2.imread(image_filename) if image_filename else cv2_frame scaled = image.astype("float32") / 255.0 lab = cv2.cvtColor(scaled, cv2.COLOR_BGR2LAB) # resize the Lab image to 224x224 (the dimensions the colorization network accepts), split channels, extract the 'L' channel, and then perform mean centering resized = cv2.resize(lab, (224, 224)) L = cv2.split(resized)[0] L -= 50 # pass the L channel through the network which will *predict* the 'a' and 'b' channel values 'print("[INFO] colorizing image...")' net.setInput(cv2.dnn.blobFromImage(L)) ab = net.forward()[0, :, :, :].transpose((1, 2, 0)) # resize the predicted 'ab' volume to the same dimensions as our input image ab = cv2.resize(ab, (image.shape[1], image.shape[0])) # grab the 'L' channel from the *original* input image (not the resized one) and concatenate the original 'L' channel with the predicted 'ab' channels L = cv2.split(lab)[0] colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2) # convert the output image from the Lab color space to RGB, then clip any values that fall outside the range [0, 1] colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR) colorized = np.clip(colorized, 0, 1) # the current colorized image is represented as a floating point data type in the range [0, 1] -- let's convert to an unsigned 8-bit integer representation in the range [0, 255] colorized = (255 * colorized).astype("uint8") return image, colorized def convert_to_grayscale(frame): gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Convert webcam frame to grayscale gray_3_channels = np.zeros_like(frame) # Convert grayscale frame (single channel) to 3 channels gray_3_channels[:, :, 0] = gray gray_3_channels[:, :, 1] = gray gray_3_channels[:, :, 2] = gray return gray_3_channels # --------------------------------- The GUI --------------------------------- # First the window layout...2 columns left_col = [[sg.Text('Folder'), sg.In(size=(25,1), enable_events=True ,key='-FOLDER-'), sg.FolderBrowse()], [sg.Listbox(values=[], enable_events=True, size=(40,20),key='-FILE LIST-')], [sg.CBox('Convert to gray first',key='-MAKEGRAY-')], [sg.Text('Version ' + version, font='Courier 8')]] images_col = [[sg.Text('Input file:'), sg.In(enable_events=True, key='-IN FILE-'), sg.FileBrowse()], [sg.Button('Colorize Photo', key='-PHOTO-'), sg.Button('Start Webcam', key='-WEBCAM-'), sg.Button('Save File', key='-SAVE-'), sg.Button('Exit')], [sg.Image(filename='', key='-IN-'), sg.Image(filename='', key='-OUT-')],] # ----- Full layout ----- layout = [[sg.Column(left_col), sg.VSeperator(), sg.Column(images_col)]] # ----- Make the window ----- window = sg.Window('Photo Colorizer', layout, grab_anywhere=True) # ----- Run the Event Loop ----- prev_filename = colorized = cap = None while True: event, values = window.read() if event in (None, 'Exit'): break if event == '-FOLDER-': # Folder name was filled in, make a list of files in the folder folder = values['-FOLDER-'] img_types = (".png", ".jpg", "jpeg", ".tiff", ".bmp") # get list of files in folder try: flist0 = os.listdir(folder) except: continue fnames = [f for f in flist0 if os.path.isfile( os.path.join(folder, f)) and f.lower().endswith(img_types)] window['-FILE LIST-'].update(fnames) elif event == '-FILE LIST-': # A file was chosen from the listbox try: filename = os.path.join(values['-FOLDER-'], values['-FILE LIST-'][0]) image = cv2.imread(filename) window['-IN-'].update(data=cv2.imencode('.png', image)[1].tobytes()) window['-OUT-'].update(data='') window['-IN FILE-'].update('') if values['-MAKEGRAY-']: gray_3_channels = convert_to_grayscale(image) window['-IN-'].update(data=cv2.imencode('.png', gray_3_channels)[1].tobytes()) image, colorized = colorize_image(cv2_frame=gray_3_channels) else: image, colorized = colorize_image(filename) window['-OUT-'].update(data=cv2.imencode('.png', colorized)[1].tobytes()) except: continue elif event == '-PHOTO-': # Colorize photo button clicked try: if values['-IN FILE-']: filename = values['-IN FILE-'] elif values['-FILE LIST-']: filename = os.path.join(values['-FOLDER-'], values['-FILE LIST-'][0]) else: continue if values['-MAKEGRAY-']: gray_3_channels = convert_to_grayscale(cv2.imread(filename)) window['-IN-'].update(data=cv2.imencode('.png', gray_3_channels)[1].tobytes()) image, colorized = colorize_image(cv2_frame=gray_3_channels) else: image, colorized = colorize_image(filename) window['-IN-'].update(data=cv2.imencode('.png', image)[1].tobytes()) window['-OUT-'].update(data=cv2.imencode('.png', colorized)[1].tobytes()) except: continue elif event == '-IN FILE-': # A single filename was chosen filename = values['-IN FILE-'] if filename != prev_filename: prev_filename = filename try: image = cv2.imread(filename) window['-IN-'].update(data=cv2.imencode('.png', image)[1].tobytes()) except: continue elif event == '-WEBCAM-': # Webcam button clicked sg.popup_quick_message('Starting up your Webcam... this takes a moment....', auto_close_duration=1, background_color='red', text_color='white', font='Any 16') window['-WEBCAM-'].update('Stop Webcam', button_color=('white','red')) cap = cv2.VideoCapture(0) if not cap else cap while True: # Loop that reads and shows webcam until stop button ret, frame = cap.read() # Read a webcam frame gray_3_channels = convert_to_grayscale(frame) image, colorized = colorize_image(cv2_frame=gray_3_channels) # Colorize the 3-channel grayscale frame window['-IN-'].update(data=cv2.imencode('.png', gray_3_channels)[1].tobytes()) window['-OUT-'].update(data=cv2.imencode('.png', colorized)[1].tobytes()) event, values = window.read(timeout=0) # Update the window outputs and check for new events if event in (None, '-WEBCAM-', 'Exit'): # Clicked the Stop Webcam button or closed window entirely window['-WEBCAM-'].update('Start Webcam', button_color=sg.theme_button_color()) window['-IN-'].update('') window['-OUT-'].update('') break elif event == '-SAVE-' and colorized is not None: # Clicked the Save File button filename = sg.popup_get_file('Save colorized image.\nColorized image be saved in format matching the extension you enter.', save_as=True) try: if filename: cv2.imwrite(filename, colorized) sg.popup_quick_message('Image save complete', background_color='red', text_color='white', font='Any 16') except: sg.popup_quick_message('ERROR - Image NOT saved!', background_color='red', text_color='white', font='Any 16') # ----- Exit program ----- window.close()