opencv实战项目十九:透射变换倾斜二维码校正


前言

随着科技的飞速发展,二维码作为一种信息载体,已经广泛应用于我们的日常生活中。无论是支付、身份验证还是信息传播,二维码都发挥着不可替代的作用。然而,在实际应用中,我们常常会遇到一个问题:由于拍摄角度、设备性能等因素的影响,导致二维码出现倾斜,从而影响识别效率。为此,本文将为大家介绍一种基于透射变换的二维码倾斜校正方法,帮助大家解决这一难题。


一、实现方法

首先,通过对图像进行二值化操作,获取二值化背景,之后进行形态学变换处理二维码区域。接下来,借助轮廓分析方法,通过凸包逼近多边形以及四边形近似获取的四个角点。最后,依据这四个角点的位置,我们应用透视变换技术对二维码进行了矫正,以确保其准确性和可读性。

二、实现代码

import cv2
import numpy as np

def 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)

三,效果

倾斜图片:在这里插入图片描述
校正后图片:在这里插入图片描述

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值