0
0

【Python】Pyocrを使用して受付機を考えてみた

Last updated at Posted at 2024-08-15

connpassを使用しイベントを実施してみることにしました
受付などできない時間帯に変わりをしてくれるものが作れないかPythonを学び始めたこともあり試しに作ってみることにしました

簡単に実装イメージ、connpassの受付票を読み取って、スプレッドシートと照らし合わせOKなら通知出す形です

スクリーンショット 2024-07-21 22.54.22.png

実装準備

読み取りを実装準備

関連ライブラリをインストール

!pip install pyocr
!pip install opencv-python

また日本語対応のためTesseractをインストール
今回windows使っていたのでこちらのサイトを参考に64bit版のTesseractをインストール

tesseractがうまく読み取れなかったのでパス指定し設定しました

import cv2
import pyocr
from PIL import Image
import pyocr.builders

pyocr.tesseract.TESSERACT_CMD = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

googleスプレッドシート連携

スプレッドシートの連携には、Google Cloud Platformの設定が必要です

設定に関しては、こちらのサイトを参考に行いました、手順こちらに書くと長くなってしまいそうなので、Google Cloud Platformの設定は、別でまた記載するようにします

設定終わったら、必要なライブラリをインストール

pip install --upgrade pip
pip install google
pip install gspread

googleスプレッドシートとgoogleドライブのスコープを設定します

# スプレッドシートの設定
scopes = [
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive'
]

credentials = Credentials.from_service_account_file(
key_file,
scopes=scopes
)

実装

実装の流れは、
[openCVでカメラ起動 > 文字読み取り > スプレッドシート照合 > 成功したらアラートと成功音]
という流れで作成しました

カメラ起動 > 文字読み取り

関連モジュールを読ませ、カメラの指定や、ウィンドウサイズを設定します

import cv2
import pyocr
from PIL import Image
import pyocr.builders

pyocr.tesseract.TESSERACT_CMD = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

tools = pyocr.get_available_tools()
print(tools)
tool = tools[0]

#使用するカメラを指定
cap = cv2.VideoCapture(0)

#希望のセッティングにしてみる (ウィンドウサイズ指定)
cap.set(cv2.CAP_PROP_FPS,60); 
cap.set(cv2.CAP_PROP_FRAME_WIDTH,1280);
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,720);

起動から文字読み取りまで
OCRには画像化したもの渡すため一部を切り取り画像化したものをtool.image_to_stringに渡し画面内の文字を取得します。

def OcrTest():
    while True:
        ret, frame = cap.read()

        Height, Width = frame.shape[:2]
        img = cv2.resize(frame, (int(Width), int(Height)))

        ocr(img, Width, Height)

        cv2.imshow('Ocr Test', img)

        if cv2.waitKey(100) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

def ocr(img, Width, Height):
    dst = img[100:Height-200, 100:Width-200]  # OCRで読みたい領域を切り出す
    PIL_Image = Image.fromarray(dst)
    text = tool.image_to_string(
        PIL_Image,
        lang='jpn', #日本語指定
        builder=pyocr.builders.TextBuilder()
    )

    if text != "":
        list = text.split()
        if list:
            # スプレッドシートと照合
            googleSheet(list)

スプレッドシート照合

先にgspreadやスコープや、使用するスプレッドシートを読み込ませます

# スプレッドシートの設定
key_file = "XXXXX.json" # 認証鍵

# スコープの設定
scopes = [
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive'
]

credentials = Credentials.from_service_account_file(
key_file,
scopes=scopes
)

gc = gspread.authorize(credentials)


# 対象のスプレッドシート
spreadsheet_url = "https://docs.google.com/spreadsheets/d/XXXXXX"
spreadsheet = gc.open_by_url(spreadsheet_url)

スプレッドシート内、OCRから読み取った文字列検索
対象文字を含むセルが見つかったら、出席と書き込みます

def googleSheet(text):
    worksheet = spreadsheet.sheet1
    all_vals = spreadsheet.sheet1.get_all_values()
    
    terget_row = 8 #書き込み対象列番号
    match_row = []
    cal = 1
    for cols in all_vals:
        row = 0
        for val in cols:
            for txt in text:
                if(val == txt):
                    match_row = [cal,row]
                    break

            row += 1
            
        cal += 1
    
    #文字検索
    if(match_row):
        # 対象セルに出席と書き込み
        worksheet.update_cell(match_row[0], terget_row, '出席')

        # 受付通知アラートへ
        showMessage("受付完了","info",3000)

成功通知

受付が成功した旨を音と、アラートでお知らせします

音の通知には、playsoundというライブラリを使用しました

pip install playsound

アラートに関しては、tkinterとPythonに入っているライブラリをそのまま使用します

def showMessage(message, type='info', timeout=2500):
    import tkinter as tk
    from tkinter import messagebox as msgb

    root = tk.Tk()
    root.withdraw()
    try:
        # root.after(timeout, root.destroy)
        if type == 'info':

            # 成功音
            playsound("SAMPLE.mp3")

            # アラートが自動消えるタイマー
            root.after(timeout, root.destroy)

            # アラート表示
            msgb.showinfo('Info', message, master=root)
        elif type == 'warning':
            msgb.showwarning('Warning', message, master=root)
        elif type == 'error':
            msgb.showerror('Error', message, master=root)
    except:
        pass

一連の流れは以上。
実際に作成した全体のコードはこちらに

これにて、スプレッドシートに受付書き込め通知まで出すことができました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0