How to Detect and Decode QR Code with YOLO, OpenCV, and Dynamsoft Barcode Reader

Xiao Ling
3 min readNov 20, 2020

In the past two weeks, I trained a custom YOLOv3 model for QR code detection and tested it with Darknet. In this article, I will use OpenCV’s DNN (Deep Neural Network) module to load the YOLO model for making detection from static images and real-time camera video stream. Besides, I will use Dynamsoft Barcode Reader to decode QR codes from the regions detected by YOLO.

YOLO QR Code Detection with OpenCV Python

Install OpenCV ( CPU only) via pip:

pip install opencv-python

You can get qrcode.names, qrcode-yolov3-tiny.cfg and qrcode-yolov3-tiny.weights files from the package YOLOv3-tiny-QR.

To quickly get familiar with the OpenCV DNN APIs, we can refer to object_detection.py, which is a sample included in the OpenCV GitHub repository.

Now, let’s implement the QR detection code logic step by step.

First, we need to read an image to a Mat object using the imread() function. In case the image size is too large to display, I defined the maximum width and height values:

frame = cv.imread("416x416.jpg")threshold = 0.6maxWidth = 1280; maxHeight = 720imgHeight, imgWidth = frame.shape[:2]hScale = 1; wScale = 1thickness = 1if imgHeight > maxHeight:    hScale = imgHeight / maxHeight    thickness = 6if imgWidth > maxWidth:    wScale = imgWidth / maxWidth    thickness = 6

The next step is to initialize the network by loading the *.names, *.cfg and *.weights files:

classes = open('qrcode.names').read().strip().split('\n')net = cv.dnn.readNetFromDarknet('qrcode-yolov3-tiny.cfg', 'qrcode-yolov3-tiny.weights')net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)

The network requires a blob object as the input, therefore we can convert the Mat object to a blob object as follows:

blob = cv.dnn.blobFromImage(frame, 1/255, (416, 416), swapRB=True, crop=False)

Afterwards, we input the blob object to the network to do inference:

ln = net.getLayerNames()ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]net.setInput(blob)outs = net.forward(ln)

As we get the network outputs, we can extract class names, confidence scores, and bounding boxes. In the meantime, we can draw them with OpenCV APIs:

Finally, we could adjust the image size to display appropriately on screen:

if hScale > wScale:    frame = cv.resize(frame, (int(imgWidth / hScale), maxHeight))elif hScale < wScale:    frame = cv.resize(frame, (maxWidth, int(imgHeight / wScale)))cv.imshow('QR Detection', frame)cv.waitKey()

Decoding QR Code with Dynamsoft Barcode Reader

Once the QR code detection is done, we can get the corresponding bounding boxes, with which we are able to take a further step to decode the QR code.

Install Dynamsoft Barcode Reader:

pip install dbr

According to the coordinates of bounding boxes, we can decode the QR code by setting the region parameters. The region decoding is much faster than the full image decoding:

On my screenshot, you can see the decoding result is obfuscated because I didn’t use a valid license key. If you want to experience the full functionalities of Dynamsoft Barcode Reader, you’d better apply for a free trial license to activate the Python barcode SDK.

References

Source Code

https://github.com/yushulx/opencv-yolo-qr-detection

Originally published at https://www.dynamsoft.com on November 20, 2020.

--

--

Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover