バーコードリーダー 【QRコード対応】

Python

バーコードリーダーの Python のプログラムについてまとめておきます。
USB カメラがあれば、QR コードや1次元のバーコードの読み取りが可能です。
以下の環境で動作確認をしています。

環境: Windows パソコン、USBカメラ(Web カメラ)
Python 3、OpenCV(+Anaconda)をインストールしています。
GUI の作成で tkinter を使用します。

背景 ~ バーコードの読み取りにトライ!

パソコンに Python をインストールしてあるとき、USB カメラが1つあれば、pyzbar などのライブラリをインストールすることで、QRコードや一般のバーコード読み取りができるようになります。

最近はポイントサービスの URL やポイントのカード番号が QR コードで配布されていることも増えています。
株式を所有している場合は、送付されてくる議決権行使書に印刷されている QR コードを読み取って議決権行使を行うと、QUO カードが当たる企画が行われていたりもします。
書籍の背面のバーコードの内容でネット検索をすると、その書籍の内容紹介や書店のサイトでのリンクを取得できます。
URL を入れたバーコードを印刷してスマートフォンで読み取るようにすることで、サイトに簡単にアクセスできるシステムを構築することも可能です。

また、バーコード認識は画像認識の基本ともいえます。カメラから画像を取得して解析を行うといった一連のプログラミングに習熟していくことで、バーコード認識、顔認識、AI/IoT での物体認識、機械学習など、応用範囲を広げていくことが可能です。

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

OpenCV がインストールしてあることが必要です。OpenCV をインストールしていない場合は、以下の関連リンク(OpenCV のインストール)を参照してください。
つぎにコンソールから以下を実行し、pyzbar をインストールしてください。

pip install pyzbar 

サンプルスクリプトの設定

① パソコン内にバーコードを扱うためのフォルダ(例:”barcode1″)を作成してください。
例: c:\user\barcode1
② 上記のフォルダに barcode_reader1.py 等の名前でテキストファイルを作成し、下記のサンプルコードをコピー&ペーストで貼りつけて保存してください。
例: c:\user\barcode1\barcode_reader1.py

※ スクリプトでは cap1 = … とした行で、接続されているカメラ番号を 0 番に設定しています。最初はこの番号で動かしてみて、カメラ番号が 0 番ではない場合や、使いたいカメラを切り替えたい場合は下記の手順の中で修正をしてください。

使い方

③ Web カメラ/USBカメラをパソコンに接続しておきます。
④ Windows のコマンドプロンプトから、barcode_reader1.py を実行してください。
例: python c:\user\barcode1\barcode_reader1.py
→ GUI が表示され、カメラの画像が表示されたら起動成功です!

※ ここで USB カメラのライブ画像が取り込めない場合は、パソコンから認識しているカメラ番号が合っていない可能性があります。
スクリプトの “# camera number” (カメラ番号)と記載している行で、値 “0” を “1”, “2” などに変更して、スクリプトを再度起動してみてください。
※ なお、カメラ番号についてよくわからない場合や、詳細を確認したい場合は、下記の関連リンク(「接続中のカメラ番号を抽出する」)を参照してみてください。カメラの動作チェックをしたいときや、パソコンにカメラが複数つながっていてどのカメラ番号で認識できているかなどを確認できると思います。

⑤ QRコードや、商品についているバーコードをカメラで映してみてください。読み取ったバーコードデータを表示します。
※ [stop] /[start] ボタンをクリックすると、ライブカメラの画像の更新を停止/開始できます。
読み取ったバーコードのデータを保持したい場合は、[stop] ボタンをクリックして読み取りを停止してください。

仕様:読み取りができるバーコードの種類

動作確認をしたところ、読み取りができるバーコードの種類は以下となっています。

バーコードの種類
読み取りができるもの JAN (13桁)、JAN 短縮タイプ(8桁)
Code128
Code39
UPC-A (12桁)、UPC-E (8桁)
Codabar
ITF
QRコード model2
読み取りができないもの PDF417、DataMatrix

主要な一次元バーコードには、ほぼ対応しています。
二次元バーコードは QRコードだけ対応しています。

サンプルスクリプトの説明

