Como decodificar uma imagem de código QR em Python (de preferência puro)?

86

TL; DR : Eu preciso decodificar um código QR de um arquivo de imagem usando Python (de preferência puro).

Eu tenho um arquivo jpg com um código QR que desejo decodificar usando Python. Encontrei algumas bibliotecas que afirmam fazer isso:

PyQRCode ( website aqui ) que supostamente pode decodificar códigos qr de imagens simplesmente fornecendo um caminho como este:

import sys, qrcode
d = qrcode.Decoder()
if d.decode('out.png'):
    print 'result: ' + d.result
else:
    print 'error: ' + d.error

Então, simplesmente instalei usando sudo pip install pyqrcode. O que eu acho estranho sobre o código de exemplo acima, no entanto, é que ele apenas importa qrcode(e não pyqrcodeembora). Como eu acho que qrcodese refere a esta biblioteca que só pode gerar imagens de código QR, meio que me confundiu. Tentei o código acima com ambos pyqrcodee qrcode, mas ambos falham na segunda linha dizendo AttributeError: 'module' object has no attribute 'Decoder'. Além disso, o site se refere ao Ubuntu 8.10 (que saiu há mais de 6 anos) e não consigo encontrar um repositório público (git ou outro) dele para verificar o commit mais recente. Então, mudei para a próxima biblioteca:

ZBar ( site aqui ) afirma ser "an open source software suite for reading bar codes from various sources, such as image files."Então eu tentei instalá-lo no Mac OSX rodando sudo pip install zbar. Isso falha com error: command 'cc' failed with exit status 1. Tentei sugestões nas respostas a esta pergunta SO , mas não consigo resolver. Então, decidi seguir em frente:

QRTools , que de acordo com esta postagem do blog pode decodificar imagens facilmente usando o seguinte código:

from qrtools import QR
myCode = QR(filename=u"/home/psutton/Documents/Python/qrcodes/qrcode.png")
if myCode.decode():
  print myCode.data
  print myCode.data_type
  print myCode.data_to_string()

Então tentei instalar usando sudo pip install qrtools, que não consigo encontrar nada. Eu também tentei com python-qrtools, qr-tools, python-qrtoolse mais um par de combinações, mas, infelizmente sem sucesso. Suponho que se refira a este repo que diz que é baseado no ZBar (veja acima). Embora eu queira executar meu código no Heroku (e, portanto, prefira uma solução Python pura), instalei-o com sucesso em uma caixa Linux (com sudo apt-get install python-qrtools) e tentei executá-lo:

from qrtools import QR
c = QR(filename='/home/kramer65/qrcode.jpg')
c.data  # prints u'NULL'
c.data_type  # prints u'text'
c.data_to_string()  # prints '\xef\xbb\xbfNULL' where I expect an int (being `1234567890`)

Embora isso pareça decodificá-lo, não parece fazê-lo corretamente. Além disso, ele precisa do ZBar e, portanto, não é puro Python. Decidi então encontrar outra biblioteca.

PyXing ( website aqui ) é supostamente uma porta Python da popular biblioteca Java ZXing , mas o commit inicial e único tem 6 anos e o projeto não tem leia-me ou documentação de qualquer tipo.

Para o resto eu achei um par qr- en codificadores (não de codificadores) e alguns terminais de API que pode decodificar para você. Já que não gosto que este serviço dependa de outros endpoints da API, gostaria de manter a decodificação local.

Então, para concluir; Alguém saberia como posso decodificar códigos QR de imagens em Python (de preferência puro)? Todas as dicas são bem vindas!

Kramer65
fonte
Deve ser: 'if myCode.decode ("/ home / kramer65 / qrcode.jpg")' e não 'QR (filename =' / home / kramer65 / qrcode.jpg ')'
Dmitry Chichkov
Acho que vale a pena mencionar uma pergunta de acompanhamento feita por @ kramer65 sobre a instalação zbarcom pip: stackoverflow.com/questions/27406641/…
Ian

Respostas:

108

Você pode tentar as seguintes etapas e códigos usando qrtools:

  • Crie um qrcodearquivo, se ainda não existir

    • Eu usei pyqrcodepara fazer isso, que pode ser instalado usandopip install pyqrcode
    • E então use o código:

      >>> import pyqrcode
      >>> qr = pyqrcode.create("HORN O.K. PLEASE.")
      >>> qr.png("horn.png", scale=6)
      
  • Decodifique um qrcodearquivo existente usandoqrtools

    • Instale qrtoolsusandosudo apt-get install python-qrtools
    • Agora use o seguinte código no prompt do Python

      >>> import qrtools
      >>> qr = qrtools.QR()
      >>> qr.decode("horn.png")
      >>> print qr.data
      u'HORN O.K. PLEASE.'
      

Aqui está o código completo em uma única execução:

