网站首页/ 信息中心/ 技术指南/

公安档案数字化:Python OCR识别与自动归档实操

发布时间:2026年06月09日 13:05:06 浏览量:0

一、环境准备与依赖安装

在开始编写代码之前,必须先配置好Python运行环境。本方案基于Python 3.8及以上版本,主要利用PaddleOCR进行中文识别,利用pandas进行数据整理。请严格按照以下步骤执行,避免环境冲突。

1. 安装Python依赖库

打开终端(Windows下为CMD或PowerShell),执行以下命令安装核心库。这里推荐使用清华源加速下载:

```bash pip install paddlepaddle paddleocr pandas pillow openpyxl pdf2image -i https://pypi.tuna.tsinghua.edu.cn/simple ```

2. 安装Poppler依赖(处理PDF必备)

如果档案中包含PDF文件,必须安装Poppler工具将PDF转换为图片。

二、目录结构设计

为了实现自动化处理,请在本地创建一个项目文件夹(例如 police_archive_tool),并严格按照以下结构建立子文件夹:

三、核心功能实现逻辑

本方案将整个流程封装为四个核心模块:文件预处理、OCR识别、关键信息提取、数据导出。

1. PDF转图像处理

公安档案多为扫描版PDF,OCR引擎无法直接读取,需先转换为图像。利用 pdf2image 库可以实现高保真转换。

代码逻辑中需指定 poppler_path,这是Windows用户最容易报错的地方,必须指向刚才解压的bin目录。

2. OCR文字识别

使用百度开源的 PaddleOCR。它在中文识别率和速度上优于Tesseract。初始化时设置 use_angle_cls=True 可以自动旋转文字,适应扫描件倾斜的问题。

3. 关键信息提取(正则)

公安档案数字化:Python OCR识别与自动归档实操

识别出的全文是杂乱的,我们需要利用正则表达式提取“身份证号”、“姓名”、“案件编号”等核心元数据。

4. 数据导出与脱敏

提取后的数据存入 pandas DataFrame,最后导出为Excel。出于安全考虑,导出前应对身份证号进行中间位脱敏处理。

四、完整代码实现

将以下代码保存为 archive_processor.py,放在项目根目录下。代码已包含完整注释,无需修改即可运行。

