How to read QR codes in Python using OpenCV

Learn how to read QR codes from images in Python using the OpenCV computer vision library's QRCodeDetector class.

How to read QR codes in Python using OpenCV
Picture by Kampus, Pexels.
6 minutes to read

The QR code or Quick Response code is a two-dimensional or matrix barcode invented in the early nineties by a Japanese car manufacturer. QR codes started to become popular in warehousing, marketing, and other areas in the early 2010s and the technology to read them is now built into the cameras of pretty much every smartphone.

Most recently, you’ll probably have noticed QR codes on the fronts of lateral flow tests for Covid 19. By scanning the QR code, scientists can quickly extract the unique code number embedded in the QR code in a reliable manner and import it directly into a database or other application.

QR codes are popular because they are fast to read, have a higher storage capacity than typical UPC barcodes, and include built in error checking. In this project, I’ll show you how you can read the QR code shown on images of Covid 19 tests to extract the unique reference code for the kit issued using the OpenCV computer visualisation library.

Install the packages

First, open a Jupyter notebook and install the OpenCV computer visualisation package using !pip install opencv-python. Confusingly, although the computer visualisation package is known (and imported) using the cv2 name, the library itself is called opencv-python, not cv2.

!pip install opencv-python
Collecting opencv-python
  Downloading opencv_python-4.5.5.64-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (60.5 MB)
     |████████████████████████████████| 60.5 MB 8.7 MB/s eta 0:00:011
[?25hRequirement already satisfied: numpy>=1.14.5; python_version >= "3.7" in /conda/envs/data-science-stack-2.5.1/lib/python3.7/site-packages (from opencv-python) (1.19.4)
Installing collected packages: opencv-python
Successfully installed opencv-python-4.5.5.64

Load the packages

Next, import the packages required. Technically, we only really need cv2 to read the QR code, but we’re going to write a bit of extra code that will read an entire directory of images of Covid 19 lateral flow test images and extract their QR code values and store the data in a Pandas dataframe, so we need a few others.

import glob
import cv2
import pandas as pd
import pathlib

Open an image and read a QR code

To avoid repetition later, we’ll create a simple helper function called read_qr_code() to read the value embedded in the QR code that may (or may not) be present on each image. We’ll pass the filename to the function holding the path to the file, then we’ll use the cv2.imread() function to read the image.

We’ll then instantiate the cv2.QRCodeDetector() class and use the detectAndDecode() function to extract the data from the QR code, if one can be read. The detectAndDecode() function actually returns several values, but we only want the text stored in the QR code, so we’re only returning the value part. If we don’t find a code, we’ll return nothing.

def read_qr_code(filename):
    """Read an image and read the QR code.
    
    Args:
        filename (string): Path to file
    
    Returns:
        qr (string): Value from QR code
    """
    
    try:
        img = cv2.imread(filename)
        detect = cv2.QRCodeDetector()
        value, points, straight_qrcode = detect.detectAndDecode(img)
        return value
    except:
        return

To test the function we’ll load up an image of a lateral flow test result showing a QR code by passing the file path to the read_qr_code() function we just created, then we’ll print out the value. This successfully extracts the correct digits from the QR code image.

value = read_qr_code('data/00003090-PHOTO-2022-03-19-08-31-34.jpg')
value
'LXQ12345774'

Read a directory of images and extract the QR code values

If you’ve got hundreds or thousands of images, you can scale up this approach to scan an entire directory and extract the QR code values and store the data. To do this we’ll first create a Pandas dataframe called df that has two columns - filename and qr, then we’ll load all the .jpg files from the /data directory and store the list in files.

Then we can use a for loop to loop over files and run the read_qr_code() function on each file, storing the filename and QR code value back to our dataframe. In just a few minutes, OpenCV can open, read, and detect the QR codes in thousands of images and store the outputs for you.

df = pd.DataFrame(columns=['filename', 'qr'])
files = glob.glob('data/*.jpg')

for file in files:

    qr = read_qr_code(file)
    row = {'filename': file, 'qr': qr}
    
    df = df.append(row, ignore_index=True)

df.head()
filename qr
0 data/00003090-PHOTO-2022-03-19-08-31-34.jpg LXQ12345774

Matt Clarke, Monday, March 21, 2022

Matt Clarke Matt is an Ecommerce and Marketing Director who uses data science to help in his work. Matt has a Master's degree in Internet Retailing (plus two other Master's degrees in different fields) and specialises in the technical side of ecommerce and marketing.