今回は検査に使用する元画像をGUIから設定できるようにします。
環境は下記になります。
Hardware:Raspberry pi4B
OS:Raspbian 10/buster
Python:3.7.3
前回の記事は以下になります。
https://iot-techs.net/information/ef8ba546-2768-571b-a8e2-1b2d13e85d00
Pythonではtkinter.filedialogモジュールを利用してフォルダを選択するダイアログを開きます。
今回は画像をのみを指定したいのでjpgのみ選択できるようにします。
ソースコードは以下になります。
#ファイルを開く
fimg = [("", "*.jpg")] #jpgのみを指定
iDir = os.path.abspath(os.path.dirname(__file__))
file = tkinter.filedialog.askopenfilename(filetypes = fimg,initialdir = iDir)
またshutilモジュールを利用して指定したファイルをリネームして上書きします。
#ファイルを設定する
file_oldname = file
file_newname_newfile = "Originalcap.jpg"
newFileName=shutil.move(file_oldname, file_newname_newfile)
ファイルが指定されていないときにエラーが発生するのでif not fileでファイル名が格納されているか確認します。
#ファイルを設定する
if not file:
print('キャンセル')
else:
file_oldname = file
file_newname_newfile = "Originalcap.jpg"
newFileName=shutil.move(file_oldname, file_newname_newfile)
全体のソースコードは以下になります。
import tkinter as tk
import os
import time
import datetime
import picamera
import cv2
import glob
import tkinter.filedialog
import tkinter.messagebox
import shutil
from tkinter import *
from PIL import Image, ImageTk
#ウィンドウの作成
base = tk.Tk()
base.geometry("750x300")
base.title("画像撮影")
camera = picamera.PiCamera()
# 保存先path
image_path = "./images/"
def clk(): #---クリックイベント画像撮影
#現在時間を取得
now = datetime.datetime.now()
#画像撮影
camera.resolution = (1024, 768)
camera.capture(now.strftime(image_path + '%Y%m%d_%H%M%S') + 'cap.jpg')
#プレビュー
camera.start_preview()
time.sleep(5)
camera.stop_preview()
def com(): #---クリックイベント比較
# 最新ファイルの取得
AllList = glob.glob('./images/*')
latest_file = max(AllList, key=os.path.getctime)
# 結果で表示するために画像を読み込む
img = Image.open(latest_file)
img_width, img_height = img.size
lastimage = ImageTk.PhotoImage(img)
print(latest_file)
# 撮影した画像を読み込む
img1 = cv2.imread(latest_file)
color = ('b','g','r')
# ヒストグラム計算
for i , col in enumerate(color):
histr1 = cv2.calcHist([img1],[i],None,[256],[0,256])
# 比較元画像を読み込む
img2 = cv2.imread('Originalcap.jpg')
color = ('b','g','r')
# ヒストグラム計算
for i , col in enumerate(color):
histr2 = cv2.calcHist([img2],[i],None,[256],[0,256])
# ヒストグラムの比較。
comphist = cv2.compareHist(histr1, histr2, cv2.HISTCMP_CORREL)
print(comphist)
# 判定
num = 0.8
if num < comphist:
# サブウィンドウ
subwindow = tk.Toplevel()
subwindow.title("成否判定") # ウィンドウタイトル
subwindow.geometry("1200x800") # ウィンドウサイズ(幅x高さ)
# ラベルの作成
labelt = tk.Label(subwindow,text='○',font=("MSゴシック", "20", "bold"),foreground='#000fff000')
labelt.pack(padx=30, pady=10)
labeltc = tk.Label(subwindow,text='画像の一致率は' + str(round(comphist * 100,2)) + '%です')
labeltc.pack(padx=30, pady=20)
# キャンバス作成
canvas = tk.Canvas(subwindow, bg="#f0f8ff", width=img_width, height=img_height)
canvas.pack(padx=30, pady=30)
canvas.create_image(0 , 0 ,anchor = tk.NW,image=lastimage)
# モーダルにする設定
subwindow.grab_set() # モーダルにする
subwindow.focus_set() # フォーカスを新しいウィンドウをへ移す
base.wait_window(subwindow)
else:
# サブウィンドウ
subwindow = tk.Toplevel()
subwindow.title("成否判定") # ウィンドウタイトル
subwindow.geometry("1200x800") # ウィンドウサイズ(幅x高さ)
# ラベル設定
labelf = tk.Label(subwindow,text='☓',font=("MSゴシック", "20", "bold"),foreground='#ff0000')
labelf.pack(padx=30, pady=10)
labeltc = tk.Label(subwindow,text='画像の一致率は' + str(round(comphist * 100,2)) + '%です')
labeltc.pack(padx=30, pady=20)
# キャンバス作成
canvas = tk.Canvas(subwindow, bg="#f0f8ff", width=img_width, height=img_height)
canvas.pack(padx=30, pady=30)
canvas.create_image(0 , 0 ,anchor = tk.NW,image=lastimage)
# モーダルにする設定
subwindow.grab_set() # モーダルにする
subwindow.focus_set() # フォーカスを新しいウィンドウをへ移す
base.wait_window(subwindow)
def ori(): #---クリックイベント比較
#ファイルを開く
fimg = [("", "*.jpg")]
iDir = os.path.abspath(os.path.dirname(__file__))
file = tkinter.filedialog.askopenfilename(filetypes = fimg,initialdir = iDir)
#ファイルを設定する
if not file:
print('キャンセル')
else:
file_oldname = file
file_newname_newfile = "Originalcap.jpg"
newFileName=shutil.move(file_oldname, file_newname_newfile)
#ウィジェットの作成
label = tk.Label(text = "ボタンを押して撮影する")
button1 = tk.Button(base, text='開始', width=20, command=clk)
button2 = tk.Button(base, text='検査', width=20, command=com)
button3 = tk.Button(base, text='検査画像設定', width=20, command=ori)
# 配置
label.pack()
button1.pack(fill = 'x',padx=20, side = 'left')
button2.pack(fill = 'x',padx=20, side = 'left')
button3.pack(fill = 'x',padx=20, side = 'left')
base.mainloop()