connpassを使用しイベントを実施してみることにしました
受付などできない時間帯に変わりをしてくれるものが作れないかPythonを学び始めたこともあり試しに作ってみることにしました
簡単に実装イメージ、connpassの受付票を読み取って、スプレッドシートと照らし合わせOKなら通知出す形です
実装準備
読み取りを実装準備
関連ライブラリをインストール
!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
一連の流れは以上。
実際に作成した全体のコードはこちらのocr_reception_machine.pyに
これにて、スプレッドシートに受付書き込め通知まで出すことができました!
追記
connpassの受付票にQRコードが表示されるようになりました
QRコードを読み取るようにすると精度が上がるので、調整しました
cv2のQRCodeDetectorを使用します
# QRコードのデコーダーを準備
qr_detector = cv2.QRCodeDetector()
while True:
ret, frame = cap.read()
if not ret:
print("カメラからの映像が取得できませんでした。")
break
# QRコードをデコード
data, bbox, _ = qr_detector.detectAndDecode(frame)
if data:
# 読み取ったデータを確認
print(data)
読み取った内容は、受付番号が含まれているURLになっており、イベント管理者がコンパスにログインした端末でQRコードを読み取りアクセスすると受付状態になります
ただし、今回は、連続して読み取り可能にするため読み取ったURLの受付番号を切り取り、
受付表スプレッドシートを参照し受付を可能にすることに
url = data
match = re.search(r'/([^/]+)/$', url)
if match:
# 末尾にある受付番号を取得
result = match.group(1)
# 以前作ったスプレッドシートマッチ用のメソッドgoogleSheetに番号を渡す
if(googleSheet([result])):
print("受付成功")
これでQRコードを使う形に変更できました
実際に作成した全体のコードはocr_reception_machine.py_qr.pyになります