Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hackassin
GitHub Repository: hackassin/learnopencv
Path: blob/master/WeChat-QRCode-Scanner-OpenCV/Python/WeChat-qrcode-scanner.ipynb
3162 views
Kernel: Python 3

WeChat QR Code Scanner

WeChat QR code scanner is a CNN-based high-performance and lightweight QR code detect and decode library. Contributed by the 3rd-party WeChat CV Team. It was released with OpenCV 4.5.2. It has been widely used in various Tencent applications, including WeChat, WeCom, QQ, QQ Browser, and so on. Checkout this link for more information.
In this notebook, you are going to learn implementation of WeChat QR Code scanner. We will also compare the default OpenCV QR code scanner with it.

WeChat QR Code Scanner in OpenCV

Function Syntax

  1. Instantiating detector object.

detector = cv2.wechat_qrcode_WeChatQRCode("PATH_TO_DETECTOR_PROTOTXT", "PATH_TO_DETECTOR_CAFFE_MODEL", "PATH_TO_SUPER_RESOLUTION_PROTOTXT", "PATH_TO_SUPER_RESOLUTION_CAFFE_MODEL")
  1. Detect and decode.

ret, points = detctor.detectAndDecode(src)

PARAMETERS

  • ret : returns list of decoded string.

  • points : optional output array of vertices of the found QR code quadrangle. Will be empty if not found.

  • src : gray scale or color image.

The model files can be downloaded from this link.

OpenCV Documentation

WeChatQRCode

Import Libraries

import cv2 import time import numpy as np import matplotlib.pyplot as plt %matplotlib inline

Define utility function to draw bounding box

def displayBbox(im, bbox): if bbox is not None: bbox = [bbox[0].astype(int)] n = len(bbox[0]) for i in range(n): cv2.line(im, tuple(bbox[0][i]), tuple(bbox[0][(i+1) % n]), (0,255,0), 3)

Instantiate QR Code detector object

detector = cv2.wechat_qrcode_WeChatQRCode("../model/detect.prototxt", "../model/detect.caffemodel", "../model/sr.prototxt", "../model/sr.caffemodel")

Load image

img = cv2.imread('sample-qrcode.jpg')

Decode and display results

Upon execution, we get the decoded data, the bounding box and the time taken in milliseconds to process the image.

# Start time. t1 = time.time() # Detect and decode. res, points = detector.detectAndDecode(img) # End time. t2 = time.time() # Detected outputs. if len(res) > 0: print('Time Taken : ', round(1000*(t2 - t1),1), ' ms') print(' ') print('Output : ', res[0]) print(' ') print('Bounding Box : ', points) displayBbox(img, points) else: print('QRCode not detected')
# Display. plt.figure(figsize = (12,10)) plt.imshow(img[...,::-1], cmap = 'gray'); plt.title('Output');

OpenCV vs WeChat Comparison

Let us perform test on a QR code video and compare on the basis of following.

  • Zoomed out (near / far)

  • Blurred.

  • Occluded.

  • Darkened.

  • Rotated.

Function to display bounding box detected by OpenCV

def displayBboxOpenCV(im, bbox): if bbox is not None: bbox = bbox.astype(int) n = len(bbox[0]) for i in range(n): cv2.line(im, tuple(bbox[0][i]), tuple(bbox[0][(i+1) % n]), yellow, 3)

Function to display bounding box detected by WeChat

def displayBboxWeChat(im, bbox): if bbox is not None: bbox = [bbox[0].astype(int)] n = len(bbox[0]) for i in range(n): cv2.line(im, tuple(bbox[0][i]), tuple(bbox[0][(i+1) % n]), green, 3)

Function to process QR code OpenCV

def opencvQR(im, qrDecoder): # Detect and decode. data, bbox, rectifiedImg = qrDecoder.detectAndDecode(im) if len(data) > 0: cv2.putText(im, 'OpenCV Output: {}'.format(data), (20, im.shape[0] - 25), font, fontScale, yellow, 2) displayBboxOpenCV(im, bbox) # print('QR Data [ OpenCV ]: ', data, bbox) else: # print('QR Code not detected by OpenCV') cv2.putText(im, 'OpenCV Output: Not Detected', (20, im.shape[0] - 25), font, fontScale, red, 2) return im

Function to process QR code WeChat

def wechatQR(im, detector): # Detect and decode. res, points = detector.detectAndDecode(im) if len(res) > 0: # print('QR Data [ Wechat ]: ', res, points) cv2.putText(im, 'WeChat Output: {}'.format(res[0]), (20, im.shape[0] - 25), font, fontScale, green, 2) displayBboxWeChat(im, points) else: # print('QRCode not detected by WeChat') cv2.putText(im, 'WeChat Output: Not Detected', (20, im.shape[0] - 25), font, fontScale, red, 2) return im

Constants and initializations.

# Color. red = (0,0,255) green = (0,255,0) blue = (255,0,0) yellow = (0,255,255) # Font. font = cv2.FONT_HERSHEY_SIMPLEX fontScale = 0.8 # Instantiate OpenCV QR Code detector. qrDecoder = cv2.QRCodeDetector() # Instantiate video capture object. vidCapture = cv2.VideoCapture('qRcode-sample.mp4') # Get metadata. frameWidth = int(vidCapture.get(cv2.CAP_PROP_FRAME_WIDTH)) frameHeight = int(vidCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)) #Instantiate video writer object. output = cv2.VideoWriter('comparison-video.mp4', cv2.VideoWriter_fourcc(*'XVID'), 30, (2*frameWidth, frameHeight))

Main loop

print('Please wait ...') while (vidCapture.isOpened()): ret, frame = vidCapture.read() if not ret: print('Error reading frames.') break img = frame.copy() # Call OpenCV QR Code scanner. outOpenCV = opencvQR(img.copy(), qrDecoder) # Call WeChat QR Code scanner. outWeChat = wechatQR(img.copy(), detector) # Concatenate outputs. result = cv2.hconcat([outOpenCV, outWeChat]) output.write(result) print('Processing finished.') output.release() vidCapture.release()

Display output

# Install moviepy from your terminal or powershell. # pip install moviepy from moviepy.editor import * output_file = './comparison-video.mp4' # loading output video. clip = VideoFileClip(output_file) clip.ipython_display(width = 800)