In [2]: import pyqrcode
In [3]: qr = pyqrcode.create("HORN O.K. PLEASE.")
In [4]: qr.png("horn.png", scale=6)
In [5]: import qrtools
In [6]: qr = qrtools.QR()
In [7]: qr.decode("horn.png")
Out[7]: True
In [8]: print qr.data
HORN O.K. PLEASE.

Ressalvas

  • Pode ser necessário instalar PyPNGusando pip install pypngpara usarpyqrcode
  • Caso você tenha PILinstalado, você pode obter IOError: decoder zip not available. Nesse caso, tente desinstalar e reinstalarPIL usando:

    pip uninstall PIL
    pip install PIL
    
  • Se isso não funcionar, tente usar Pillowvez

    pip uninstall PIL
    pip install pillow
    
mu 無
fonte
1
Oi mu 無, obrigado pela sua resposta. Embora o qrtools requeira zbar e, portanto, não seja Python puro, ele realmente funciona agora. O principal problema agora é que preciso instalar a ligação zbar python no heroku, sobre a qual fiz uma pergunta aqui: stackoverflow.com/questions/27406641/… . Vou aceitar sua resposta, mas agradeceria muito se você também desse uma olhada na minha outra pergunta para que eu possa resolver rodando qrtools no heroku. Obrigado um milhão!
Kramer65
3
Isso não funciona, dá Exceção: tostring () foi removido.
Bhishan Poudel
2
@BhishanPoudel também encontrei isso. Parece que o bug foi corrigido e deve aparecer na próxima versão. Para qualquer um que encontrar isso, você pode editar a linha 181 de /usr/lib/python2.7/dist-packages/qrtools.py (a localização pode variar) e substituir "tostring" por "tobytes". Está funcionando bem para mim agora.
jonthalpy
5
não funciona. AttributeError: módulo 'qrtools' não tem atributo 'QR'
Saeed Mohtasham
1
@SaeedMohtasham tryfrom qrtools import qrtools
Krenair
9

O código a seguir funciona bem comigo:

brew install zbar
pip install pyqrcode
pip install pyzbar

Para criação de imagem de código QR:

import pyqrcode
qr = pyqrcode.create("test1")
qr.png("test1.png", scale=6)

Para decodificação de código QR:

from PIL import Image
from pyzbar.pyzbar import decode
data = decode(Image.open('test1.png'))
print(data)

que imprime o resultado:

[Decoded(data=b'test1', type='QRCODE', rect=Rect(left=24, top=24, width=126, height=126), polygon=[Point(x=24, y=24), Point(x=24, y=150), Point(x=150, y=150), Point(x=150, y=24)])]
Yuiq
fonte
para que a solução acima funcione, você também precisa executar pip install pypng && pip install image
asad_hussain
6

Estou respondendo apenas a parte da pergunta sobre zbarinstalação.

Gastei quase meia hora e algumas horas para fazê-lo funcionar no Windows + Python 2.7 de 64 bits, então aqui estão as notas adicionais para a resposta aceita:

PS: Fazendo com que funcione com Python 3.x é ainda mais difícil: Compilar zbar para Python 3.x .

PS2: Acabei de testar o pyzbar com pip install pyzbare é MUITO mais fácil, funciona imediatamente (a única coisa é que você precisa ter os arquivos VC Redist 2013 instalados). Também é recomendável usar esta biblioteca neste artigo pyimagesearch.com .

Basj
fonte
0

Existe uma biblioteca chamada BoofCV que alega ser melhor do que ZBar e outras bibliotecas .
Aqui estão as etapas para usar isso (qualquer sistema operacional).

Pré-requisitos:

  • Certifique-se de que o JDK 14+ esteja instalado e configurado em $ PATH
  • pip install pyboof

Classe para decodificar:

import os
import numpy as np
import pyboof as pb

pb.init_memmap() #Optional

class QR_Extractor:
    # Src: github.com/lessthanoptimal/PyBoof/blob/master/examples/qrcode_detect.py
    def __init__(self):
        self.detector = pb.FactoryFiducial(np.uint8).qrcode()
    
    def extract(self, img_path):
        if not os.path.isfile(img_path):
            print('File not found:', img_path)
            return None
        image = pb.load_single_band(img_path, np.uint8)
        self.detector.detect(image)
        qr_codes = []
        for qr in self.detector.detections:
            qr_codes.append({
                'text': qr.message,
                'points': qr.bounds.convert_tuple()
            })
        return qr_codes

Uso:

qr_scanner = QR_Extractor()
output = qr_scanner.extract('Your-Image.jpg')
print(output)

Testado e funciona em Python 3.8 (Windows e Ubuntu)

Gokul NC
fonte
0

Para Windows usando ZBar

Pré-requisitos:

Para decodificar:

from PIL import Image
from pyzbar import pyzbar

img = Image.open('My-Image.jpg')
output = pyzbar.decode(img)
print(output)

Como alternativa, você também pode tentar usar ZBarLightconfigurando-o conforme mencionado aqui:
https://pypi.org/project/zbarlight/

Gokul NC
fonte