How to Detect and Decode QR Code with YOLO, OpenCV, and Dynamsoft Barcode Reader
By: Xiao Ling
Tags: Opencv, Yolov3, Qr Code

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.6 maxWidth = 1280; maxHeight = 720 imgHeight, imgWidth = frame.shape[:2] hScale = 1; wScale = 1 thickness = 1 if imgHeight > maxHeight: hScale = imgHeight / maxHeight thickness = 6 if 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('

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

Determine the output layer, and then input the blob object to the network and perform a forward pass:

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

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 region parameters. 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.

References

Source Code

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