Pythonで処理前後の画像を並べてGUIに表示して、パラメータによる画像変化がダイナミックにわかる
画像処理のパラメータを決めるとき、パラメータ変化がすぐに画像に反映されると、だいぶやりやすくなる。
ガウシアンフィルターをかけたときの変化が見えるようにツールを作った。画像処理はopencv、GUIはTkinterを使用した。
結果
左が元画像、右がガウシアンフィルターをかけた画像。右端のスライダーコントロール(Pythonではスケールと呼ぶ)でガウシアンフィルターのパラメータ(フィルターのサイズ、ガウシアンの偏差)が可変できる。すぐ画像に反映される。
プログラム
# 24_image_show_001.py # python 3.8.1 # opencv-python 4.1.2.30 # Pillow 7.0.0 # tkinter 8.6 # coding: utf-8 # import tkinter as tk from tkinter import HORIZONTAL from PIL import Image, ImageTk import cv2 #=============# # Create root # #=============# root = tk.Tk() root.title("Image Show") root.resizable(width=False, height=False) #===============# # Create frames # #===============# frmL = tk.Frame(root) frmC = tk.Frame(root) frmR = tk.Frame(root) #==================# # Define methods 1 # #==================# def formatConverter(img): img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Convert to RGB format. img_pil = Image.fromarray(img_rgb) # Convert to PIL format. img_tk = ImageTk.PhotoImage(img_pil) # Convert to ImageTk format. return img_tk #==============# # Make img src # #==============# ## Read image img_bgr = cv2.imread("24_lenna.jpg") ## For image processing img_tk = formatConverter(img_bgr) ## For original image c_img_tk = formatConverter(img_bgr) #==================# # Define methods 2 # #==================# def changeVal(event=None): #Do not forget 'event=None', or an arg error occurs. global imgCVT, blur_tk size = 3 ** val1.get() sigma = val2.get() blur = cv2.GaussianBlur(img_bgr, (size, size), sigma) blur_tk = formatConverter(blur) imgCVT.configure(image=blur_tk) label_val1.configure(text=size) label_val2.configure(text=sigma) # imgCVT.photo = blur_tk #If you do not want "blur_tk" to be global val, activate this script instead. # imgCVT.image = blur_tk #This will work as well as above. #================# # Create widgets # #================# imgORG = tk.Label(frmL, image=c_img_tk) imgCVT = tk.Label(frmC, image=img_tk) val1 = tk.IntVar() scale1 = tk.Scale( frmR, variable = val1, from_ = 0, to = 4, resolution = 1, showvalue = 0, label = "Filter:size", orient = tk.HORIZONTAL, command = changeVal ) val2 = tk.IntVar() scale2 = tk.Scale( frmR, variable = val2, from_ = 1, to = 10, resolution = 1, showvalue = 0, label = "Filter:sigma", orient = tk.HORIZONTAL, command = changeVal ) label_imgORG = tk.Label(frmL, text="Original image") label_imgCVT = tk.Label(frmC, text="Converted image") label_val1 = tk.Label(frmR, text="1") label_val2 = tk.Label(frmR, text="1") #========# # Layout # #========# frmL.pack(side='left') frmC.pack(side='left') frmR.pack(side='left') imgORG.pack(side='top') label_imgORG.pack(side='top') imgCVT.pack(side='top') label_imgCVT.pack(side='top') scale1.pack(side='top') label_val1.pack(side='top') scale2.pack(side='top') label_val2.pack(side='top') root.mainloop()
参考サイト
Tkinter に画像を表示させる
Pythonでグラフ(Matplotlib)を表示して動的に変更する — 某エンジニアのお仕事以外のメモ(分冊)
Tkinterで作成したウインドウにOpenCV-Pythonの画像を表示 - Qiita
Labelに表示した画像を更新する方法(これがわかるまで時間かかった)
python - How to update the image of a Tkinter Label widget? - Stack Overflow
The Tkinter Label Widget
The Tkinter PhotoImage Class
Opencvのガウシアンフィルター
opencv-python画像処理入門 - Qiita