Detecting and Decoding QR Codes in Python with YOLO and Dynamsoft Barcode Reader
In the past two weeks, I trained a custom YOLOv3 model specifically for QR code detection and tested it using Darknet. In this article, I will demonstrate how to use OpenCV’s DNN (Deep Neural Network) module to load the YOLO model for detecting QR codes from static images and real-time camera video streams. Additionally, I will show how to use the Dynamsoft Barcode Reader to decode QR codes from the detected regions provided by YOLO.
This article is Part 1 in a 9-Part Series.
- Part 1 - Detecting and Decoding QR Codes in Python with YOLO and Dynamsoft Barcode Reader
- Part 2 - How to a GUI Barcode Reader with Qt PySide6 on Raspberry Pi
- Part 3 - Advanced GUI Python Barcode and QR Code Reader for Windows, Linux, macOS and Rasberry Pi OS
- Part 4 - Scanning QR Code from Desktop Screen with Qt and Python Barcode SDK
- Part 5 - Building an Online Barcode and QR Code Scanning App with Python Django
- Part 6 - How to Build Flet Chat App with Barcode and Gemini APIs
- Part 7 - Python Ctypes: Invoking C/C++ Shared Library and Native Threading
- Part 8 - A Guide to Running ARM32 and ARM64 Python Barcode Readers in Docker Containers
- Part 9 - Python Barcode SDK Benchmark: Comparing ZXing, ZBar, and Dynamsoft with Real-World & Stress Tests

Prerequisites
-
OpenCV 4.x
pip install opencv-python -
Dynamsoft Barcode Reader
pip install dynamsoft-capture-vision-bundle -
Obtain a Dynamsoft Barcode Reader trial license and update your code with the provided license key:
from dynamsoft_capture_vision_bundle import * errorCode, errorMsg = LicenseManager.init_license("LICENSE-KEY") if errorCode != EnumErrorCode.EC_OK and errorCode != EnumErrorCode.EC_LICENSE_CACHE_USED: print("License initialization failed: ErrorCode:", errorCode, ", ErrorString:", errorMsg) cvr_instance = CaptureVisionRouter()
QR Code Detection with YOLO and OpenCV Python
To quickly get started with OpenCV’s DNN module, you can refer to the sample script object_detection.py from the OpenCV GitHub repository. Below, we’ll build on this sample to implement QR code detection using a YOLO model.
Step-by-Step Implementation of QR Detection
-
Load the Image: Use the imread() function to load an image into a Mat object. To manage large images, define maximum width and height values:
import cv2 as cv import numpy as np 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 -
Initialize the YOLO Model: Load the YOLO configuration (
*.cfg), weights (*.weights), and class names (*.names) 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) -
Create a Blob: Convert the image into a blob object suitable for input into the network:
blob = cv.dnn.blobFromImage(frame, 1/255, (416, 416), swapRB=True, crop=False) -
Perform Inference: Feed the blob into the network and run forward pass to get the detections:
ln = net.getLayerNames() ln = [ln[i - 1] for i in net.getUnconnectedOutLayers().flatten()] net.setInput(blob) outs = net.forward(ln) -
Post-Processing: Extract class names, confidence scores, and bounding boxes from the network outputs, and draw them using OpenCV:
def postprocess(frame, outs): frameHeight, frameWidth = frame.shape[:2] classIds = [] confidences = [] boxes = [] for out in outs: for detection in out: scores = detection[5:] classId = np.argmax(scores) confidence = scores[classId] if confidence > threshold: x, y, width, height = detection[:4] * np.array( [frameWidth, frameHeight, frameWidth, frameHeight]) left = int(x - width / 2) top = int(y - height / 2) classIds.append(classId) confidences.append(float(confidence)) boxes.append([left, top, int(width), int(height)]) indices = cv.dnn.NMSBoxes(boxes, confidences, threshold, threshold - 0.1) if not isinstance(indices, tuple): for i in indices.flatten(): # Flatten the indices if they are in nested format box = boxes[i] left = box[0] top = box[1] width = box[2] height = box[3] # Crop the detected object from the frame cropped_image = frame[top:top + height, left:left + width] cv.imshow('cropped', cropped_image) cv.imwrite('cropped.jpg', cropped_image) # Draw bounding box around the detected object cv.rectangle(frame, (left, top), (left + width, top + height), (0, 0, 255), thickness) # Draw class name and confidence on the bounding box label = '%s:%.2f' % (classes[classIds[i]], confidences[i]) cv.putText(frame, label, (left, top), cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255)) -
Resize and Display the Image: Adjust the image size to fit your display:
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 Codes with Dynamsoft Barcode Reader
After detecting QR codes, use the bounding boxes to decode the QR content. Setting the region parameters speeds up decoding compared to scanning the full image:
from dynamsoft_capture_vision_bundle import *
errorCode, errorMsg = LicenseManager.init_license("LICENSE-KEY")
if errorCode != EnumErrorCode.EC_OK and errorCode != EnumErrorCode.EC_LICENSE_CACHE_USED:
print("License initialization failed: ErrorCode:",
errorCode, ", ErrorString:", errorMsg)
cvr_instance = CaptureVisionRouter()
def decodeframe(frame, left, top, right, bottom):
error_code, error_msg, settings = cvr_instance.get_simplified_settings(EnumPresetTemplate.PT_READ_BARCODES.value)
quad = Quadrilateral()
quad.points = [Point(left, top), Point(right, top), Point(right, bottom), Point(left, bottom)]
settings.roi = quad
settings.roi_measured_in_percentage = False
cvr_instance.update_settings(EnumPresetTemplate.PT_READ_BARCODES.value, settings)
result = cvr_instance.capture(frame, EnumPresetTemplate.PT_READ_BARCODES.value)
return result
Note: Replace
LICENSE-KEYwith your actual license key.

Source Code
https://github.com/yushulx/python-barcode-qrcode-sdk/tree/main/examples/official/yolo_qr