"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como construir um scanner de código de barras Python para Windows, Linux e macOS

Como construir um scanner de código de barras Python para Windows, Linux e macOS

Publicado em 2024-11-02
Navegar:187

Leitura de código de barras tornou-se uma ferramenta essencial em vários setores, desde varejo e logística até saúde. Em plataformas desktop, permite a rápida captura e processamento de informações sem entrada manual de dados, economizando tempo e reduzindo erros. Neste tutorial, continuaremos explorando os recursos do Dynamsoft Capture Vision SDK criando um leitor de código de barras Python para Windows, Linux e macOS.

Demonstração do scanner de código de barras Python no macOS

Pré-requisitos

  • Licença de avaliação do Dynamsoft Capture Vision: Obtenha uma chave de licença de avaliação de 30 dias para o Dynamsoft Capture Vision SDK.

  • Pacotes Python: Instale os pacotes Python necessários usando os seguintes comandos:

    pip install dynamsoft-capture-vision-bundle opencv-python
    

    Para que servem esses pacotes?

    • Dynamsoft-capture-vision-bundle é o Dynamsoft Capture Vision SDK para Python.
    • opencv-python captura quadros de câmera e exibe resultados de imagens processadas.

Lendo códigos de barras de imagens estáticas

Como o Dynamsoft Capture Vision SDK é uma estrutura unificada integrada com várias tarefas de processamento de imagem, podemos alternar facilmente entre os modos de processamento de imagem passando o nome PresetTemplate para o método capture().

Modelos integrados do Dynamsoft Capture Vision SDK

O trecho de código a seguir mostra a enumeração PresetTemplate integrada no Dynamsoft Capture Vision SDK:

class EnumPresetTemplate(Enum):
    PT_DEFAULT = _DynamsoftCaptureVisionRouter.getPT_DEFAULT()
    PT_READ_BARCODES = _DynamsoftCaptureVisionRouter.getPT_READ_BARCODES()
    PT_RECOGNIZE_TEXT_LINES = _DynamsoftCaptureVisionRouter.getPT_RECOGNIZE_TEXT_LINES()
    PT_DETECT_DOCUMENT_BOUNDARIES = (
        _DynamsoftCaptureVisionRouter.getPT_DETECT_DOCUMENT_BOUNDARIES()
    )
    PT_DETECT_AND_NORMALIZE_DOCUMENT = (
        _DynamsoftCaptureVisionRouter.getPT_DETECT_AND_NORMALIZE_DOCUMENT()
    )
    PT_NORMALIZE_DOCUMENT = _DynamsoftCaptureVisionRouter.getPT_NORMALIZE_DOCUMENT()
    PT_READ_BARCODES_SPEED_FIRST = (
        _DynamsoftCaptureVisionRouter.getPT_READ_BARCODES_SPEED_FIRST()
    )
    PT_READ_BARCODES_READ_RATE_FIRST = (
        _DynamsoftCaptureVisionRouter.getPT_READ_BARCODES_READ_RATE_FIRST()
    )
    PT_READ_SINGLE_BARCODE = _DynamsoftCaptureVisionRouter.getPT_READ_SINGLE_BARCODE()
    PT_RECOGNIZE_NUMBERS = _DynamsoftCaptureVisionRouter.getPT_RECOGNIZE_NUMBERS()
    PT_RECOGNIZE_LETTERS = _DynamsoftCaptureVisionRouter.getPT_RECOGNIZE_LETTERS()
    PT_RECOGNIZE_NUMBERS_AND_LETTERS = (
        _DynamsoftCaptureVisionRouter.getPT_RECOGNIZE_NUMBERS_AND_LETTERS()
    )
    PT_RECOGNIZE_NUMBERS_AND_UPPERCASE_LETTERS = (
        _DynamsoftCaptureVisionRouter.getPT_RECOGNIZE_NUMBERS_AND_UPPERCASE_LETTERS()
    )
    PT_RECOGNIZE_UPPERCASE_LETTERS = (
        _DynamsoftCaptureVisionRouter.getPT_RECOGNIZE_UPPERCASE_LETTERS()
    )

