Python | OpenCV QR Code 與 BarCode 辨識
📚 前言
在 與 OpenCV 整合推論 中,我們學會了如何把深度學習模型整合進 OpenCV 的視訊流程。
這一篇介紹一個非常實用的應用:QR Code 與 BarCode 辨識。
從商品掃碼、入場驗票到倉儲管理,條碼掃描是日常中最常見的電腦視覺應用之一,而且實作起來相對簡單。
🎨 範例圖片
這裡我們使用 BarcodeOcean 提供的條碼產生器:BarcodeOcean。
使用「生成QR Code」產生後,下載將檔名改為 qrcode.png,放在 assets/,即可用於以下各範例。
使用「生成條碼」產生後,下載將檔名改為 Barcode.png,放在 assets/,即可用於以下各範例。
🛠️ 套件安裝
OpenCV 內建 QRCodeDetector 可解碼 QR Code,Barcode 辨識則建議搭配 pyzbar 套件:
1 2
| pip install pyzbar pip install qrcode[pil]
|
💡 Windows 使用者若安裝 pyzbar 後出現 zbar DLL not found 錯誤,需另外下載 zbar DLL:
可安裝 pip install pyzbar-win32-fix 或從 zbar 官網 下載 DLL 後放入 %SystemRoot%\System32。
💻 使用 OpenCV 解碼 QR Code
OpenCV 內建 cv2.QRCodeDetector,不需要額外套件即可解碼 QR Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import cv2
img = cv2.imread("assets/qrcode.png") detector = cv2.QRCodeDetector()
data, bbox, _ = detector.detectAndDecode(img)
if data: print(f"QR Code 內容:{data}")
if bbox is not None: bbox = bbox.astype(int) for i in range(len(bbox[0])): pt1 = tuple(bbox[0][i]) pt2 = tuple(bbox[0][(i + 1) % len(bbox[0])]) cv2.line(img, pt1, pt2, (0, 255, 0), 2)
cv2.putText(img, data, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) else: print("未偵測到 QR Code")
cv2.imshow("QR Code", img) cv2.waitKey(0) cv2.destroyAllWindows()
|

圖:使用 OpenCV 內建 QRCodeDetector 解碼圖片中的 QR Code,繪製邊框並顯示解碼內容
💻 使用 pyzbar 解碼 QR Code 與 BarCode
pyzbar 支援多種條碼格式(QR Code、Code128、EAN-13、EAN-8、UPC-A 等),是更通用的選擇:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import cv2 from pyzbar import pyzbar
img = cv2.imread("assets/Barcode.png")
barcodes = pyzbar.decode(img)
for barcode in barcodes: data = barcode.data.decode("utf-8") bc_type = barcode.type
x, y, w, h = barcode.rect cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
label = f"{bc_type}: {data}" cv2.putText(img, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) print(f"類型:{bc_type},內容:{data}")
cv2.imshow("Barcode", img) cv2.waitKey(0) cv2.destroyAllWindows()
|

圖:使用 pyzbar 解碼圖片中的 QR Code 或 BarCode,繪製矩形框並輸出條碼類型與內容
💻 即時攝影機掃描
結合攝影機做即時掃描,是最常見的應用場景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| import cv2 from pyzbar import pyzbar
cap = cv2.VideoCapture(0) if not cap.isOpened(): print("無法開啟攝影機,請確認設備是否連接") exit() print("對準條碼,按 q 離開")
scanned = set()
while True: ret, frame = cap.read() if not ret: break
barcodes = pyzbar.decode(frame)
for barcode in barcodes: data = barcode.data.decode("utf-8") bc_type = barcode.type
x, y, w, h = barcode.rect cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(frame, f"{bc_type}: {data}", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
if data not in scanned: scanned.add(data) print(f"掃描到 [{bc_type}]:{data}")
cv2.imshow("Scanner", frame) if cv2.waitKey(1) & 0xFF == ord("q"): break
cap.release() cv2.destroyAllWindows()
|
📝 註:由於本身沒有攝影鏡頭,所以無法示範效果。
💻 批次處理圖片資料夾
需要批次掃描大量圖片時(如倉儲盤點照片):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import cv2 import os from pyzbar import pyzbar
img_dir = "assets/" results = []
for fname in os.listdir(img_dir): if not fname.lower().endswith((".jpg", ".jpeg", ".png")): continue
img = cv2.imread(os.path.join(img_dir, fname)) barcodes = pyzbar.decode(img)
for barcode in barcodes: data = barcode.data.decode("utf-8") bc_type = barcode.type results.append({"file": fname, "type": bc_type, "data": data}) print(f"{fname} [{bc_type}] {data}")
print(f"\n共掃描 {len(results)} 筆條碼")
|

圖:批次掃描目錄中的所有圖片,輸出每張圖片中偵測到的條碼類型、內容與統計筆數
💻 產生 QR Code
使用 qrcode 套件產生自訂的 QR Code 圖片:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import qrcode import os
output_dir = "output"
if not os.path.exists(output_dir): os.makedirs(output_dir) print(f"已自動建立資料夾:{output_dir}")
data1 = "https://morosedog.gitlab.io/"
img1 = qrcode.make(data1)
save_path1 = os.path.join(output_dir, "qrcode_basic.png") img1.save(save_path1) print(f"基本 QR Code 已儲存 → {save_path1}")
qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=10, border=4, )
qr.add_data("Hello, OpenCV!") qr.make(fit=True)
img2 = qr.make_image(fill_color="black", back_color="white")
save_path2 = os.path.join(output_dir, "qrcode_custom.png") img2.save(save_path2) print(f"自訂 QR Code 已儲存 → {save_path2}")
print("✅ 所有 QR Code 產生完成!")
|

