Jak zdekodować obraz kodu QR w (najlepiej czystym) Pythonie?


86

TL; DR : Potrzebuję sposobu na zdekodowanie kodu QR z pliku obrazu przy użyciu (najlepiej czystego) Pythona.

Mam plik jpg z kodem QR, który chcę zdekodować za pomocą Pythona. Znalazłem kilka bibliotek, które twierdzą, że robią to:

PyQRCode ( strona tutaj ), który rzekomo może dekodować kody qr z obrazów, po prostu podając ścieżkę taką jak ta:

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

Więc po prostu zainstalowałem go za pomocą sudo pip install pyqrcode. To, co uważam za dziwne w powyższym kodzie przykładowym, polega na tym, że tylko importuje qrcode(i pyqrcodejednak nie ) Ponieważ myślę, że qrcodeodnosi się do tej biblioteki, która może generować tylko obrazy kodu QR, trochę mnie to zdezorientowało. Więc wypróbowałem powyższy kod z obydwoma pyqrcodei qrcode, ale oba zawodzą w drugim wierszu mówiąc AttributeError: 'module' object has no attribute 'Decoder'. Ponadto strona odnosi się do Ubuntu 8.10 (który pojawił się ponad 6 lat temu) i nie mogę znaleźć jego publicznego (git lub innego) repozytorium, aby sprawdzić najnowsze zatwierdzenie. Więc przeszedłem do następnej biblioteki:

ZBar ( strona tutaj ) twierdzi, że jest, "an open source software suite for reading bar codes from various sources, such as image files."więc próbowałem zainstalować go na Mac OSX sudo pip install zbar. To się nie powiedzie z error: command 'cc' failed with exit status 1. Próbowałem sugestii w odpowiedziach na to pytanie SO , ale nie mogę go rozwiązać. Postanowiłem więc przejść dalej:

QRTools , które według tego wpisu na blogu mogą łatwo dekodować obrazy za pomocą następującego kodu:

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

Więc próbowałem go zainstalować za pomocą sudo pip install qrtools, który nie może nic znaleźć. Próbowałem też to python-qrtools, qr-tools, python-qrtoolsi jeszcze kilka kombinacji, ale niestety bezskutecznie. Przypuszczam, że odnosi się do tego repozytorium, które mówi, że jest oparte na ZBar (patrz wyżej). Chociaż chcę uruchomić swój kod na Heroku (i dlatego wolę czyste rozwiązanie Pythona), pomyślnie zainstalowałem go na Linuksie (z sudo apt-get install python-qrtools) i próbowałem go uruchomić:

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

Chociaż wydaje się, że to dekoduje, nie wydaje się, aby robił to poprawnie. Ponadto potrzebuje ZBar i dlatego nie jest czystym Pythonem. Postanowiłem więc znaleźć kolejną bibliotekę.

PyXing ( strona tutaj ) jest podobno portem Pythona popularnej biblioteki Java ZXing , ale początkowe i jedyne zatwierdzenie ma 6 lat, a projekt nie ma żadnego pliku readme ani dokumentacji.

Co do reszty, znalazłem kilka koderów qr- en (nie de- koderów) i kilka punktów końcowych API, które mogą dla ciebie dekodować. Ponieważ nie podoba mi się, że ta usługa jest zależna od innych punktów końcowych API, chciałbym jednak zachować lokalne dekodowanie.

Podsumowując; czy ktoś wie, jak mogę dekodować kody QR z obrazów w (najlepiej czystym) Pythonie? Wszystkie wskazówki są mile widziane!


Powinien to być: „if myCode.decode („ / home / kramer65 / qrcode.jpg ”)”, a nie „QR (filename = '/ home / kramer65 / qrcode.jpg') '
Dmitry Chichkov

Uważam, że warto wspomnieć o kolejnym pytaniu zadanym przez @ kramer65 na temat instalacji za zbarpomocą pip: stackoverflow.com/questions/27406641/…
Ian

Odpowiedzi:


108

