老旧档案数字化修复与整理实操全流程指南
一、开发环境搭建与依赖配置
在开始档案修复之前,必须先配置好Python运行环境。本方案基于OpenCV进行图像处理,使用Tesseract-OCR进行文字识别。请严格按照以下步骤操作,避免环境不一致导致的报错。
1. 安装Python基础库
打开终端或命令行窗口,依次执行以下命令安装核心依赖库。OpenCV用于图像修复,Pillow用于格式转换,pytesseract是OCR的Python接口。
```
pip install opencv-python numpy pillow pytesseract
```
2. 安装Tesseract-OCR引擎
Python库只是接口,实际的识别能力依赖Tesseract引擎。
- Windows用户:访问 https://github.com/UB-Mannheim/tesseract/wiki 下载 tesseract-ocr-w64-setup-5.3.3.exe。安装时务必勾选 "Chinese (Simplified)" 语言包,否则无法识别中文档案。安装路径建议保持默认(C:\Program Files\Tesseract-OCR)。
- Linux用户:直接执行包管理命令。
```
sudo apt-get install tesseract-ocr tesseract-ocr-chi-sim
```
3. 配置环境变量
在Python脚本中需要指定Tesseract的可执行文件路径。如果是Windows用户,若未添加系统PATH,必须在代码中显式指定。创建一个 config.py 文件,内容如下:
```
import os
Windows用户请修改为你的实际安装路径
os.environ['TESSDATA_PREFIX'] = r'C:\Program Files\Tesseract-OCR\tessdata'
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
```
二、档案图像去噪与二值化处理
老旧纸质档案扫描后通常存在大量噪点、污渍或背景发灰的问题,直接影响OCR识别率。我们需要通过图像预处理技术将扫描件转化为高对比度的黑白图像。
1. 灰度化与高斯模糊
首先将彩色图像转为灰度图,减少计算量。随后使用高斯模糊去除高频噪声(如纸张纤维颗粒)。以下是核心处理函数:
```
import cv2
import numpy as np
def preprocess_image(image_path):
读取图像
img = cv2.imread(image_path)
if img is None:
raise ValueError(f"无法读取图像: {image_path}")
转为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
高斯模糊去噪,核大小(5,5)是经验值,适合一般文档
blur = cv2.GaussianBlur(gray, (5, 5), 0)
return blur
```
2. 自适应阈值二值化
不要使用简单的全局阈值(`cv2.threshold`),因为老旧档案光照往往不均匀。必须使用 自适应阈值 算法,它能根据图像局部像素亮度自动计算分界线,效果远优于全局处理。
```
def binarize_image(blur_img):
blockSize必须为奇数,11表示计算邻域的大小,C是减去的常数
THRESH_BINARY_INV表示背景白、字黑,符合阅读习惯
thresh = cv2.adaptiveThreshold(
blur_img, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2
)
return thresh
```
三、基于最小外接矩形的倾斜校正
人工扫描时很难保证纸张完全平整,倾斜的图像会导致OCR识别错位。我们需要通过检测文本行的轮廓来计算倾斜角度,并利用仿射变换进行旋转校正。
1. 检测文本块与计算角度
先提取所有文本行的坐标点,然后使用 `cv2.minAreaRect` 找到包含这些点的最小外接矩形,该矩形的角度即为图像的倾斜角。
```
def get_angle(thresh_img):
获取所有非零点(即文字像素点)的坐标
coords = np.column_stack(np.where(thresh_img > 0))
使用最小外接矩形计算角度
angle = cv2.minAreaRect(coords)[-1]
调整角度逻辑:minAreaRect返回的角度范围是[-90, 0]
如果角度小于-45,我们需要修正它以适应旋转逻辑
if angle < -45:
angle = -(90 + angle)
else:
angle = -angle
return angle
```
2. 执行旋转校正
获取角度后,构造旋转矩阵并执行 `cv2.warpAffine`。注意,旋转后图像边缘可能会被裁切,因此在计算旋转中心时需要格外小心。
```
def rotate_image(image, angle):
(h, w) = image.shape[:2]
center = (w // 2, h // 2)
构造旋转矩阵
M = cv2.getRotationMatrix2D(center, angle, 1.0)
执行仿射变换
rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
return rotated
```
四、OCR识别与元数据自动提取
图像修复完成后,下一步是提取档案中的关键信息(如档案号、日期、标题)用于文件重命名。我们将使用正则表达式从OCR结果中精准匹配目标字段。
1. 执行OCR识别
配置 `pytesseract` 的识别参数。`--psm 6` 表示假设图像为统一的文本块,这对于单页档案效果最好。
```
import pytesseract
from PIL import Image
import re
def extract_text(image_path):
使用PIL打开图像

pil_img = Image.open(image_path)
自定义配置:psm 6 适合单页文本块
custom_config = r'--oem 3 --psm 6 -l chi_sim+eng'
识别文本
text = pytesseract.image_to_string(pil_img, config=custom_config)
return text
```
2. 正则提取关键元数据
假设档案中有固定的格式,例如“档案编号:2023-001”和“日期:2023年10月01日”。我们需要编写正则表达式来捕获这些内容。如果识别失败,必须有默认值防止程序崩溃。
```
def parse_metadata(text):
提取档案编号,假设格式为"档号:"后跟数字
archive_id_match = re.search(r'档号[::]\s(\d+-\d+)', text)
archive_id = archive_id_match.group(1) if archive_id_match else "UNKNOWN_ID"
提取日期,匹配常见日期格式
date_match = re.search(r'(\d{4}年\d{1,2}月\d{1,2}日)', text)
date_str = date_match.group(1) if date_match else "UNKNOWN_DATE"
return archive_id, date_str
```
五、批量自动化整理脚本封装
将上述所有环节串联起来,编写一个主函数 `process_archive_folder`,实现对整个文件夹的遍历、修复、识别和重命名。这是实现零门槛落地的关键一步。
完整执行逻辑
创建 run.py,将以下代码完整复制进去。请确保你的目录结构中有一个名为 input 的文件夹存放待处理图片,程序会自动生成 output 文件夹存放结果。
```
import os
import cv2
import glob
假设上面的函数定义都在这个文件中,或者从config.py导入
from config import
def process_archive_folder(input_dir, output_dir):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
支持jpg, png, jpeg格式
files = glob.glob(os.path.join(input_dir, "."))
valid_ext = ('.jpg', '.jpeg', '.png')
for file_path in files:
if not file_path.lower().endswith(valid_ext):
continue
filename = os.path.basename(file_path)
print(f"正在处理: {filename}...")
try:
1. 图像预处理
blur_img = preprocess_image(file_path)
binary_img = binarize_image(blur_img)
2. 倾斜校正
angle = get_angle(binary_img)
如果角度太小,无需旋转,避免画质损失
if abs(angle) > 0.5:
注意:rotate_image通常作用于原图或灰度图,这里对原图旋转
original_img = cv2.imread(file_path)
fixed_img = rotate_image(original_img, angle)
else:
fixed_img = cv2.imread(file_path)
3. 保存中间修复图(可选,用于OCR)
temp_path = os.path.join(output_dir, "temp_" + filename)
cv2.imwrite(temp_path, fixed_img)
4. OCR识别与元数据提取
text = extract_text(temp_path)
archive_id, date_str = parse_metadata(text)
5. 重命名并移动到最终目录
新文件名格式:日期_档案号.扩展名
ext = os.path.splitext(filename)[1]
new_filename = f"{date_str}_{archive_id}{ext}"
清理文件名中的非法字符
new_filename = re.sub(r'[\\/?:"<>|]', "", new_filename)
final_path = os.path.join(output_dir, new_filename)
cv2.imwrite(final_path, fixed_img)
删除临时文件
os.remove(temp_path)
print(f"处理完成: {new_filename}")
except Exception as e:
print(f"处理文件 {filename} 失败: {str(e)}")
continue
if __name__ == "__main__":
定义输入输出路径,请根据实际情况修改
input_directory = "./input"
output_directory = "./output"
process_archive_folder(input_directory, output_directory)
```
操作说明:
- 准备数据:在项目根目录下新建 input 文件夹,将所有待修复的扫描档案图片放入其中。
- 运行脚本:在终端执行 python run.py。
- 查看结果:程序运行结束后,打开 output 文件夹。你将看到所有图片已经完成了去噪、倾斜校正,并且文件名已经自动修改为“日期_档案号”的格式,实现了从杂乱扫描件到结构化数字档案的自动化转变。