```python import os import re import shutil import pandas as pd from paddleocr import PaddleOCR from pdf2image import convert_from_path from PIL import Image import logging 配置日志 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') ================= 配置区域 ================= 文件夹路径配置 INPUT_DIR = 'input' OUTPUT_DIR = 'output' TEMP_DIR = 'temp' OUTPUT_EXCEL = 'archive_result.xlsx' Windows用户请修改此处为你的poppler bin路径,Linux/Mac可设为None POPPLER_PATH = r"C:\Program Files\poppler-23.08.0\Library\bin" 初始化OCR模型,第一次运行会自动下载模型文件 ocr = PaddleOCR(use_angle_cls=True, lang="ch", show_log=False) ================= 核心函数 ================= def ensure_dirs(): """确保所需目录存在""" for dir_path in [INPUT_DIR, OUTPUT_DIR, TEMP_DIR]: if not os.path.exists(dir_path): os.makedirs(dir_path) def convert_pdf_to_images(pdf_path): """ 将PDF转换为图片列表 :param pdf_path: PDF文件路径 :return: 图片路径列表 """ try: 注意:Windows下必须指定poppler_path pages = convert_from_path(pdf_path, poppler_path=POPPLER_PATH) image_paths = [] pdf_name = os.path.splitext(os.path.basename(pdf_path))[0] for i, page in enumerate(pages): temp_img_path = os.path.join(TEMP_DIR, f"{pdf_name}_page_{i+1}.jpg") page.save(temp_img_path, 'JPEG') image_paths.append(temp_img_path) return image_paths except Exception as e: logging.error(f"PDF转换失败: {pdf_path}, 错误: {e}") return [] def extract_text_from_image(img_path): """ 使用PaddleOCR识别图片文字 :param img_path: 图片路径 :return: 识别出的完整文本字符串 """ try: result = ocr.ocr(img_path, cls=True) full_text = "" if result and result[0]: for line in result[0]: text = line[1][0] full_text += text + "\n" return full_text except Exception as e: logging.error(f"OCR识别失败: {img_path}, 错误: {e}") return "" def extract_key_info(text, filename): """ 利用正则从文本中提取关键信息 :param text: OCR识别的文本 :param filename: 原始文件名 :return: 字典格式的信息 """ 身份证号正则(支持18位) id_card_pattern = r"[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]" 姓名提取(简单示例:匹配“姓名:”后的中文,需根据实际文书格式优化) name_pattern = r"姓名[::]\s([\u4e00-\u9fa5]{2,4})" 案件号示例(需根据实际公安文书格式修改) case_no_pattern = r"案件编号[::]\s([A-Za-z0-9\-]+)" id_match = re.search(id_card_pattern, text) name_match = re.search(name_pattern, text) case_match = re.search(case_no_pattern, text) info = { "文件名": filename, "姓名": name_match.group(1) if name_match else "未识别", "身份证号": id_match.group(0) if id_match else "未识别", "案件编号": case_match.group(1) if case_match else "未识别", "OCR全文摘要": text[:50] + "..." 仅保留前50字作为摘要 } return info def mask_sensitive_data(df): """ 对Excel中的身份证号进行脱敏处理 """ def mask_id(id_str): if len(id_str) == 18: return id_str[:6] + "" + id_str[-4:] return id_str if "身份证号" in df.columns: df["身份证号"] = df["身份证号"].apply(mask_id) return df def main(): ensure_dirs() all_data = [] 遍历输入文件夹 files = os.listdir(INPUT_DIR) if not files: logging.warning("input目录为空,请放入档案文件。") return for file in files: file_path = os.path.join(INPUT_DIR, file) logging.info(f"正在处理文件: {file}") images_to_process = [] 判断文件类型 if file.lower().endswith('.pdf'): images_to_process = convert_pdf_to_images(file_path) elif file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')): images_to_process = [file_path] else: logging.warning(f"跳过不支持的文件格式: {file}") continue 对每一页/每一张图进行识别 注意:如果一个文件有多页,通常取第一页或合并所有页文本。 这里我们取所有识别结果的汇总。 combined_text = "" for img_path in images_to_process: text = extract_text_from_image(img_path) combined_text += text + "\n" 提取信息 if combined_text.strip(): file_info = extract_key_info(combined_text, file) all_data.append(file_info) 清理临时图片 if file.lower().endswith('.pdf'): for img in images_to_process: if os.path.exists(img): os.remove(img) 数据导出 if all_data: df = pd.DataFrame(all_data) df = mask_sensitive_data(df) output_path = os.path.join(OUTPUT_DIR, OUTPUT_EXCEL) df.to_excel(output_path, index=False) logging.info(f"处理完成!结果已保存至: {output_path}") else: logging.info("未提取到任何有效信息。") if __name__ == "__main__": main() ```

五、常见问题处理

在实操过程中,可能会遇到以下技术细节问题,请对照排查:

1. 识别率低怎么办?

如果扫描件清晰度较差,可以在代码中加入图像预处理环节。在 extract_text_from_image 函数中,OCR识别前使用PIL对图片进行二值化和降噪处理:

```python 图像增强示例代码片段 from PIL import ImageEnhance img = Image.open(img_path) img = img.convert('L') 转灰度 img = ImageEnhance.Contrast(img).enhance(2.0) 提高对比度 img.save(img_path) ```

2. 提取不到特定字段?

公安文书种类繁多(拘留证、起诉意见书等),extract_key_info 函数中的正则表达式需要根据实际文书样式调整。建议先打印出 combined_text 查看OCR识别出的原始文本结构,再编写对应的正则。

3. 内存溢出?

如果批量处理几百个PDF,内存可能会爆。建议在 main 函数循环中,每处理10个文件就调用一次 import gc; gc.collect() 强制回收垃圾内存。

数字档案馆系统学籍数字档案馆系统实用操作指南
数字档案馆系统学籍数字档案馆系统实用操作指南
上个月我闺蜜评中级职称,需要提供当年的本科学籍档案证明。她跑了三趟原学校档案馆,人家说十年前的纸质档案,早就挪去郊外的仓库了。要调档得提前一周预约,还得本人签字才能调,给她急得连着两晚睡不着。后来才知...
2026年06月09日 13:05:06
微信咨询
电话联系
QQ客服
微信咨询一对一服务
服务热线: 028-8744 4417
QQ客服: 2305721818