"""二维码识别工具。""" 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)