¿Cómo decodificar una imagen de código QR en Python (preferiblemente puro)?

86

TL; DR : Necesito una forma de decodificar un código QR de un archivo de imagen usando Python (preferiblemente puro).

Tengo un archivo jpg con un código QR que quiero decodificar usando Python. Encontré un par de bibliotecas que afirman hacer esto:

PyQRCode ( sitio web aquí ) que supuestamente puede decodificar códigos qr a partir de imágenes simplemente proporcionando una ruta como esta:

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

Así que simplemente lo instalé usando sudo pip install pyqrcode. Sin embargo, lo que encuentro extraño sobre el código de ejemplo anterior es que solo importa qrcode(y no pyqrcodeaunque). Como creo que se qrcoderefiere a esta biblioteca que solo puede generar imágenes de código qr, me confundió un poco. Así que probé el código anterior con ambos pyqrcodey qrcode, pero ambos fallaron en la segunda línea diciendo AttributeError: 'module' object has no attribute 'Decoder'. Además, el sitio web se refiere a Ubuntu 8.10 (que salió hace más de 6 años) y no puedo encontrar un repositorio público (git u otro) para verificar la última confirmación. Así que pasé a la siguiente biblioteca:

ZBar ( sitio web aquí ) afirma ser "an open source software suite for reading bar codes from various sources, such as image files."así que intenté instalarlo en Mac OSX en ejecución sudo pip install zbar. Esto falla con error: command 'cc' failed with exit status 1. Intenté sugerencias en las respuestas a esta pregunta SO , pero parece que no puedo resolverlo. Así que decidí seguir adelante de nuevo:

QRTools , que según esta publicación de blog puede decodificar imágenes fácilmente usando el siguiente 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()

Así que intenté instalarlo usando sudo pip install qrtools, que no puedo encontrar nada. También he probado con python-qrtools, qr-tools, python-qrtoolsy un par más combinaciones, pero lamentablemente sin éxito. Supongo que se refiere a este repositorio que dice que está basado en ZBar (ver arriba). Aunque quiero ejecutar mi código en Heroku (y por lo tanto prefiero una solución pura de Python), lo instalé con éxito en una caja de Linux (con sudo apt-get install python-qrtools) e intenté ejecutarlo:

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`)

Aunque esto parece decodificarlo, no parece hacerlo correctamente. Además, necesita ZBar y, por lo tanto, no es Python puro. Así que decidí buscar otra biblioteca.

PyXing ( sitio web aquí ) es supuestamente un puerto Python de la popular biblioteca Java ZXing , pero la confirmación inicial y única tiene 6 años y el proyecto no tiene ningún archivo Léame o documentación.

Para el resto He encontrado un par qr- ES codificadores (no de codificadores) y algunos puntos finales de API que puede decodificar para usted. Como no me gusta que este servicio dependa de otros puntos finales de API, me gustaría mantener la decodificación local.

Así que para concluir; ¿Alguien sabría cómo puedo decodificar códigos QR a partir de imágenes en Python (preferiblemente puro)? ¡Todos los consejos son bienvenidos!

kramer65
fuente
Debería ser: 'if myCode.decode ("/ home / kramer65 / qrcode.jpg")' y no 'QR (filename =' / home / kramer65 / qrcode.jpg ')'
Dmitry Chichkov
Creo que vale la pena mencionar una pregunta de seguimiento formulada por @ kramer65 sobre la instalación zbarcon pip: stackoverflow.com/questions/27406641/…
Ian

Respuestas:

108

Puede probar los siguientes pasos y código usando qrtools:

  • Cree un qrcodearchivo, si aún no existe

    • Solía pyqrcodehacer esto, que se puede instalar usandopip install pyqrcode
    • Y luego usa el código:

      >>> import pyqrcode
      >>> qr = pyqrcode.create("HORN O.K. PLEASE.")
      >>> qr.png("horn.png", scale=6)
      
  • Decodificar un qrcodearchivo existente usandoqrtools

    • Instalar qrtoolsusandosudo apt-get install python-qrtools
    • Ahora use el siguiente código dentro de su indicador de Python

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

Aquí está el código completo en una sola ejecución:

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.

Advertencias

  • Es posible que deba instalar PyPNGusando pip install pypngpara usarpyqrcode
  • En caso de que lo haya PILinstalado, es posible que obtenga IOError: decoder zip not available. En ese caso, intente desinstalar y reinstalarPIL usando:

    pip uninstall PIL
    pip install PIL
    
  • Si eso no funciona, intente usar en su Pillowlugar

    pip uninstall PIL
    pip install pillow
    
mu 無
fuente
1
Hola mu 無, gracias por tu respuesta. Aunque qrtools requiere zbar y, por lo tanto, no es Python puro, de hecho funciona ahora. El problema principal ahora es que necesito instalar el enlace zbar python en heroku, sobre el cual hice una pregunta aquí: stackoverflow.com/questions/27406641/… . Voy a aceptar tu respuesta, pero te agradecería mucho si también echas un vistazo a mi otra pregunta para que pueda resolver la ejecución de qrtools en heroku. ¡Un millón de gracias!
kramer65
3
Esto no funciona, da Exception: tostring () ha sido eliminado.
Bhishan Poudel
2
@BhishanPoudel También encontré esto. Parece que el error se ha corregido y debería aparecer en la próxima versión. Para cualquiera que encuentre esto, puede editar la línea 181 de /usr/lib/python2.7/dist-packages/qrtools.py (la ubicación puede variar) y reemplazar "tostring" con "tobytes". Me está funcionando bien ahora.
jonthalpy
5
no funciona. AttributeError: módulo 'qrtools' no tiene atributo 'QR'
Saeed Mohtasham
1
@SaeedMohtasham tryfrom qrtools import qrtools
Krenair
9

El siguiente código funciona bien conmigo:

brew install zbar
pip install pyqrcode
pip install pyzbar

Para la creación de imágenes de códigos QR:

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

Para decodificación de códigos QR:

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

que imprime el 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
fuente
para que la solución anterior funcione, también debe ejecutar pip install pypng && pip install image
asad_hussain
6

Respondo solo una parte de la pregunta sobre la zbarinstalación.

Pasé casi media hora unas pocas horas para que funcionara en Windows + Python 2.7 de 64 bits, por lo que aquí hay notas adicionales a la respuesta aceptada:

PD: Hacer que funcione con Python 3.x es aún más difícil: compile zbar para Python 3.x .

PS2: Acabo de probar pyzbar con pip install pyzbary es MUCHO más fácil, funciona de inmediato (lo único que necesita es tener instalados los archivos VC Redist 2013). También se recomienda utilizar esta biblioteca en este artículo de pyimagesearch.com .

Basj
fuente
0

Hay una biblioteca llamada BoofCV que dice ser mejor que ZBar y otras bibliotecas .
Estos son los pasos para usar eso (cualquier sistema operativo).

Prerrequisitos:

  • Asegúrese de que JDK 14+ esté instalado y configurado en $ PATH
  • pip install pyboof

Clase 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)

Probado y funciona en Python 3.8 (Windows y Ubuntu)

Gokul NC
fuente
0

Para Windows usando ZBar

Prerrequisitos:

Para decodificar:

from PIL import Image
from pyzbar import pyzbar

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

Alternativamente, también puede intentar usarlo ZBarLightconfigurándolo como se menciona aquí:
https://pypi.org/project/zbarlight/

Gokul NC
fuente