一、环境准备与依赖安装
在开始编写代码之前,我们需要搭建一个稳定且高效的Python运行环境。本文基于Linux环境(Ubuntu 20.04+)进行演示,Windows用户需调整部分路径配置,但核心代码逻辑通用。我们将使用Tesseract-OCR作为识别引擎,OpenCV进行图像预处理,SQLite作为轻量级数据库。
1. 安装系统级依赖
首先更新系统源并安装Tesseract引擎及其中文语言包。这是识别准确率的基础,必须安装chi_sim(简体中文)数据。
```bash
sudo apt-get update
sudo apt-get install tesseract-ocr tesseract-ocr-chi-sim
sudo apt-get install python3-pip python3-dev libglib2.0-0
```
安装完成后,使用以下命令验证引擎是否就绪:
```bash
tesseract --version
```
2. 安装Python依赖库
创建项目目录并安装必要的Python库。这里我们指定清华源以加快下载速度。
```bash
mkdir archive_digitalization
cd archive_digitalization
pip3 install pytesseract opencv-python pillow numpy
```
关键库说明:
- pytesseract: Tesseract的Python封装接口。
- opencv-python: 用于图像降噪、二值化处理。
- pillow: 用于基础的图像读写操作。
二、图像预处理算法实现
扫描件往往存在噪点、倾斜或光照不均的问题,直接送入OCR会导致识别率大幅下降。我们需要编写一个预处理函数,对图像进行灰度化、去噪和二值化处理。
在项目目录下创建文件preprocess.py,写入以下代码:
```python
import cv2
import numpy as np
def preprocess_image(image_path):
读取图像
image = cv2.imread(image_path)
if image is None:
raise ValueError(f"无法读取图像: {image_path}")
1. 转灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
2. 去噪 - 使用双边滤波保留边缘同时去除噪点
d=9, sigmaColor=75, sigmaSpace=75 是针对文档扫描的常用参数
denoised = cv2.bilateralFilter(gray, 9, 75, 75)
3. 二值化 - 使用Otsu算法自动寻找阈值
THRESH_BINARY_INV 将背景变白,文字变黑,符合Tesseract输入习惯
_, binary = cv2.threshold(denoised, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return binary
```
技术细节解析:
代码中使用了cv2.bilateralFilter而非高斯模糊,因为双边滤波在去噪的同时能更好地保留文字边缘,防止字符模糊不清。THRESH_OTSU会自动计算最佳的全局阈值,适应不同扫描亮度的文档。
三、OCR识别核心配置
接下来编写OCR识别模块。我们需要显式指定Tesseract的可执行文件路径(以防系统环境变量问题),并配置识别参数以优化中文识别效果。

创建文件ocr_engine.py:
```python
import pytesseract
from PIL import Image
import cv2
指定tesseract路径,Linux通常在/usr/bin/tesseract,Windows需改为exe路径
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
def extract_text_from_image(processed_image):
配置识别参数
--psm 6: 假设图像为统一的文本块
--oem 3: 使用默认的LSTM神经网络引擎
custom_config = r'--oem 3 --psm 6 -l chi_sim+eng'
try:
将OpenCV图像转换为PIL Image对象
pil_image = Image.fromarray(processed_image)
text = pytesseract.image_to_string(pil_image, config=custom_config)
return text
except Exception as e:
print(f"OCR识别失败: {e}")
return ""
```
参数配置重点:
-l chi_sim+eng表示同时加载简体中文和英文语言包,防止中英文混合档案出现乱码。--psm 6适用于单列、整齐排列的文档页,这是最常见的档案格式。
四、数据存储结构设计
为了实现数字化后的可检索性,我们将识别出的文本、原始文件名和识别时间存入SQLite数据库。这种方式无需配置额外的数据库服务器,零门槛落地。
创建文件db_manager.py:
```python
import sqlite3
import os
DB_NAME = "archives.db"
def init_db():
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
创建档案表,包含ID、文件名、识别内容、入库时间
cursor.execute('''
CREATE TABLE IF NOT EXISTS digital_archives (
id INTEGER PRIMARY KEY AUTOINCREMENT,
filename TEXT NOT NULL,
content TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
def insert_record(filename, content):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('''
INSERT INTO digital_archives (filename, content)
VALUES (?, ?)
''', (filename, content))
conn.commit()
conn.close()
print(f"已入库: {filename}")
def search_records(keyword):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
使用LIKE进行模糊查询
cursor.execute('''
SELECT filename, content, created_at FROM digital_archives
WHERE content LIKE ?
''', (f'%{keyword}%',))
results = cursor.fetchall()
conn.close()
return results
```
五、全流程自动化脚本编写
我们将上述模块串联起来。创建一个scan_images文件夹用于存放待处理的扫描件图片(支持jpg, png格式),然后编写主控脚本main.py。
1. 准备输入目录
```bash
mkdir scan_images
请将您的扫描件图片放入此目录,例如: scan_images/doc1.jpg
```
2. 编写主控逻辑
```python
import os
import glob
from preprocess import preprocess_image
from ocr_engine import extract_text_from_image
from db_manager import init_db, insert_record
def main():
初始化数据库
init_db()
获取scan_images目录下所有图片
image_dir = "scan_images"
supported_exts = ('.jpg', '.jpeg', '.png')
files_grabbed = []
for ext in supported_exts:
files_grabbed.extend(glob.glob(os.path.join(image_dir, ext)))
if not files_grabbed:
print(f"在 {image_dir} 目录下未找到图片文件,请先放入扫描件。")
return
print(f"开始处理,共发现 {len(files_grabbed)} 个文件...")
for image_path in files_grabbed:
filename = os.path.basename(image_path)
print(f"正在处理: {filename}")
try:
1. 预处理
processed_img = preprocess_image(image_path)
2. OCR识别
text_content = extract_text_from_image(processed_img)
清理识别结果中的多余空白字符
clean_text = " ".join(text_content.split())
if clean_text:
3. 入库
insert_record(filename, clean_text)
else:
print(f"警告: {filename} 未能识别出有效文字,请检查图片质量。")
except Exception as e:
print(f"处理文件 {filename} 时发生错误: {e}")
if __name__ == "__main__":
main()
```
六、检索与验证
处理完成后,我们需要验证数据是否正确入库,并测试检索功能。在main.py中追加一段简单的交互式查询代码,或者直接在Python命令行中操作。
为了方便测试,我们在main.py末尾添加一个简单的查询入口:
```python
... (接main函数中的代码) ...
print("\n所有文件处理完毕。")
print("-" 30)
简单的检索测试
from db_manager import search_records
while True:
keyword = input("请输入检索关键词 (输入 'q' 退出): ")
if keyword.lower() == 'q':
break
results = search_records(keyword)
if results:
print(f"找到 {len(results)} 条匹配记录:")
for idx, (fname, content, date) in enumerate(results, 1):
摘要显示,截取关键词前后部分
snippet = content[:50] + "..." if len(content) > 50 else content
print(f"{idx}. [{fname}] ({date})")
print(f" 摘要: {snippet}\n")
else:
print("未找到匹配记录。")
```
运行全流程
确保scan_images文件夹中有图片,然后直接运行主脚本:
```bash
python3 main.py
```
程序将自动遍历图片、进行降噪处理、识别中文并存入archives.db。处理完毕后,你可以直接在控制台输入关键词,系统会瞬间返回包含该关键词的档案文件名及内容摘要。