O modelo PT_DEFAULT suporta múltiplas tarefas, incluindo detecção de documentos, reconhecimento MRZ e detecção de código de barras. Para otimizar o desempenho especificamente para detecção de código de barras, defina o modelo como EnumPresetTemplate.PT_READ_BARCODES.value.

Código Python para detecção de código de barras

Referenciando os exemplos anteriores de detecção de documentos e reconhecimento de MRZ, o código a seguir pode ser usado para ler códigos de barras de imagens estáticas:

import sys
from dynamsoft_capture_vision_bundle import *
import os
import cv2
import numpy as np
from utils import *

if __name__ == '__main__':

    print("**********************************************************")
    print("Welcome to Dynamsoft Capture Vision - Barcode Sample")
    print("**********************************************************")

    error_code, error_message = LicenseManager.init_license(
        "LICENSE-KEY")
    if error_code != EnumErrorCode.EC_OK and error_code != EnumErrorCode.EC_LICENSE_CACHE_USED:
        print("License initialization failed: ErrorCode:",
              error_code, ", ErrorString:", error_message)
    else:
        cvr_instance = CaptureVisionRouter()
        while (True):
            image_path = input(
                ">> Input your image full path:\n"
                ">> 'Enter' for sample image or 'Q'/'q' to quit\n"
            ).strip('\'"')

            if image_path.lower() == "q":
                sys.exit(0)

            if image_path == "":
                image_path = "../../../images/multi.png"

            if not os.path.exists(image_path):
                print("The image path does not exist.")
                continue
            result = cvr_instance.capture(
                image_path, EnumPresetTemplate.PT_READ_BARCODES.value)
            if result.get_error_code() != EnumErrorCode.EC_OK:
                print("Error:", result.get_error_code(),
                      result.get_error_string())
            else:
                cv_image = cv2.imread(image_path)

                items = result.get_items()
                print('Found {} barcodes.'.format(len(items)))
                for item in items:
                    format_type = item.get_format()
                    text = item.get_text()
                    print("Barcode Format:", format_type)
                    print("Barcode Text:", text)

                    location = item.get_location()
                    x1 = location.points[0].x
                    y1 = location.points[0].y
                    x2 = location.points[1].x
                    y2 = location.points[1].y
                    x3 = location.points[2].x
                    y3 = location.points[2].y
                    x4 = location.points[3].x
                    y4 = location.points[3].y
                    del location

                    cv2.drawContours(
                        cv_image, [np.intp([(x1, y1), (x2, y2), (x3, y3), (x4, y4)])], 0, (0, 255, 0), 2)

                    cv2.putText(cv_image, text, (x1, y1 - 10),
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

                cv2.imshow(
                    "Original Image with Detected Barcodes", cv_image)
                cv2.waitKey(0)
                cv2.destroyAllWindows()

    input("Press Enter to quit...")

Nota: Substitua LICENSE-KEY pela sua chave de licença válida.

Testando o leitor de código de barras Python com uma imagem de vários códigos de barras

Decodificar vários códigos de barras a partir de uma única imagem é um caso de uso comum no varejo e na logística. A imagem a seguir contém vários códigos de barras de diferentes formatos:

How to Build a Python Barcode Scanner for Windows, Linux, and macOS

Detecção de múltiplos códigos de barras em tempo real com uma webcam

Ao ler códigos de barras de um arquivo de imagem, invocamos o método capture() no thread principal. Entretanto, para processar fluxos de vídeo em tempo real de uma webcam, é necessária uma abordagem diferente para evitar o bloqueio do thread principal. O Dynamsoft Capture Vision SDK fornece um mecanismo integrado para lidar com quadros de vídeo em tempo real e processá-los de forma assíncrona em um thread de trabalho C nativo. Para implementar isso, estenda as classes ImageSourceAdapter e CapturedResultReceiver para lidar com os dados da imagem e os resultados capturados, respectivamente, e depois chame o método start_capturing() para começar a processar o stream de vídeo.

from dynamsoft_capture_vision_bundle import *
import cv2
import numpy as np
import queue
from utils import *


class FrameFetcher(ImageSourceAdapter):
    def has_next_image_to_fetch(self) -> bool:
        return True

    def add_frame(self, imageData):
        self.add_image_to_buffer(imageData)


class MyCapturedResultReceiver(CapturedResultReceiver):
    def __init__(self, result_queue):
        super().__init__()
        self.result_queue = result_queue

    def on_captured_result_received(self, captured_result):
        self.result_queue.put(captured_result)


if __name__ == '__main__':
    errorCode, errorMsg = LicenseManager.init_license(
        "LICENSE-KEY")
    if errorCode != EnumErrorCode.EC_OK and errorCode != EnumErrorCode.EC_LICENSE_CACHE_USED:
        print("License initialization failed: ErrorCode:",
              errorCode, ", ErrorString:", errorMsg)
    else:
        vc = cv2.VideoCapture(0)
        if not vc.isOpened():
            print("Error: Camera is not opened!")
            exit(1)

        cvr = CaptureVisionRouter()
        fetcher = FrameFetcher()
        cvr.set_input(fetcher)

        # Create a thread-safe queue to store captured items
        result_queue = queue.Queue()

        receiver = MyCapturedResultReceiver(result_queue)
        cvr.add_result_receiver(receiver)

        errorCode, errorMsg = cvr.start_capturing(
            EnumPresetTemplate.PT_READ_BARCODES.value)

        if errorCode != EnumErrorCode.EC_OK:
            print("error:", errorMsg)

        while True:
            ret, frame = vc.read()
            if not ret:
                print("Error: Cannot read frame!")
                break

            fetcher.add_frame(convertMat2ImageData(frame))

            if not result_queue.empty():
                captured_result = result_queue.get_nowait()

                items = captured_result.get_items()
                for item in items:

                    if item.get_type() == EnumCapturedResultItemType.CRIT_BARCODE:
                        text = item.get_text()
                        location = item.get_location()
                        x1 = location.points[0].x
                        y1 = location.points[0].y
                        x2 = location.points[1].x
                        y2 = location.points[1].y
                        x3 = location.points[2].x
                        y3 = location.points[2].y
                        x4 = location.points[3].x
                        y4 = location.points[3].y
                        cv2.drawContours(
                            frame, [np.intp([(x1, y1), (x2, y2), (x3, y3), (x4, y4)])], 0, (0, 255, 0), 2)

                        cv2.putText(frame, text, (x1, y1),
                                    cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

                        del location

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            cv2.imshow('frame', frame)

        cvr.stop_capturing()
        vc.release()
        cv2.destroyAllWindows()

Explicação

  • A classe FrameFetcher implementa a interface ImageSourceAdapter para alimentar dados do quadro no buffer integrado.
  • A classe MyCapturedResultReceiver implementa a interface CapturedResultReceiver. O método on_captured_result_received é executado em um thread de trabalho C nativo e envia objetos CapturedResult para o thread principal, onde eles são armazenados em uma fila thread-safe para uso posterior.
  • Um CapturedResult contém vários objetos CapturedResultItem. O tipo CRIT_BARCODE representa dados de código de barras reconhecidos.

Testando o Python Barcode Scanner no macOS

How to Build a Python Barcode Scanner for Windows, Linux, and macOS

Código Fonte

https://github.com/yushulx/python-barcode-qrcode-sdk/tree/main/examples/official/10.x

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/yushulx/how-to-build-a-python-barcode-scanner-for-windows-linux-and-macos-15d?1 Se houver alguma violação, por favor entre em contato com study_golang@163 .comdelete
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3