Możesz wypróbować następujące kroki i kod przy użyciu qrtools:

  • Utwórz qrcodeplik, jeśli jeszcze nie istnieje

    • Użyłem pyqrcodedo tego, co można zainstalować za pomocąpip install pyqrcode
    • A następnie użyj kodu:

      >>> import pyqrcode
      >>> qr = pyqrcode.create("HORN O.K. PLEASE.")
      >>> qr.png("horn.png", scale=6)
      
  • Zdekoduj istniejący qrcodeplik za pomocąqrtools

    • Zainstaluj qrtoolsza pomocąsudo apt-get install python-qrtools
    • Teraz użyj następującego kodu w zachęcie Pythona

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

Oto pełny kod w jednym uruchomieniu:

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.

Ostrzeżenia

  • Być może trzeba zainstalować PyPNGużywając pip install pypngza korzystaniepyqrcode
  • Jeśli PILzainstalowałeś, możesz dostać IOError: decoder zip not available. W takim przypadku spróbuj odinstalować i ponownie zainstalowaćPIL za pomocą:

    pip uninstall PIL
    pip install PIL
    
  • Jeśli to nie zadziała, spróbuj użyć Pillowzamiast tego

    pip uninstall PIL
    pip install pillow
    

1
Cześć mu 無, dziękuję za odpowiedź. Chociaż qrtools wymaga zbar i dlatego nie jest czystym Pythonem, teraz rzeczywiście działa. Główny problem polega na tym, że muszę teraz zainstalować wiązanie Pythona zbar na heroku, o które tutaj zadałem pytanie: stackoverflow.com/questions/27406641/… . Przyjmę twoją odpowiedź, ale byłbym bardzo wdzięczny, gdybyś spojrzał również na moje drugie pytanie, abym mógł rozwiązać uruchamianie qrtools na heroku. Stukrotne dzięki!
kramer65

3
To nie działa, daje wyjątek: tostring () został usunięty.
Bhishan Poudel

2
@BhishanPoudel Spotkałem to również. Wygląda na to, że błąd został naprawiony i powinien pojawić się w następnej wersji. Każdy, kto to napotka, może edytować wiersz 181 pliku /usr/lib/python2.7/dist-packages/qrtools.py (lokalizacja może się różnić) i zamienić „tostring” na „tobytes”. Teraz dla mnie działa dobrze.
jonthalpy

5
nie działa. AttributeError: moduł „qrtools” nie ma atrybutu „QR”
Saeed Mohtasham

1
@SaeedMohtasham spróbujfrom qrtools import qrtools
Krenair

9

Poniższy kod działa dobrze ze mną:

brew install zbar
pip install pyqrcode
pip install pyzbar

Do tworzenia obrazu z kodem QR:

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

Do dekodowania kodu QR:

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

który wypisuje wynik:

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

aby powyższe rozwiązanie działało, musisz również uruchomić pip install pypng && pip install image
asad_hussain

6

Odpowiadam tylko na część pytania o zbarinstalację.

Spędziłem prawie pół godziny kilka godzin, aby to działało na Windows + Python 2.7 64-bit, więc oto dodatkowe uwagi do zaakceptowanej odpowiedzi:

PS: Making pracować z Pythona 3.x jest jeszcze trudniejsze: Compile zbar dla Pythona 3.x .

PS2: Właśnie przetestowałem pyzbar z pip install pyzbari jest ZNACZNIE łatwiejszy, działa po wyjęciu z pudełka (jedyną rzeczą jest to, że musisz mieć zainstalowane pliki VC Redist 2013). Zaleca się również korzystanie z tej biblioteki w tym artykule na pyimagesearch.com .


0

Istnieje biblioteka o nazwie BoofCV, która twierdzi, że jest lepsza niż ZBar i inne biblioteki .
Oto kroki, aby z tego skorzystać (dowolny system operacyjny).

Wymagania wstępne:

  • Upewnij się, że JDK 14+ jest zainstalowany i ustawiony w $ PATH
  • pip install pyboof

Klasa do zdekodowania:

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

Stosowanie:

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

Przetestowany i działa na Pythonie 3.8 (Windows i Ubuntu)


0

W przypadku systemu Windows używającego ZBar

Wymagania wstępne:

Aby zdekodować:

from PIL import Image
from pyzbar import pyzbar

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

Alternatywnie możesz również spróbować użyć ZBarLight, konfigurując go, jak wspomniano tutaj:
https://pypi.org/project/zbarlight/

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.