Pythonでファイルを選択できるようにする

Posted at 2023 年 06 月 25 日

今回は検査に使用する元画像を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()