ウェブカメラ、OpenCVとPythonを使用してスキャンバーコードとQRコード


DynamsoftはWindows、Linux、MacOS、およびラズベリーパイのOSのためのエンタープライズクラスのPythonのバーコードとQRコードSDKを提供する唯一の会社です.SDKは、開発者はすぐに堅牢なコマンドライン、Web、およびソースの広い範囲からバーコードやQRコードをスキャンできるデスクトップアプリケーションを構築することができます.この記事では、Dynamsoft Barcode Reader、OpenCV、およびウェブカメラを使用して、クロスプラットフォームのデスクトップバーコードとQRコードスキャナをPythonで作成します.

ダウンロード


  • 大阪大学
    ウェブカメラとステッチ画像にアクセスするために使用します.
    pip install opencv-python
    

  • バーコードリーダー
    バーコードや画像からQRコードをデコードするために使用されます.
    pip install dbr
    
  • 許可活性化


    ダイナモバーコードリーダーを有効にするには、hereからデスクトップライセンスキーを取得します.
    BarcodeReader.init_license("LICENSE-KEY")
    

    バーコードとQRコードスキャナをビルドする手順


    PythonのGIL ( Global Interpreter Lock )はマルチスレッドアプリケーションのパフォーマンスボトルネックです.したがって、CPUの集中的なバーコードとQRコード検出アルゴリズムを実行するPythonのマルチプロセッシングライブラリを使用することをお勧めします.サンプルコードvideo_threaded.pyはPythonのマルチプロセッシングライブラリを使用する方法を示します.
    ここでは、バーコードとQRコードスキャナを構築する手順です

  • 必要なパッケージをインポートします
    import numpy as np
    import cv2 as cv
    
    from multiprocessing.pool import ThreadPool
    from collections import deque
    
    import dbr
    from dbr import *
    

  • ライセンスキーを設定し、Dynamsoftバーコードリーダーを有効にし、インスタンス化します.
    BarcodeReader.init_license("LICENSE-KEY")
    reader = BarcodeReader()
    

  • 使用するプロセスの量を持つスレッドプールを作成します.
    threadn = 1 # cv.getNumberOfCPUs()
    pool = ThreadPool(processes = threadn)
    barcodeTasks = deque()
    
    注意:すべてのCPUコアを使用する場合、CPUの使用量は高くなります.

  • ウェブカメラのビデオフレームからバーコードとQRコードを検出するためにタスク関数を作成します
    def process_frame(frame):
        results = None
        try:
            results = reader.decode_buffer(frame)
        except BarcodeReaderError as bre:
            print(bre)
    
        return results
    
    while True:
        ret, frame = cap.read()
        while len(barcodeTasks) > 0 and barcodeTasks[0].ready():
            results = barcodeTasks.popleft().get()
            if results != None:
                for result in results:
                    points = result.localization_result.localization_points
                    cv.line(frame, points[0], points[1], (0,255,0), 2)
                    cv.line(frame, points[1], points[2], (0,255,0), 2)
                    cv.line(frame, points[2], points[3], (0,255,0), 2)
                    cv.line(frame, points[3], points[0], (0,255,0), 2)
                    cv.putText(frame, result.barcode_text, points[0], cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255))
    
        if len(barcodeTasks) < threadn:
            task = pool.apply_async(process_frame, (frame.copy(), ))
            barcodeTasks.append(task)
    
        cv.imshow('Barcode & QR Code Scanner', frame)
        ch = cv.waitKey(1)
        if ch == 27:
            break
    

  • バーコードとQRコードスキャナを実行します.

  • Dynamsoftバーコードリーダーは、単一の画像から複数のバーコードとQRコードを検出することができます.しかし,画質は検出精度に影響する.すべてのバーコードとQRコードをキャプチャするには、上記の画像で見ることができるように、我々はフィールドのレンズの深さを増やす必要があります.このように、バーコードとQRコードは、読むにはあまりに小さくなるかもしれません.この問題を解決するために、我々はカメラの近くにスキャンするための高品質の画像を取得し、パノラマに複数のバーコードとQRコード画像をステッチするOpenCVのステッチAPIを使用します.

    複数のバーコードとQRコード画像をパノラマにステッチする


    OpenCVのリポジトリAPIを使用する方法を示すファイルは、stitching.pyファイルが含まれます.
    パノラマステッチを実装するには、次の手順に従います.

  • Stitcherオブジェクトを初期化します
    modes = (cv.Stitcher_PANORAMA, cv.Stitcher_SCANS)
    stitcher = cv.Stitcher.create(modes[1])
    stitcher.setPanoConfidenceThresh(0.5)
    

  • バーコードとQRコードを含む画像をステッチするための新しいタスク関数を作成します.
    panoramaPool = ThreadPool(processes = threadn)
    panoramaTask = deque()
    
    def stitch_frame(self, frame):
        try:
            results = self.reader.decode_buffer(frame)
            if results != None:
                for result in results:
                    points = result.localization_result.localization_points
                    cv.line(frame, points[0], points[1], (0,255,0), 2)
                    cv.line(frame, points[1], points[2], (0,255,0), 2)
                    cv.line(frame, points[2], points[3], (0,255,0), 2)
                    cv.line(frame, points[3], points[0], (0,255,0), 2)
                    cv.putText(frame, result.barcode_text, points[0], cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255))
    
                self.panorama.append((frame, len(results)))
                print('Stitching .............')
                try:
                    all_images = [frame for frame, count in self.panorama]
                    status, image = self.stitcher.stitch(all_images)
    
                    if status != cv.Stitcher_OK:
                        print("Can't stitch images, error code = %d" % status)
                        return self.panorama[0][0]
                    else:
                        # Stop stitching if the output image is out of control
                        if image.shape[0] >= frame.shape[0] * 1.5:
                            self.isPanoramaDone = True
                            self.save_frame(all_images[0])
                            print('Stitching is done.............')
                            return None
    
                        # Drop the stitched image if its quality is not good enough
                        total = 0
                        for frame, count in self.panorama:
                            total += count
    
                        count_stitch = self.count_barcodes(image)
                        if count_stitch > total or count_stitch < self.panorama[0][1]:
                            return self.panorama[0][0]
    
                        # Wait for the next stitching and return the current stitched image
                        self.panorama = [(image, count_stitch)]
                        return image
                except Exception as e:
                    print(e)
                    return None
    
        except BarcodeReaderError as e:
            print(e)
            return None
    
        return None
    
    while len(panoramaTask) > 0 and panoramaTask[0].ready():
        image = panoramaTask.popleft().get()
        if image is not None:
            cv.imshow('panorama', image)
    
    if len(panoramaTask) < threadn:
        task = panoramaPool.apply_async(self.stitch_frame, (frame_cp, ))
        panoramaTask.append(task)
    

  • パノラマステッチ結果を得るためにコードを実行します.

  • ソースコード


    https://github.com/yushulx/webcam-barcode-qrcode-reader-python