Files
campus_spider/app/tool/qr_decode.py
T

55 lines
1.7 KiB
Python

"""二维码识别工具。"""
from __future__ import annotations
from pathlib import Path
import cv2
import numpy as np
from .cv import _load_image, _normalize_points, _warp_qr_image
def _decode_with_detector(img: np.ndarray) -> list[str]:
detector = cv2.QRCodeDetector()
texts: list[str] = []
if hasattr(detector, "detectAndDecodeMulti"):
ok, decoded_info, points, _ = detector.detectAndDecodeMulti(img)
if ok and points is not None:
normalized_points = _normalize_points(points)
if isinstance(decoded_info, (list, tuple)):
decoded_iter = [item or "" for item in decoded_info]
else:
decoded_iter = [decoded_info or ""]
for idx, points_item in enumerate(normalized_points):
text = decoded_iter[idx] if idx < len(decoded_iter) else ""
if not text:
crop = _warp_qr_image(img, np.array(points_item, dtype=np.float32))
fallback_text, _, _ = detector.detectAndDecode(crop)
text = fallback_text or ""
if text:
texts.append(text)
if texts:
return texts
text, points, _ = detector.detectAndDecode(img)
if text:
return [text]
normalized_points = _normalize_points(points)
if normalized_points:
crop = _warp_qr_image(img, np.array(normalized_points[0], dtype=np.float32))
fallback_text, _, _ = detector.detectAndDecode(crop)
if fallback_text:
return [fallback_text]
return []
def decode_qr(image: bytes | np.ndarray | str | Path) -> list[str]:
"""识别图片中的二维码内容。"""
img = _load_image(image)
return _decode_with_detector(img)