基于Python和OpenCV实现文档扫描与OCR识别系统,通过边缘检测、轮廓提取与透视变换校正倾斜文档,利用TesseractOCR提取文字。系统支持二值化或中值模糊预处理,可调整参数优化识别效果,适用于文档数字化处理。
Python+OpenCV文档扫描与OCR识别系统
时间:2026-07-29
浏览:292
文章目录
一、项目简介
本文介绍一个基于Python与OpenCV的文档扫描与OCR识别系统,能够自动检测文档边缘、执行透视变换校正,并借助Tesseract OCR引擎提取文档中的文字信息。该系统适用于日常办公中的文档数字化处理,有效提升文档整理效率。

项目效果:
- 输入:一张倾斜的文档照片
- 输出:校正后的正面文档视图 + 识别出的文字内容
二、项目演示
2.1 扫描流程
- 原始图像 → 读取文档照片
- 边缘检测 → 识别文档轮廓
- 透视变换 → 校正为正面视图
- 二值化处理 → 便于OCR识别
2.2 OCR识别流程
- 读取扫描图像 → 读取处理后的文档图像
- 图像预处理 → 二值化或中值模糊
- 文字识别 → 使用Tesseract提取文字
- 输出结果 → 打印识别的文字内容
三、技术栈
| 技术 | 用途 |
|---|---|
| Python | 编程语言 |
| OpenCV | 图像处理核心库 |
| NumPy | 数值计算 |
| Tesseract OCR | 文字识别引擎 |
| pytesseract | Tesseract 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:尝试以下方法:
- 确保图像清晰,对比度高,避免模糊或反光
- 调整预处理方式(
thresh或blur),根据图像噪点选择合适方法 - 检查图像是否倾斜或模糊,必要时重新校正
- 增加训练数据(添加中文训练数据支持中文识别,如
chi_sim语言包)
Q2: 轮廓检测不到文档边缘?
A:可能原因:
- 文档与背景对比度不足,可尝试调整图像亮度或使用不同背景
- 图像质量太差,如分辨率过低或严重畸变
- 调整Canny边缘检测阈值,降低下限或提高上限以捕捉更多边缘
- 尝试调整轮廓逼近参数,适当增大
0.02 * peri中的系数
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文字识别(预处理与调用)
希望这个项目对大家有所帮助,如果有任何问题或建议,欢迎在评论区留言交流!
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。