Skip to main content

Robust and Straight-Forward solution for reading difficult and tricky QR codes within images in Python. Supported by a YOLOv7 QR Detection model.

Project description

QReader

QReader QReader is a Robust and Straight-Forward solution for reading difficult and tricky QR codes within images in Python. Powered by a YOLOv7 model.

Behind the scenes, the library is composed by two main building blocks: A QR Detector based on a YOLOv7 model trained on a large dataset of QR codes (also offered as stand-alone), and the Pyzbar QR Decoder. On top of Pyzbar, QReader transparently applyes different image preprocessing techniques that maximize the decoding rate on difficult images.

Installation

To install QReader, simply run:

pip install qreader

If you're not using Windows, you may need to install some additional pyzbar dependencies:

On Linux:

sudo apt-get install libzbar0

On Mac OS X:

brew install zbar

NOTE: If you're running QReader in a server with very limited resources, you may want to install the CPU version of PyTorch, before installing QReader. To do so, run: pip install torch --no-cache-dir (Thanks to @cjwalther for his advice).

Usage

Open In Colab

QReader is a very simple and straight-forward library. For most use cases, you'll only need to call detect_and_decode:

from qreader import QReader
import cv2


# Create a QReader instance
qreader = QReader()

# Get the image that contains the QR code (QReader expects an uint8 numpy array)
image = cv2.cvtColor(cv2.imread("path/to/image.png"), cv2.COLOR_BGR2RGB)

# Use the detect_and_decode function to get the decoded QR data
decoded_text = qreader.detect_and_decode(image=image)

detect_and_decode will return a tuple containing the decoded string of every QR found in the image. NOTE: Some entries can be None, it will happen when a QR have been detected but couldn't be decoded.

API Reference

QReader.detect_and_decode(image, return_bboxes = False)

This method will decode the QR codes in the given image and return the decoded strings (or None, if any of them could be detected but not decoded).

  • image: np.ndarray. NumPy Array containing the image to decode. The image is expected to be in uint8 format [HxWxC], RGB.

  • return_bboxes: boolean. If True, it will also return the bboxes of each detected QR. Default: False

  • Returns: tuple[str | None] | tuple[tuple[tuple[int, int, int, int], str | None]]: A tuple with all detected QR codes decodified. If return_bboxes is False, the output will look like: ('Decoded QR 1', 'Decoded QR 2', None, 'Decoded QR 4', ...). If return_bboxes is True it will look like: (((x1_1, y1_1, x2_1, y2_1), 'Decoded QR 1'), ((x1_2, y1_2, x2_2, y2_2), 'Decoded QR 2'), ...).

QReader.detect(image)

This method detects the QR codes in the image and returns the bounding boxes surrounding them in the format (x1, y1, x2, y2).

  • image: np.ndarray. NumPy Array containing the image to decode. The image must is expected to be in uint8 format [HxWxC], RGB.

  • Returns: tuple[tuple[int, int, int, int]]. The bounding boxes of the QR code in the format ((x1_1, y1_1, x2_1, y2_1), (x1_1, y1_1, x2_1, x2_2)).

NOTE: This the only function you will need? Take a look at QRDet.

QReader.decode(image, bbox = None)

This method decodes a single QR code on the given image, if a bbox is given (recommended) it will only look within that delimited region.

Internally, this method will run the pyzbar decoder, using different image preprocessing techniques (sharpening, binarization, blurring...) every time it fails to increase the detection rate.

  • image: np.ndarray. NumPy Array containing the image to decode. The image must is expected to be in uint8 format [HxWxC], RGB.

  • bbox: tuple[int, int, int, int] | None. The bounding box of the QR code in the format (x1, y1, x2, y2) [that's the output of detect]. If None, it will look for the QR code in the whole image (not recommended). Default: None.

  • Returns: str. The decoded text of the QR code. If no QR code can be decoded, it will return None.

Usage Tests

test_on_mobile
Two sample images. At left, an image taken with a mobile phone. At right, a 64x64 QR pasted over a drawing.

The following code will try to decode these images containing QRs with QReader, pyzbar and OpenCV.

from qreader import QReader
from cv2 import QRCodeDetector, imread
from pyzbar.pyzbar import decode

# Initialize the three tested readers (QRReader, OpenCV and pyzbar)
qreader_reader, cv2_reader, pyzbar_reader = QReader(), QRCodeDetector(), decode

for img_path in ('test_mobile.jpeg', 'test_draw_64x64.jpeg'):
    # Read the image
    img = imread(img_path)

    # Try to decode the QR code with the three readers
    qreader_out = qreader_reader.detect_and_decode(image=img)
    cv2_out = cv2_reader.detectAndDecode(img=img)[0]
    pyzbar_out = pyzbar_reader(image=img)
    # Read the content of the pyzbar output (double decoding will save you from a lot of wrongly decoded characters)
    pyzbar_out = tuple(out.data.data.decode('utf-8').encode('shift-jis').decode('utf-8') for out in pyzbar_out)

    # Print the results
    print(f"Image: {img_path} -> QReader: {qreader_out}. OpenCV: {cv2_out}. pyzbar: {pyzbar_out}.")

The output of the previous code is:

Image: test_mobile.jpeg -> QReader: ('https://github.com/Eric-Canas/QReader'). OpenCV: . pyzbar: ().
Image: test_draw_64x64.jpeg -> QReader: ('https://github.com/Eric-Canas/QReader'). OpenCV: . pyzbar: ().

Note that QReader internally uses pyzbar as decoder. The improved detection-decoding rate that QReader achieves comes from the combination of different image pre-processing techniques and the YOLOv7 based QR detector that is able to detect QR codes in harder conditions than classical Computer Vision methods.

Acknowledgements

This library is based on the following projects:

  • YoloV7 model for Object Detection.
  • Pyzbar QR Decoder.
  • OpenCV methods for image filtering.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qreader-2.8.tar.gz (6.8 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page