# -*- coding: utf-8 -*- # @Time : 2024/2/19 9:54 # @Author : len # @File : correct_qr.py # @Software: PyCharm # @Comment : import cv2 import numpy as np import scipy.spatial.distance as dist def correct_qr_code_skew(image_path): # 读取图像 image_source = cv2.imread(image_path) gray = cv2.cvtColor(image_source, cv2.COLOR_BGR2GRAY) # 使用goodFeaturesToTrack来检测角点 corners = cv2.goodFeaturesToTrack(gray, maxCorners=4, qualityLevel=0.01, minDistance=10) # 如果检测到角点 if corners is not None and len(corners) >= 4: # 对角点数组进行整形 corners = np.intp(corners) # 对角点进行排序 rect = order_points(corners.reshape(4, 2)) # 计算变换后图像的宽和高 width = max(int(dist.euclidean(rect[2], rect[3])), int(dist.euclidean(rect[1], rect[0]))) height = max(int(dist.euclidean(rect[1], rect[2])), int(dist.euclidean(rect[0], rect[3]))) # 构造目标点,用于将图像映射到鸟瞰图 dst = np.array([[0, 0], [width - 1, 0], [width - 1, height - 1], [0, height - 1]], dtype="float32") # 计算透视变换矩阵并应用 M = cv2.getPerspectiveTransform(rect, dst) warp = cv2.warpPerspective(image_source, M, (width, height)) # 使用QRCodeDetector来检测和解码二维码 detector = cv2.QRCodeDetector() data, vertices_array, binary_qr_code = detector.detectAndDecode(warp) # 如果检测到二维码,则返回解码数据 if vertices_array is not None: return data, warp else: print("未检测到二维码。") return None else: # 如果未检测到足够的角点,则打印错误信息 print("未检测到足够的角点。") return None # 用于排序角点的函数 def order_points(pts): # 初始化排序后的点 rect = np.zeros((4, 2), dtype="float32") # 根据点的坐标总和来进行排序 s = pts.sum(axis=1) rect[0] = pts[np.argmin(s)] rect[2] = pts[np.argmax(s)] # 计算点的差值,用于找到其余两个点 diff = np.diff(pts, axis=1) rect[1] = pts[np.argmin(diff)] rect[3] = pts[np.argmax(diff)] # 返回排序后的点 return rect # 运行校正函数 # 请确保传入正确的图像路径 result = correct_qr_code_skew("./data/img.png") if result: decoded_data, corrected_image = result print("解码的数据:", decoded_data)