文章目录
- 前言
- 一、实现方法
- 二、实现代码
- 三,效果
前言
随着科技的飞速发展,二维码作为一种信息载体,已经广泛应用于我们的日常生活中。无论是支付、身份验证还是信息传播,二维码都发挥着不可替代的作用。然而,在实际应用中,我们常常会遇到一个问题:由于拍摄角度、设备性能等因素的影响,导致二维码出现倾斜,从而影响识别效率。为此,本文将为大家介绍一种基于透射变换的二维码倾斜校正方法,帮助大家解决这一难题。
一、实现方法
首先,通过对图像进行二值化操作,获取二值化背景,之后进行形态学变换处理二维码区域。接下来,借助轮廓分析方法,通过凸包逼近多边形以及四边形近似获取的四个角点。最后,依据这四个角点的位置,我们应用透视变换技术对二维码进行了矫正,以确保其准确性和可读性。
二、实现代码
import cv2
import numpy as npdef sort_vertices_clockwise(vertices):"""将四边形的四个顶点按照顺时针排序"""# 找到y坐标最小的点(即最低点),如果有多个最低点,则选择x坐标最小的点lowest_idx = np.argmin(vertices[:, 1])lowest_point = vertices[lowest_idx]# 将最低点移动到数组的起始位置vertices = np.roll(vertices, -lowest_idx, axis=0)# 计算其他三个点相对于最低点的极角other_points = vertices[1:]ref_point = vertices[0]angles = np.arctan2(other_points[:, 1] - ref_point[1], other_points[:, 0] - ref_point[0])# 根据极角对顶点进行排序sorted_indices = np.argsort(angles)sorted_vertices = np.vstack((ref_point, other_points[sorted_indices]))return sorted_vertices# 图片路径
path = r"F:\cv_traditional\1725413298229.png"# 读取图片,转换为灰度图
img = cv2.imread(path, 0)
print(img.shape)# 二值化处理,设置阈值50,将图片转换为二值图像
ret, thd = cv2.threshold(img, 50, 255, cv2.THRESH_BINARY_INV)# 定义结构元素,用于形态学操作
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 21))# 对二值图像进行闭运算,填充轮廓内的孔洞
close = cv2.morphologyEx(thd, cv2.MORPH_CLOSE, kernel1)# 查找轮廓
contours, _ = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 找到面积最大的轮廓
max_contour = max(contours, key=cv2.contourArea)# 计算最大轮廓的凸包
hull = cv2.convexHull(max_contour)# 计算凸包的周长,并设置逼近多边形的精度
epsilon = 0.02 * cv2.arcLength(hull, True)# 使用approxPolyDP函数逼近多边形
approx = cv2.approxPolyDP(hull, epsilon, True)# 将轮廓点转换为1维数组
vertices_1d = np.array([np.squeeze(point) for point in approx])# 打印顺时针排序后的顶点
print(sort_vertices_clockwise(vertices_1d))# 绘制最大轮廓
cv2.drawContours(img, [approx], -1, (0, 255, 0), 3)# 获取图像的宽度和高度
h, w = img.shape# 定义变换后的目标点坐标
dst_point1 = [0, 0]
dst_point2 = [w, 0]
dst_point3 = [w, h]
dst_point4 = [0, h]# 将排序后的顶点转换为浮点数
ori = np.float32(sort_vertices_clockwise(vertices_1d))# 定义目标坐标点
dst = np.float32([dst_point1, dst_point2, dst_point3, dst_point4])# 计算透射变换矩阵
M = cv2.getPerspectiveTransform(ori, dst)# 应用透射变换
transformed_image = cv2.warpPerspective(img, M, (700, 700))# 显示原始图像和变换后的图像
cv2.imshow("原始图像", img)
cv2.imshow("变换后的图像", transformed_image)# 等待按键后关闭窗口
cv2.waitKey(0)
三,效果
倾斜图片:
校正后图片: