PythonでパソコンのカメラでQRコードを読み込む。(バーコードも読めます)

Python

パソコンのカメラでQRコードを読み込むには?

プログラムを作成しているとカメラを利用して帳票やスマートフォンに表示されているQRコードを読みたくなる場合があります。例えば以下のシチュエーションの場合が考えられます。

利用シチュエーション

帳票の伝票番号読み込み
伝票番号をスキャンすることで人が直接番号を入力する手間を省き、その結果として承認処理をより迅速にまたは効率的に進めることができるというメリットがあります。これは特に大量の伝票を扱う業務において作業の速度と精度を大幅に向上させることが可能です。

URLの読み込み
QRコードを使用することでウェブサイトのアドレス(URL)を手動で入力する際に生じる時間の浪費や入力ミスといった問題を効果的に解決します。URLが長いまたは複雑である場合特にその効果は顕著です。ユーザーはQRコードをスキャンするだけで直接関連するウェブページにアクセスできるため使い勝手が大幅に向上します。

入力の正確性
手入力による作業には必然的に入力ミスが伴うことがありますが、QRコードを利用することでこのようなミスを大幅に減少させることができます。データの入力において正確性を確保することは、特に重要な情報を扱う場合には欠かせない要素です。QRコードを使うことで正確なデータの転送を保証し、手入力時に発生する誤字脱字や数字の入れ違えといった問題から解放されます。

    本記事ではノートパソコン等に付属しているカメラや後付けのWebカメラ等を利用してQRコードを読み込みする関数を紹介します。

    パソコンのカメラでQRコードを読み込みするサンプルコード

    サンプルコードを紹介します。

    # pip install opencv-python
    # OpenCV (Open Source Computer Vision Library) ライブラリを利用
    import cv2
    # pip install pyzbar 
    # pyzbarバーコードやQRコードを読み取り、解析するためのライブラリ
    from pyzbar.pyzbar import decode
    
    def read_qr_code(return_type=False):
        """
        PCのカメラを使用してQRコードを読み取り、解析した結果を返す関数。
        
        Args:
            return_type (bool): 読み取り結果にコードのタイプ(形式)も含めるかどうか。デフォルトはFalse。
        
        Returns:
            str: 読み取ったコードのデータ。コードが見つからなかった場合はNoneを返す。
            tuple: (str, str) 読み取ったコードのデータとそのタイプ。return_typeがTrueの場合。
        """
    
        # カメラのキャプチャを開始
        cap = cv2.VideoCapture(0)
        
        try:
            while True:
                # カメラからフレームを読み込む
                ret, frame = cap.read()
                if not ret:
                    continue  # フレームが正しく読み込めなかった場合、次のフレームを読み込む
                
                # コードのデコード
                decoded_objects = decode(frame)
                for obj in decoded_objects:
                    # コードタイプも返す場合
                    if return_type:
                        return (obj.data.decode('utf-8'), obj.type)
                    else:
                        # QRコードのデータのみを返す
                        return obj.data.decode('utf-8')
                
                # フレームを表示(デバッグ用)コメントアウトで表示しなくなります。
                cv2.imshow('Code Reader', frame)
                
                # [ESC] を押すと読み取りを停止
                if cv2.waitKey(1) & 0xFF == 27: # [ESC] キーのASCIIコードは27
                    break
                
        finally:
            # カメラのキャプチャを解放
            cap.release()
            # 作成したウィンドウをすべて閉じる
            cv2.destroyAllWindows()
    
        return None
    
    
    ########################################
    # 関数のテスト
    if __name__ == "__main__":
        
        # コードのみ読み込み
        print("読み取ったデータ:", read_qr_code())  
        
        # タイプ情報も含めて結果を表示
        # print("読み取ったデータ:", read_qr_code(True))  
    
    
    

    カメラで読み込みした情報を画像化するOpenCVとバーコードやQRコードを読み取りするpyzbarを使用していますので事前に以下を参照してインストールしてください。

    pip install opencv-python
    pip install pyzbar 

    実行結果

    例えば本サイトQRコードを作成するのこの記事を開くと以下の図のようなQRコードが表示されます。

    これをPCのカメラで読み込ませると結果は以下のようになります。

    読み取ったデータ: https://kamedassou.com

    pyzbarはバーコードも読み込みできる仕様なので、本サイトのバーコードを作成するこの記事を開くと以下の図のようなバーコードが表示されます。

    これをPCのカメラで読み込ませると結果は以下のようになります。

    読み取ったデータ: 4901750404857

    解説

    処理の方法としてはOpenCVでカメラ動画を静止画にしてpyzbarで静止画からコードを判定して処理をしている形となります、そのためコード読み込みがうまくできなかった場合には以下WARNINGが出力される場合があります。WARNINGですので気にしなくとも問題ありません。

    WARNING: .\zbar\decoder\pdf417.c:89: <unknown>: Assertion "g[0] >= 0 && g[1] >= 0 && g[2] >= 0" failed.
            dir=0 sig=9646 k=6 g0=fa3 g1=ffffffff g2=9fc buf[0000]=

    読み取ったコードの種類を知りたい。

    関数のテストの以下部分をコメントアウトするとどのようなコードを読み取ったかもわかります。

        # タイプ情報も含めて結果を表示
        print("読み取ったデータ:", read_qr_code(True))  

    試しに先ほどのQRコードを読み込みすると’QRCODE’と返します。

    読み取ったデータ: ('https://kamedassou.com', 'QRCODE')

    ※ただISBN13を読み込みするとEAN13、ITFはI25と返すようなのでこの辺は運用と調整が必要かと思います。

    カメラが複数台の場合

    複数台のカメラが付いている場合には以下文を調整する必要があります。
    引数の(0)を(1)に変更したりして、接続するカメラに合わせる必要があります。

        # カメラのキャプチャを開始
        cap = cv2.VideoCapture(0)

    デバッグ用の画面が不要な場合

    このサンプルを起動すると以下の図のようにパソコンの画面にカメラで映した映像が表示されます。

    これが不要な場合には、以下をコメントアウトすることにより表示されなくなります。

                # フレームを表示(デバッグ用)コメントアウトで表示しなくなります。
                cv2.imshow('Code Reader', frame)

    読み取りの停止

    ESCキーで読み取り停止しますので参考にしてください。別のキーを割り当てする場合はこちらを変更してください。

                # [ESC] を押すと読み取りを停止
                if cv2.waitKey(1) & 0xFF == 27:

    メモ帳等に入力したい場合

    紹介したソースの場合、コンソールに読み込みしたコードを表示する処理となっていますが、戻り値をメモ帳やEXCELに直接入力したい場合には以下を参考にすると対応が可能となります。

    pyperclipとpyautoguiのimport追加と関数のテスト部分を変更しています。

    # pip install opencv-python
    # OpenCV (Open Source Computer Vision Library) ライブラリを利用
    import cv2
    
    # pip install pyzbar 
    # pyzbarバーコードやQRコードを読み取り、解析するためのライブラリ
    from pyzbar.pyzbar import decode
    
    # pip install pyperclip pyautogui
    # キーボードやマウス操作を自動化するためのライブラリ
    import pyperclip
    
    # pip install pyautogui
    # クリップボードへのアクセスをするライブラリ
    import pyautogui
    
    def read_qr_code():
        """
        PCのカメラを使用してQRコードを読み取り、アクティブな画面に貼り付ける関数。
        """
        
        # カメラのキャプチャを開始
        cap = cv2.VideoCapture(0)
        
        try:
            while True:
                ret, frame = cap.read()
                if not ret:
                    continue
                
                decoded_objects = decode(frame)
                for obj in decoded_objects:
                    qr_data = obj.data.decode('utf-8')
                    return qr_data
                
                # フレームを表示(デバッグ用)コメントアウトで表示しなくなります。
                cv2.imshow('Code Reader', frame)
                
                # [ESC] を押すと読み取りを停止
                if cv2.waitKey(1) & 0xFF == 27: # [ESC] キーのASCIIコードは27
                    break
                
        finally:
            # カメラのキャプチャを解放
            cap.release()
            # 作成したウィンドウをすべて閉じる
            cv2.destroyAllWindows()
    
        return None
    
    # 関数のテスト
    if __name__ == "__main__":
        
        pyperclip.copy(read_qr_code())
        # クリップボードの内容を貼り付け
        pyautogui.hotkey('ctrl', 'v')
        pyautogui.press('enter')  # Enterキーを押す

    最後に

    以上がPythonを利用してパソコンのカメラでQRコードやバーコードを読み込みする方法です。

    読み込みすることで省力化となる業務がかなりあると思いますので、興味のある方は試してみてはいかがでしょうか。

    コメント

    タイトルとURLをコピーしました