圖:使用 qrcode 套件產生基本與自訂樣式的 QR Code 圖片,設定容錯等級、格子大小與邊框

圖:QR Code 錯誤修正等級(Error Correction Level)比較表,包含各等級的可容錯比例與建議使用情境
💻 用 OpenCV 驗證產生的 QR Code
產生後立刻用 OpenCV 驗證是否可正常讀取:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import qrcode import cv2 import numpy as np import os
data = "驗證測試字串"
qr_pil = qrcode.make(data)
rgb_array = np.array(qr_pil.convert("RGB")) img = cv2.cvtColor(rgb_array, cv2.COLOR_RGB2BGR)
detector = cv2.QRCodeDetector() decoded_data, bbox, _ = detector.detectAndDecode(img)
print(f"原始內容:{data}") print(f"解碼結果:{decoded_data}")
if decoded_data == data: print("✅ 驗證成功!產生與解碼一致") else: print("❌ 驗證失敗")
output_dir = "output" if not os.path.exists(output_dir): os.makedirs(output_dir)
save_path = os.path.join(output_dir, "qrcode_verify.png") cv2.imwrite(save_path, img) print(f"圖片已儲存至:{save_path}")
cv2.imshow("Generated QR Code", img) cv2.waitKey(0) cv2.destroyAllWindows()
|

圖:產生 QR Code 後立即用 OpenCV QRCodeDetector 解碼驗證,確認生成與讀取結果一致
⚠️ 注意事項
- 圖片品質影響辨識率:模糊、光線不足、角度過斜都會降低辨識率。實際應用時建議先做影像前處理(灰階、銳化)再解碼。
- pyzbar 比 OpenCV 內建的 QRCodeDetector 更通用:OpenCV 只能解 QR Code,pyzbar 支援十幾種條碼格式,建議以 pyzbar 為主。
- pyzbar 在 macOS 上需要額外安裝 zbar:
brew install zbar。
- 容錯等級越高,QR Code 越複雜:
ERROR_CORRECT_H 雖然耐用,但產生的圖案較密集,距離過遠時反而難以掃描。
- scanned set 防止重複觸發:即時掃描時同一個條碼可能連續數幀都被偵測到,用 set 記錄已掃描的內容可避免重複處理。
📊 應用場景
- 門票驗證:掃描入場 QR Code,即時查詢資料庫確認有效性。
- 商品盤點:批次掃描倉庫照片,自動統計 EAN-13 條碼數量。
- 名片辨識:掃描名片上的 QR Code,擷取聯絡資訊。
- 產線追蹤:每個產品貼上 QR Code,在生產各階段掃描記錄流程。
🎯 結語
QR Code 與 BarCode 辨識是電腦視覺中相對容易上手、卻非常實用的一塊。
搭配 pyzbar 與 OpenCV,幾十行程式就能完成即時掃描系統。
下一篇將進入 OpenCV 專案:即時濾鏡相機,實作一個可即時切換、疊加多種視覺效果的濾鏡相機。
📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。
註:以上參考了
OpenCV QRCodeDetector 官方文件
pyzbar GitHub
qrcode PyPI