QR Code Scanner實作

Watson Wang
6 min readJun 7, 2021

--

Photo by Thor Alvis on Unsplash

剛看到這題目時,想說應該會需要花一段時間,理解一下各種生成原理,然後圖像轉正之類的才能得到成果,但 python 果然不讓人失望,簡單幾行的使用package就結束了。

直接看code吧

from pyzbar import pyzbar
import cv2
# find the barcodes and decode each of the barcodesimage = cv2.imread('./1.jpg')
barcodes = pyzbar.decode(image)
# loop over the detected barcodes
for barcode in barcodes:
# bounding box surrounding the barcode on the image
(x, y, w, h) = barcode.rect
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
# print the barcode type and data to the terminal
print("{} barcode: {}".format(barcodeType, barcodeData))
# show the output image
cv2.imwrite("Image", image)

成果

QRCODE barcode: SMSTO:1922:場所代碼:2363 0508 8881 590
本次簡訊實聯限防疫目的使用

那今天就到這邊嗎?這樣寫一篇簡短的篇幅相信我半夜也會良心不安的,讓我們一起深入理解一下其中原理吧。

QR code

特色

QR code為正方形,常見的顏色就是黑白的,在三個角落都各有一個類似國字「回」的圖示,此為用來幫助掃瞄器定位的圖案,使得不管何種角度掃瞄都能準確定位。而在中間可以看到有6個校正圖塊(align pattern),用於校正辨識用,其他還有一些關於版本跟解碼格式的資訊。

https://zh.wikipedia.org/wiki/QR%E7%A2%BC

容錯能力

即使圖像上有所毀損,但QR code仍能被機器讀取,一般而言,QRcode圖形面積越大,容錯率越高。

主要分為四級:

  1. L — 容錯率7%
  2. M — 容錯率15%
  3. Q — 容錯率25%
  4. H — 容錯率30%

那我們大致先了解了構造,然後我們大致操作一下抓取圖片的作法:就是先抓出這三個定位點,我們可以使用cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)來抓出圖片中的所有輪廓,再因定位點是有六層輪廓這個特色來抓取,其中edges我們輸入的是轉為灰階後去抓出輪廓的圖

六層輪廓?

因為在計算輪廓中,一個顏色的方框會被計算兩次,而構成一個定位方塊為三個黑白方塊,所以我們以此為基準去做找尋。

findcoutour() 回傳值Hierarchy

程式碼

contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
hierarchy = hierarchy[0] #因為回傳的hierarchy是一個三維陣列
found = []
for i in range(len(contours)):
k = i
c = 0
while hierarchy[k][2] != -1:
k = hierarchy[k][2]
c = c + 1
if c >= 5:
found.append(i)
img_dc = img.copy()
for i in found:
cv2.drawContours(img_dc, contours, i, (0, 255, 0), 3)
cv2.imwrite('three_points.jpg',img_dc)

那以上就是如何定位QRcode的方法,今天先到這裡吧~😆

程式碼

參考連結

https://www.csie.ntu.edu.tw/~kmchao/bcc17spr/QR_Code_20170321.pdf

--

--