今、話題の人工知能(AI)などで人気のPython。初心者に優しいとか言われていますが、全然優しくない! という事を、つらつら、愚痴っていきます

286.ラズパイ無双[22 QRコード読取]

»

初回:2022/11/23

 Raspberry Pi (ラズベリーパイ、通称"ラズパイ")で何か作ってみようという新シリーズです。今回は、実務にも役立つ『QRコード』の読取プログラムをご紹介したいと思います。

P子「QRコードって何?」※1

 無理くりの話の持って行き方ですけど、そのあたりも含めて、説明していきたいと思います。

【目次】

1.QRコードとは?

 ≪参考1≫
  https://www.qrcode.com/about/
  QRコードとは?

 「QRコード」は株式会社デンソーウェーブさんの登録商標で、JIS X 0510、ISO/IEC18004で規格化されています。
 このあたりは、≪参考1≫からさらに、『QRコードの規格化・標準化』に書かれています。

 デンソーウェーブさんが保有するQRコードの特許(特許第 2938338号)も、権利行使を行わないことを宣言されているそうです。

P子「太っ腹ね」

 さらに、気になるライセンス料とか、商用利用とかについても、使用料不要で、商用利用も可能です。ただし『QRコードの名称』を使用する場合には、登録商標文の記載は必要です。

 ≪参考2≫
  https://www.qrcode.com/faq.html
  FAQ

2.QRコードのバージョン

 ≪参考3≫
  https://www.qrcode.com/about/version.html
  QRコードの情報量とバージョン

 以下に扱うのは、一般的なQRコードであるモデル2というQRコードです。

 QRコードのバージョン(種類)は、1から40まであり、それらはセル構成(セル数)が決められています。ところが、誤り訂正レベルに応じたデータビット数(混合)が異なるので、数字、英数字、バイナリ、漢字で登録できる文字数が異なってきます。
 また、実際に印字する場合は、セル自体の大きさも指定する為、QRコードの印字サイズを簡単に決めることはできません。

 工業系業務システムで使用する場合には、ある程度の文字数とか文字種類は決まっていると思いますので、現品票とか作業指示書などに使用する場合は、サイズが決まってくると非常に助かります。

 このあたりの知識は、QRコードの作成時に必要になってきますが、とりあえず読み取りだけなら気にしなくて構いません。

P子「ホントに気にしなくていいの?」

 まあ、ほんのちょっとだけ、気にしておいてください。

3.openCVで読取

 ここからが本題です。

 ≪参考4≫
  https://note.nkmk.me/python-opencv-qrcode/
  Python, OpenCVでQRコードを検出・読み取り

 まずは、openCVのみでQRコードを検出・読み取る方法です。
 cv2.QRCodeDetector というクラスを使用します。

import cv2 LIME = ( 0, 255, 0) # 明るい緑 RED = ( 0, 0, 255) # 赤 THICK = 2 # 線の太さ qr = cv2.QRCodeDetector() cap = cv2.VideoCapture(0) while True: _, frame = cap.read() # ret:検出で True、dec_inf:文字列要素のタプル、pos:QRコードの四隅の座標 ret, dec_inf, pos, _ = qr.detectAndDecodeMulti(frame) if ret: for s, p in zip(dec_inf, pos): pts = p.astype(int) # QRコードのポリゴンの座標 # [[155 132], [286 140], [281 263], [151 260]] 左上、右上、右下、左下 # print(pts) if s: print(s) # 左上の座標 (X座標の最小値と、Y座標の最小値が左上の位置) p1 = (min(pts[:,0]),min(pts[:,1])) frame = cv2.polylines(frame,[pts],True,LIME,THICK) cv2.putText(frame,s,p1,cv2.FONT_HERSHEY_PLAIN,1,LIME,1,cv2.LINE_AA) else: # バツ印の意味で、斜線を引く(各ポイントは対角線になる) frame = cv2.line(frame,pts[0],pts[2],RED,THICK) frame = cv2.line(frame,pts[1],pts[3],RED,THICK) cv2.imshow('QR CODE', frame) k = cv2.waitKey(10) # ミリ秒単位で表されるキーボード入力待ち時間 if k == ord('q') or k == 27: # q または、ESC で終了 break if cap is not None : cap.release() cv2.destroyAllWindows() # すべてのウィンドウを閉じる
 qr = cv2.QRCodeDetector() で、オブジェクトを生成して、qr.detectAndDecodeMulti(frame) で検出とデコードを行います。メソッド名を見て分かるように、複数のQRコードを見つけることができます。

 QRコードを見つけたものの、エンコード...文字列に変換できなかった場合は、空文字列が得られます。

 後は、QRコードの周りを囲ったり、×を付けたり、エンコード出来た文字列を表示したりしているだけです。

