How to Detect and Decode QR Code with YOLO, OpenCV, and Dynamsoft Barcode Reader
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
- https://opencv-tutorial.readthedocs.io/en/latest/yolo/yolo.html
- https://docs.opencv.org/master/d6/d0f/group__dnn.html
- https://docs.opencv.org/3.4/db/d30/classcv_1_1dnn_1_1Net.html
Source Code
Originally published at https://www.dynamsoft.com on November 20, 2020.