Embedded_game/QR/correct_qr.py

81 lines
2.5 KiB
Python
Raw Permalink Normal View History

2025-01-02 12:48:11 +08:00
# -*- 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)