Come decodificare un'immagine del codice QR in Python (preferibilmente puro)?


88

TL; DR : Ho bisogno di un modo per decodificare un codice QR da un file immagine usando Python (preferibilmente puro).

Ho un file jpg con un codice QR che voglio decodificare usando Python. Ho trovato un paio di librerie che affermano di farlo:

PyQRCode ( sito web qui ) che presumibilmente può decodificare i codici qr dalle immagini semplicemente fornendo un percorso come questo:

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

Quindi l'ho semplicemente installato usando sudo pip install pyqrcode. La cosa che trovo strano del codice di esempio sopra, tuttavia, è che importa solo qrcode(e non pyqrcodeperò) Dal momento che penso si qrcoderiferisca a questa libreria che può generare solo immagini di codice qr, mi ha confuso. Quindi ho provato il codice sopra con entrambi pyqrcodee qrcode, ma entrambi falliscono alla seconda riga dicendo AttributeError: 'module' object has no attribute 'Decoder'. Inoltre, il sito web fa riferimento a Ubuntu 8.10 (uscito più di 6 anni fa) e non riesco a trovare un repository pubblico (git o altro) per controllare l'ultimo commit. Quindi sono passato alla libreria successiva:

ZBar ( sito web qui ) afferma di essere "an open source software suite for reading bar codes from various sources, such as image files."Quindi ho provato a installarlo su Mac OSX in esecuzione sudo pip install zbar. Questo fallisce con error: command 'cc' failed with exit status 1. Ho provato a suggerimenti nelle risposte a questa domanda SO , ma non riesco a risolverlo. Quindi ho deciso di andare avanti di nuovo:

QRTools , che secondo questo post del blog può decodificare facilmente le immagini utilizzando il seguente codice:

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

Quindi ho provato a installarlo usando sudo pip install qrtools, che non riesce a trovare nulla. Ho anche provato con python-qrtools, qr-tools, python-qrtoolse un altro paio di combinazioni, ma purtroppo senza alcun risultato. Suppongo che si riferisca a questo repo che dice che è basato su ZBar (vedi sopra). Anche se voglio eseguire il mio codice su Heroku (e quindi preferisco una soluzione Python pura) l'ho installato con successo su una macchina Linux (con sudo apt-get install python-qrtools) e ho provato a eseguirlo:

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

Sebbene questo sembri decodificarlo, non sembra farlo correttamente. Inoltre necessita di ZBar e quindi non è puro Python. Così ho deciso di trovare un'altra libreria.

PyXing ( sito web qui ) è presumibilmente un port Python della popolare libreria Java ZXing , ma il commit iniziale e unico è di 6 anni e il progetto non ha alcun readme o documentazione di sorta.

Per il resto ho trovato un paio QR en codificatori (non de codificatori) e alcuni endpoint API in grado di decodificare per voi. Dal momento che non mi piace che questo servizio dipenda da altri endpoint API, vorrei mantenere la decodifica locale.

Quindi per concludere; qualcuno saprebbe come decodificare i codici QR da immagini in Python (preferibilmente puro)? Tutti i suggerimenti sono ben accetti!


Dovrebbe essere: "if myCode.decode (" / home / kramer65 / qrcode.jpg ")" e non "QR (filename = '/ home / kramer65 / qrcode.jpg')"
Dmitry Chichkov

Penso che valga la pena menzionare una domanda di follow-up posta da @ kramer65 sull'installazione zbarcon pip: stackoverflow.com/questions/27406641/…
Ian

Risposte:


109

Puoi provare i seguenti passaggi e codice usando qrtools:

  • Crea un qrcodefile, se non già esistente

    • Ho usato pyqrcodeper fare questo, che può essere installato usandopip install pyqrcode
    • E poi usa il codice:

      >>> import pyqrcode
      >>> qr = pyqrcode.create("HORN O.K. PLEASE.")
      >>> qr.png("horn.png", scale=6)
      
  • Decodifica un qrcodefile esistente utilizzandoqrtools

    • Installa qrtoolsusandosudo apt-get install python-qrtools
    • Ora usa il seguente codice all'interno del tuo prompt di Python

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

Ecco il codice completo in una singola esecuzione:

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.

Avvertenze

  • Potrebbe essere necessario installare PyPNGutilizzando pip install pypngper l'utilizzopyqrcode
  • Nel caso tu abbia PILinstallato, potresti ottenere IOError: decoder zip not available. In tal caso, prova a disinstallare e reinstallarePIL utilizzando:

    pip uninstall PIL
    pip install PIL
    
  • Se non funziona, prova a usare Pillowinvece

    pip uninstall PIL
    pip install pillow
    

1
Ciao mu 無, grazie per la tua risposta. Sebbene qrtools richieda zbar e quindi non sia puro Python, ora funziona davvero. Il problema principale è ora che devo installare l'associazione python zbar su heroku, su cui ho posto una domanda qui: stackoverflow.com/questions/27406641/… . Accetterò la tua risposta, ma ti sarei molto grato se dai un'occhiata anche all'altra mia domanda in modo da poter risolvere i qrtools in esecuzione su heroku. Grazie mille!
kramer65

3
Questo non funziona, dà Eccezione: tostring () è stato rimosso.
Bhishan Poudel

2
@BhishanPoudel Ho riscontrato anche questo. Sembra che il bug sia stato risolto e dovrebbe apparire nella prossima versione. Per chiunque si imbatta in questo, è possibile modificare la riga 181 di /usr/lib/python2.7/dist-packages/qrtools.py (la posizione può variare) e sostituire "tostring" con "tobytes". Adesso sta funzionando bene per me.
jonthalpy

5
non funziona. AttributeError: il modulo "qrtools" non ha attributo "QR"
Saeed Mohtasham

1
@SaeedMohtasham tryfrom qrtools import qrtools
Krenair

11

Il seguente codice funziona bene con me:

brew install zbar
pip install pyqrcode
pip install pyzbar

Per la creazione dell'immagine del codice QR:

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

Per la decodifica del codice QR:

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

che stampa il risultato:

[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)])]

affinché la soluzione di cui sopra funzioni, devi anche eseguire pip install pypng e pip install image
asad_hussain

6

Rispondo solo alla parte della domanda zbarsull'installazione.

Ho impiegato quasi mezz'ora alcune ore per farlo funzionare su Windows + Python 2.7 a 64 bit, quindi ecco alcune note aggiuntive alla risposta accettata:

PS: farlo funzionare con Python 3.x è ancora più difficile: compila zbar per Python 3.x .

PS2: Ho appena testato pyzbar con pip install pyzbared è MOLTO più semplice, funziona immediatamente (l'unica cosa è che devi avere i file VC Redist 2013 installati). Si consiglia inoltre di utilizzare questa libreria in questo articolo di pyimagesearch.com .


1

Per Windows che utilizza ZBar

Prerequisiti:

  • Installa ZBar in uno dei seguenti modi:
  • pip install pyzbar

Per decodificare:

from PIL import Image
from pyzbar import pyzbar

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

In alternativa, puoi anche provare a utilizzarlo ZBarLightconfigurandolo come indicato qui:
https://pypi.org/project/zbarlight/


0

C'è una libreria chiamata BoofCV che sostiene di essere migliore di ZBar e altre librerie .
Ecco i passaggi per utilizzarlo (qualsiasi sistema operativo).

Prerequisiti:

  • Assicurati che JDK 14+ sia installato e impostato in $ PATH
  • pip install pyboof

Classe da decodificare:

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

Utilizzo:

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

Testato e funziona su Python 3.8 (Windows e Ubuntu)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.