4.pyzbarで読取

 ZBarはバーコードを読み取るためのオープンソースライブラリで、pyzbarはPythonでZBarを利用するためのライブラリです。

 ≪参考5≫
  https://qiita.com/orengepy/items/1d405762813846765ec1
  Pythonでバーコードを読み込む

 まずは、インストールを行います。

 $ pip3 install pyzbar

 これだけで、使えるようになります。

from pyzbar.pyzbar import decode,ZBarSymbol # QRコードのスキャン import cv2 import numpy as np # polylines で使用 LIME = ( 0, 255, 0) # 明るい緑 RED = ( 0, 0, 255) # 赤 THICK = 2 # 線の太さ cap = cv2.VideoCapture(0) while True: _, frame = cap.read() # data は、(テキスト、タイプ、Rect、polygon、quality、orientation) data = decode(frame, symbols=[ZBarSymbol.QRCODE,ZBarSymbol.CODE39]) if len(data) > 0 and len(data[0]) > 0 and len(data[0][0]) > 0 : for (s,t,r,p,q,o) in data : # (テキスト、タイプ、Rect、polygon、quality、orientation) s = s.decode('utf-8', 'ignore') # コード内容 # p ⇒ [Point(x=123, y=277), Point(x=127, y=353), Point(x=202, y=346), Point(x=196, y=273)] pts = np.array(p, np.int32) # pts ⇒ [[123 277],[127 352],[202 346],[196 272]] # print(f"{o} {pts}") # 左上の座標 (X座標の最小値と、Y座標の最小値が左上の位置) p1 = (min(pts[:,0]),min(pts[:,1])) frame = cv2.polylines(frame,[pts],True,LIME,THICK) # Trueは、閉包図形 cv2.putText(frame,s,p1,cv2.FONT_HERSHEY_PLAIN,1,LIME,1,cv2.LINE_AA) # テスト用の処理 if 'ERR' in s : # サンプル。ERR 文字列を含むかどうかで判定 # バツ印の意味で、斜線を引く(各ポイントは対角線になる) frame = cv2.line(frame,pts[0],pts[2],RED,THICK*2) # 線幅(THICK)を2倍にする。 frame = cv2.line(frame,pts[1],pts[3],RED,THICK*2) # 線幅(THICK)を2倍にする。 cv2.imshow('QR CODE', frame) k = cv2.waitKey(10) # ミリ秒単位で表されるキーボード入力待ち時間 if k == ord('q') or k == 27: # q または、ESC で終了 break if cap is not None : cap.release() cv2.destroyAllWindows() # すべてのウィンドウを閉じる

5.まとめ

 きちんと評価したわけではありませんが、pyzbar の方が、読み取り感度が高いようです。

 ただ、ラズパイでQRコードを複数同時に読み取ることが出来れば、工業系業務システムでの運用も色々と考えられます。

 なかなか楽しみです。

ほな、さいなら

======= <<注釈>>=======

※1 P子「QRコードって何?」
 P子とは、私があこがれているツンデレPythonの仮想女性の心の声です。

Comment(0)

コメント

コメントを投稿する