基于Python+OpenCV实现文档扫描与OCR识别系统

 更新时间:2026年07月29日 09:00:44   作者:码力砖家  
本文主要分享了一个基于 Python + OpenCV 的文档扫描与OCR识别系统,这个项目可以自动检测文档边缘、进行透视变换校正,并使用 Tesseract OCR 提取文档中的文字内容,有需要的小伙伴可以了解下

一、项目简介

今天分享一个基于 Python + OpenCV 的文档扫描与OCR识别系统。这个项目可以自动检测文档边缘、进行透视变换校正,并使用 Tesseract OCR 提取文档中的文字内容。

项目效果

  • 输入:一张倾斜的文档照片
  • 输出:校正后的正面文档视图 + 识别出的文字内容

二、项目演示

2.1 扫描流程

  • 原始图像 → 读取文档照片
  • 边缘检测 → 识别文档轮廓
  • 透视变换 → 校正为正面视图
  • 二值化处理 → 便于OCR识别

2.2 OCR识别流程

  • 读取扫描图像 → 读取处理后的文档图像
  • 图像预处理 → 二值化或中值模糊
  • 文字识别 → 使用Tesseract提取文字
  • 输出结果 → 打印识别的文字内容

三、技术栈

技术用途
Python编程语言
OpenCV图像处理核心库
NumPy数值计算
Tesseract OCR文字识别引擎
pytesseractTesseract Python封装
Pillow图像读取

四、项目结构

Scan/
├── scan.py              # 文档扫描核心模块
├── test.py              # OCR文字识别模块
├── scan.jpg             # 默认输入/输出图像
├── images/              # 示例图像目录
│   ├── page.jpg         # 示例文档图像
│   └── receipt.jpg      # 示例收据图像
└── Tesseract-OCR/       # Tesseract OCR引擎(内置)

五、核心代码详解

5.1 文档扫描模块 (scan.py)

5.1.1 角点排序函数

def order_points(pts):
    # 初始化4个坐标点
    rect = np.zeros((4, 2), dtype = "float32")
    
    # 按顺序找到对应坐标:左上、右上、右下、左下
    s = pts.sum(axis = 1)
    rect[0] = pts[np.argmin(s)]  # 左上:x+y最小
    rect[2] = pts[np.argmax(s)]  # 右下:x+y最大
    
    diff = np.diff(pts, axis = 1)
    rect[1] = pts[np.argmin(diff)]  # 右上:x-y最小
    rect[3] = pts[np.argmax(diff)]  # 左下:x-y最大
    
    return rect

原理:通过计算坐标点的和与差来确定四个角点的位置,确保顺序正确。

5.1.2 透视变换函数

def four_point_transform(image, pts):
    rect = order_points(pts)
    (tl, tr, br, bl) = rect
    
    # 计算目标宽度和高度
    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, (maxWidth, maxHeight))
    
    return warped

原理:根据原始四个角点和目标矩形,计算透视变换矩阵,将倾斜的文档校正为正面视图。

5.1.3 主流程

# 1. 读取图像并缩放
image = cv2.imread(args["image"])
ratio = image.shape[0] / 500.0
orig = image.copy()
image = resize(orig, height = 500)

# 2. 边缘检测
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 75, 200)

# 3. 轮廓检测
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:5]

# 4. 找到四边形轮廓
for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)
    if len(approx) == 4:
        screenCnt = approx
        break

