USB接続のカメラを使ってQRコードリーダーを作ります。
環境とモジュール
Python3.6以上、Windows10、市販のUSBカメラ
OpenCV、PIL、pyzbar (別途インストールが必要)
参考にした記事
カメラでQRコードを読み取る方法(Python)
tkinter canvasの使い方
Pythonコード
"""
OpenCVの動画取得機能を利用し、TkのCanvasに描画して、QRコードを認識させるプログラム
"""
from datetime import datetime
from time import sleep
import tkinter
import cv2
from PIL import Image, ImageTk
from pyzbar import pyzbar
root = tkinter.Tk()
root.title("QR reader")
root.geometry("640x480")
CANVAS_X = 640
CANVAS_Y = 480
# Canvas作成
canvas = tkinter.Canvas(root, width=CANVAS_X, height=CANVAS_Y)
canvas.pack()
# VideoCaptureの引数にカメラ番号を入れる。
# デフォルトでは0、ノートPCの内臓Webカメラは0、別にUSBカメラを接続した場合は1を入れる。
cap = cv2.VideoCapture(0)
def show_frame():
global CANVAS_X, CANVAS_Y
ret, frame = cap.read()
if ret == False:
print('カメラから画像を取得できませんでした')
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # BGRなのでRGBに変換
image_pil = Image.fromarray(image_rgb) # RGBからPILフォーマットへ変換
image_tk = ImageTk.PhotoImage(image_pil) # ImageTkフォーマットへ変換
# image_tkがどこからも参照されないとすぐ破棄される。
# そのために下のようにインスタンスを作っておくかグローバル変数にしておく
canvas.image_tk = image_tk
# global image_tk
# ImageTk 画像配置 画像の中心が指定した座標x,yになる
canvas.create_image(CANVAS_X / 2, CANVAS_Y / 2, image=image_tk)
# Canvasに現在の日時を表示
now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
canvas.create_text(CANVAS_X / 2, 30, text=now_time, font=("Helvetica", 18, "bold"))
# 画像からQRコードを読み取る
decoded_objs = pyzbar.decode(frame)
# pyzbar.decode(frame)の返値
# ('Decoded', ['data', 'type', 'rect', 'polygon'])
# [0][0]->.data, [0][1]->.type, [0][2]->rect, [0][3]->polygon
# 配列要素がある場合
if decoded_objs != []:
# [0][0]->.data, [0][1]->.type, [0][2]->rect
# example
# for obj in decoded_objs:
# print('Type: ', obj.type)
str_dec_obj = decoded_objs[0][0].decode('utf-8', 'ignore')
print('QR cord: {}'.format(str_dec_obj))
left, top, width, height = decoded_objs[0][2]
# 取得したQRコードの範囲を描画
canvas.create_rectangle(left, top, left + width, top + height, outline="green", width=5)
# 取得したQRの内容を表示
canvas.create_text(left + (width / 2), top - 30, text=str_dec_obj, font=("Helvetica", 20, "bold"))
# QRコードを取得して、その内容をTextに書き出し、そのままTKのプログラムを終了するコード
# with open('QR_read_data.txt', 'w') as exportFile:
# exportFile.write(str_dec_obj)
# sleep(1)
# cap.release()
# root.quit()
# 10msごとにこの関数を呼び出す
canvas.after(10, show_frame)
show_frame()
root.mainloop()