・ スクリプトの冒頭で、OpenCV、tkinter、pyzbar、PIL の Image をインポートしています。
・ def stop1() としている関数は、バーコードの読み取り、停止を設定するためのものです。
・ def decoder1() としている関数がバーコード読み取りのメインとなる部分です。
・ frame1 = tk1.Tk() としている行で、まず、GUI 画面となる frame1 を定義します。
つぎに、GUI 画面の画面サイズを設定します。
・ ラベル label1 と、読み取ったバーコードデータを表示するためのテキストボックス textbox1 (実際はエントリ)を定義します。
それぞれ、place() とした関数で、画面上で表示する位置と幅の調整をします。
・ cap1 = cv2.VideoCapture() としたところで、接続している USB 端子に対応したカメラ番号を設定しています。
カメラから画像が取得できない場合は、この番号 0 を修正します。
・ canvas1 = tk1.Canvas() としたところで、frame1 上に画像を表示するためのキャンバス Canvas を設定しています。Canvas の位置は place() で設定しています。
・ つぎにグローバルパラメータを設定し、decoder1() を実行します。
decoder1() は def で定義しており、末尾に frame1.after() を実行することで、一定時間おきに自分自身を繰り返し実行するようにしています。これにより、バーコード画像、QRコード画像を連続で読み取る動きになります。
・ frame1.mainloop() で GUI を表示します。
・ 前半の cap1 を定義したところで、カメラのハードウェアのリソースを取得しています。そこで、アプリの終了時に cap1.release() としてリソースを開放しておきます。

まとめ

これで 一次元バーコード、QRコードの読み取りも自由にできるようになりました。
使っていない USB カメラ、Web カメラがあれば、有効活用できます。

なお、動作確認が取れている USB カメラの機種や、カメラ番号の自動抽出など、以下の関連リンクにまとめていますので、もしも興味があるようでしたら、参考にしてみてください。

関連リンク
・ バーコード作成ソフトウェア 【Python & Tkinter】
・ QRコード作成ソフトウェア 【Python & Tkinter】
・ 仮想環境での OpenCV のインストール方法 & エラー時の対処方法 【Anaconda】
・ 動作確認済み USB カメラ 【おすすめ】
・ 接続中のカメラ番号を抽出する 【OpenCV & Python】
・ スマホ議決権行使をパソコンで行う方法
・ 顔認識ソフトウェア 【OpenCV】
・ バーコードリーダ Web アプリ 【Raspberry Pi & Flask】
・ バーコード作成 Web アプリ 【Raspberry Pi & Flask】

サンプルスクリプト

バーコードリーダー barcode_reader1.py

#!/usr/bin/env python
# -*- coding: utf8 -*-
import cv2
from pyzbar.pyzbar import decode 
import tkinter as tk1 
from PIL import Image, ImageTk

def stop1(): 
    global stp1 
    if stp1 == 0: 
        stp1 = 1 
        button1["text"] = "start" 
    else: 
        stp1 = 0 
        button1["text"] = "stop" 

def decoder1(): 
    global cap1 
    global frame1 
    global canvas1 
    global img1 
    global cnt1 
    global stp1 
    if stp1 == 0: 
        result0, img0 = cap1.read()
        if result0:
            decode0 = decode( cv2.cvtColor( img0, cv2.COLOR_RGBA2GRAY )  ) 
            img1 = cv2.cvtColor( img0, cv2.COLOR_BGR2RGB ) 
            if len( decode0 ) > 0: 
                str1 = decode0[0].data.decode("utf-8") 
                rect1 = decode0[0].rect
                textbox1.delete( 0, tk1.END ) 
                textbox1.insert( 0, str1 ) 
                cv2.rectangle( img1, ( rect1.left, rect1.top ), ( rect1.left + rect1.width, rect1.top + rect1.height ), ( 0, 0, 255 ), thickness = 1 ) 
                cnt1 = 0 
            else: 
                cnt1 = cnt1 + 1 
                if cnt1 > 5: 
                    textbox1.delete( 0, tk1.END ) 
            img1 = ImageTk.PhotoImage( image= Image.fromarray( img1 ) ) 
            canvas1.create_image( 0, 0, anchor=tk1.NW, image=img1 ) 
    frame1.after( 3000, decoder1 ) 

frame1 = tk1.Tk()
frame1.title(u"barcode_reader v0.1")
frame1.geometry("680x550")

label1 = tk1.Label(text='barcode data')
label1.place(x=10, y=10, width = 100) 

textbox1 = tk1.Entry( master=frame1 ) 
textbox1.place(x=110, y=10, width=400) 

button1 = tk1.Button( frame1, text='stop', command=stop1 )
button1.place(x=560, y=10, width=100)

cap1 = cv2.VideoCapture( 0, cv2.CAP_DSHOW )   # camera number 

canvas1 = tk1.Canvas( frame1, width=cap1.get( cv2.CAP_PROP_FRAME_WIDTH ), height=cap1.get( cv2.CAP_PROP_FRAME_HEIGHT ), bg='white' )
canvas1.place(x=20, y=50) 

img1 = 0 
cnt1 = 0 
stp1 = 0 
decoder1() 

frame1.mainloop()
cap1.release()
タイトルとURLをコピーしました