it编程 > 前端脚本 > Python

Python利用OpenCV实现文档图像自动矫正的方法

0人参与 2026-03-19 Python

1. 引言

在日常生活中,用手机拍摄的文档照片往往因为拍摄角度而产生透视畸变——原本方正的纸张变成了不规则的四边形,导致文字歪斜,影响阅读和ocr识别。透视变换技术可以将图像中任意四边形区域“拉正”为矩形,完美解决这一问题。本文将基于你提供的完整python代码,深入解析利用opencv实现自动文档矫正的每一步,从图像预处理、轮廓检测到透视变换,并详细讲解核心函数的原理与参数含义。

2. 透视变换核心原理

透视变换是一种将图像从一个平面投影到另一个平面的几何变换。它用一个 3×3 的单应性矩阵 描述,需要至少4对对应点才能求解。在文档矫正场景中,这4对点就是原始图像中文档的四个顶点和矫正后矩形的四个顶点。opencv提供了两个核心函数:

3. 环境准备

4. 代码逐段详解

4.1 导入库

import numpy as np
import cv2

4.2 辅助函数

4.2.1 图像显示函数cv_show

def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitkey(0)
    cv2.destroyallwindows()

4.2.2 图像等比例缩放函数resize

def resize(image, width=none, height=none, inter=cv2.inter_area):
    dim = none
    (h, w) = image.shape[:2]
    if width is none and height is none:
        return image
    if width is none:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))
    resized = cv2.resize(image, dim, interpolation=inter)
    return resized

4.2.3 顶点排序函数order_points

def order_points(pts):
    # 一共4个坐标点
    rect = np.zeros(shape=(4, 2), dtype="float32")  # 用来存储排序之后的坐标位置
    # 按顺序找到对应坐标0123分别是 左上,右上,右下,左下
    s = pts.sum(axis=1)  # 对pts矩阵的每一行进行求和操作。(x+y)
    rect[0] = pts[np.argmin(s)]
    rect[2] = pts[np.argmax(s)]
    diff = np.diff(pts, axis=1)  # 对pts矩阵的每一行进行求差操作。(y-x)
    rect[1] = pts[np.argmin(diff)]
    rect[3] = pts[np.argmax(diff)]
    return rect

4.2.4 透视变换核心函数four_point_transform

def four_point_transform(image, pts):
    # 获取输入坐标点
    rect = order_points(pts)
    (tl, tr, br, bl) = rect
    # 计算输入的w和h值
    widtha = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
    widthb = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
    maxwidth = max(int(widtha), int(widthb))
    heighta = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
    heightb = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
    maxheight = max(int(heighta), int(heightb))
    # 变换后对应坐标位置
    dst = np.array([[0, 0], [maxwidth - 1, 0],
                            [maxwidth - 1, maxheight - 1], [0, maxheight - 1]], dtype="float32")
    # 获取透视变换矩阵
    m = cv2.getperspectivetransform(rect, dst)
    # 执行透视变换
    warped = cv2.warpperspective(image, m, dsize=(maxwidth, maxheight))
    # 返回变换后结果
    return warped

步骤解析:

4.3 主程序流程

4.3.1 读取图像并显示原图

image = cv2.imread('fapiao.jpg')
cv_show('image', image)

4.3.2 缩放图像以加快处理

ratio = image.shape[0] / 500.0  # 计算缩小比率
orig = image.copy()
image = resize(orig, height=500)
cv_show('1', image)

结果展示:

4.3.3 轮廓检测

print("step 1: 轮廓检测")
gray = cv2.cvtcolor(image, cv2.color_bgr2gray)  # 读取灰度图

edged = cv2.threshold(gray, 0, 255, cv2.thresh_binary | cv2.thresh_otsu)[1]  # 自动寻找阈值二值化
cnts = cv2.findcontours(edged.copy(), cv2.retr_list, cv2.chain_approx_simple)[-2]
image_contours = cv2.drawcontours(image.copy(), cnts, -1, color=(0, 0, 255), thickness=1)
cv_show('image_contours', image_contours)

结果展示:

4.3.4 获取最大轮廓并近似为四边形

print("step 2: 获取最大轮廓")
screencnt = sorted(cnts, key=cv2.contourarea, reverse=true)[0]  # 获取面积最大的轮廓
print(screencnt.shape)
peri = cv2.arclength(screencnt, closed=true)  # 计算轮廓周长
screencnt = cv2.approxpolydp(screencnt, 0.05 * peri, closed=true)  # 轮廓近似
print(screencnt.shape)
image_contour = cv2.drawcontours(image.copy(), [screencnt], -1, (0, 255, 0), thickness=2)

cv2.imshow("image_contour", image_contour)
cv2.waitkey(0)

结果展示:

4.3.5 透视变换

###############
# 透视变换
warped = four_point_transform(orig, screencnt.reshape(4, 2) * ratio)
cv2.imwrite('invoice_new.jpg', warped)
cv2.namedwindow('xx', cv2.window_normal)
cv2.imshow("xx", warped)
cv2.waitkey(0)

运行结果展示:

5. 运行结果

输入图像 fapiao.jpg 是一张倾斜拍摄的发票,程序将依次显示:

矫正后的图像将呈现标准的矩形,文字方向变正,极大方便后续ocr识别。

6. 总结与注意事项

6.1 总结

本文通过一个完整的opencv案例,详细讲解了如何利用透视变换自动矫正倾斜的文档图像。核心步骤包括:

代码结构清晰,函数封装良好,便于复用和扩展。

6.2 注意事项

通过理解和掌握这段代码,你可以轻松将其应用到车牌矫正、名片扫描、增强现实等更多场景中。如果在实践中遇到问题,欢迎留言交流!

以上就是python利用opencv实现文档图像自动矫正的方法的详细内容,更多关于python opencv文档图像自动矫正的资料请关注代码网其它相关文章!

(0)

您想发表意见!!点此发布评论

推荐阅读

Python编程之PDF转图片的三种实现方法详解

03-19

Python项目重构SQLite数据库的实战记录

03-19

Python实现桌面端应用消息提醒功能

03-19

python在windows开启webserver的几种方法

03-19

Python + Skills 架构实现从理论到实践

03-19

Python基础课程之猜数字游戏完整代码示例

03-19

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论