# 5. 透视变换和二值化
warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
ref = cv2.threshold(warped, 100, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite('scan.jpg', ref)

步骤说明

  • 读取图像并按比例缩放
  • 灰度化 → 高斯模糊 → Canny边缘检测
  • 查找轮廓并按面积排序
  • 通过轮廓逼近找到四边形(文档边缘)
  • 进行透视变换和二值化处理

5.2 OCR识别模块 (test.py)

from PIL import Image
import pytesseract
import cv2
import os

preprocess = 'blur'  # thresh

image = cv2.imread('scan.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 预处理
if preprocess == "thresh":
    gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
elif preprocess == "blur":
    gray = cv2.medianBlur(gray, 3)

# 调用Tesseract OCR
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename, gray)
pytesseract.pytesseract.tesseract_cmd = r'./Tesseract-OCR/tesseract.exe'
text = pytesseract.image_to_string(Image.open(filename))
print(text)
os.remove(filename)

预处理方式

  • thresh:二值化处理,适用于对比度较高的图像
  • blur:中值模糊处理,适用于有噪点的图像

六、安装与运行

6.1 安装依赖

pip install numpy opencv-python pytesseract pillow

6.2 运行文档扫描

# 使用默认图像
python scan.py
​
# 指定输入图像
python scan.py -i images/page.jpg

6.3 运行OCR识别

python test.py

七、使用技巧

7.1 图像采集建议

  • 光线充足:避免阴影和反光
  • 对比度明显:文档与背景颜色差异大
  • 边缘清晰:文档边界完整可见
  • 适度距离:不要太近或太远

7.2 参数调整

  • Canny边缘检测阈值cv2.Canny(gray, 75, 200),根据图像调整
  • 轮廓逼近精度0.02 * peri,值越小轮廓越接近原始
  • 二值化阈值cv2.threshold(warped, 100, 255, ...),根据图像亮度调整

八、常见问题

Q1: OCR识别率低怎么办?

A:尝试以下方法:

  1. 确保图像清晰,对比度高
  2. 调整预处理方式(threshblur
  3. 检查图像是否倾斜或模糊
  4. 增加训练数据(添加中文训练数据支持中文识别)

Q2: 轮廓检测不到文档边缘?

A:可能原因:

  1. 文档与背景对比度不足
  2. 图像质量太差
  3. 调整Canny边缘检测阈值
  4. 尝试调整轮廓逼近参数

Q3: 如何支持中文识别?

A:下载中文训练数据 chi_sim.traineddata,放入 Tesseract-OCR/tessdata/ 目录,然后修改代码:

text = pytesseract.image_to_string(Image.open(filename), lang='chi_sim')

九、项目扩展

批量处理:支持批量扫描多个文档

图形界面:添加PyQt或Tkinter界面

实时扫描:使用摄像头实时扫描

多语言支持:添加多种语言的OCR训练数据

文档分类:根据内容自动分类文档

十、总结

本文介绍了一个基于 Python + OpenCV 的文档扫描与OCR识别系统,通过边缘检测、轮廓提取、透视变换和OCR识别等技术,实现了从文档照片到文字提取的完整流程。

核心知识点

  • 图像预处理(灰度化、高斯模糊、边缘检测)
  • 轮廓检测与筛选
  • 透视变换校正
  • Tesseract OCR文字识别

希望这个项目对大家有所帮助,如果有任何问题或建议,欢迎在评论区留言交流!

相关文章

  • Python手拉手教你爬取贝壳房源数据的实战教程

    Python手拉手教你爬取贝壳房源数据的实战教程

    随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容,了解python爬虫,本文给大家分享Python爬取贝壳房源数据的实战教程,感兴趣的朋友一起学习吧
    2021-05-05
  • 分布式全文检索引擎ElasticSearch原理及使用实例

    分布式全文检索引擎ElasticSearch原理及使用实例

    这篇文章主要介绍了分布式全文检索引擎ElasticSearch原理及使用实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Python OLS 双向逐步回归方式

    Python OLS 双向逐步回归方式

    这篇文章主要介绍了Python OLS 双向逐步回归方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • python出现RuntimeError错误问题及解决

    python出现RuntimeError错误问题及解决

    这篇文章主要介绍了python出现RuntimeError错误问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Python之pymysql的使用小结

    Python之pymysql的使用小结

    这篇文章主要介绍了Python之pymysql的使用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • Python代码列表求并集,交集,差集

    Python代码列表求并集,交集,差集

    这篇文章主要介绍了Python代码列表求并集,交集,差集,下面文章讲详细的介绍如何利用python代码实现并集,交集,差集的相关资料展开内容,需要的朋友可以参考一下
    2021-11-11
  • python 全文检索引擎详解

    python 全文检索引擎详解

    这篇文章主要介绍了python 全文检索引擎详解的相关资料,需要的朋友可以参考下
    2017-04-04
  • 用Cython加速Python到“起飞”(推荐)

    用Cython加速Python到“起飞”(推荐)

    这篇文章主要介绍了用Cython加速Python到“起飞”,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • anaconda 部署Jupyter Notebook服务器过程详解

    anaconda 部署Jupyter Notebook服务器过程详解

    这篇文章主要为大家介绍了anaconda 部署Jupyter Notebook服务器过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Python代码实现双链表

    Python代码实现双链表

    这篇文章主要为大家详细介绍了Python代码实现双链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05

最新评论