81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
|
# -*- 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)
|
||
|
|
||
|
|
||
|
|