Jan-21-2021, 07:11 AM
I put a QR code on a page (actually top right corner, but with say about 1cm from the edges of the page)
This code (found on stackoverflow) successfully finds that QR code, but I have no idea how it works.
Could anyone explain it a bit? If you know an improvement, that would be great too.
This code (found on stackoverflow) successfully finds that QR code, but I have no idea how it works.
Could anyone explain it a bit? If you know an improvement, that would be great too.
import cv2 import numpy as np # cv2.imread() can't handle .pdf files, I first convert to .jpg # jpgfiles[0] = '/home/pedro/winter2020/20BE/pdf2jpg/1825010141_QR1.jpg' # image = cv2.imread(jpgfiles[0]) # Load image, grayscale, Gaussian blur, Otsu's threshold image = cv2.imread(jpgfiles[0]) original = image.copy() gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (9,9), 0) thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] # Morph close kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2) # Find contours and filter for QR code cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] for c in cnts: peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.04 * peri, True) x,y,w,h = cv2.boundingRect(approx) area = cv2.contourArea(c) ar = w / float(h) if len(approx) == 4 and area > 1000 and (ar > .85 and ar < 1.3): cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3) ROI = original[y:y+h, x:x+w] cv2.imwrite('ROI.png', ROI) cv2.imshow('thresh', thresh) cv2.imshow('close', close) cv2.imshow('image', image) cv2.imshow('ROI', ROI) cv2.waitKey(2000) cv2.cv2.destroyAllWindows()I can read my test QR code with:
img = '/home/pedro/ROI.png' image = cv2.imread(img) decodedObjects = pyzbar.decode(image) # I found cv2.detectAndDecode(image) unreliable (about 15% error, no data) for obj in decodedObjects: print("Type:", obj.type) print("Data: ", obj.data, "\n") # data looks a bit funny because it contains a Chinese name # output # Type: QRCODE # Data: b'1825010141:\xe9\x99\x86\xe9\x81\xa5' # this particular Chinese name decodes correctly, but some do not decode well # I tried it on 162 students