在开始任何扫描工作之前,必须通过技术手段锁定扫描参数,防止人工操作失误。我们建议创建一个标准的 scan_config.json 配置文件,强制所有扫描终端调用此配置。
以下是标准配置文件内容,包含分辨率、色彩模式及压缩格式定义,请直接保存为 scan_config.json:
{
"quality_standards": {
"dpi": 300,
"color_mode": "RGB",
"bit_depth": 24,
"compression": "JPEG",
"compression_quality": 85,
"max_file_size_mb": 5,
"min_file_size_kb": 50
},
"image_processing": {
"auto_deskew": true,
"auto_rotate": true,
"border_removal": true
},
"output_format": {
"extension": ".jpg",
"naming_convention": "{date}_{batch_id}_{page_num:04d}"
}
}
该配置文件设定了DPI必须为300,色彩模式为24位RGB,并开启了自动纠偏和去边框功能。这是质量控制的技术基石。
为了保证档案文件的有序存储,不能依赖人工手动创建文件夹。使用以下 Python 脚本根据日期和批次号自动生成标准化的目录树结构。
请确保已安装 Python 环境,并执行以下脚本生成目录:
import os
from datetime import datetime
def create_archive_structure(root_path, batch_id):
"""
根据批次ID创建标准档案目录结构
"""
date_str = datetime.now().strftime("%Y%m%d")
base_dir = os.path.join(root_path, f"{date_str}_{batch_id}")
定义子目录结构
sub_dirs = [
"01_Original_Scans", 原始扫描件
"02_Processed_Images", 处理后图像
"03_Quality_Reports", 质检报告
"04_Failed_Checks" 不合格文件隔离区
]
if not os.path.exists(base_dir):
os.makedirs(base_dir)
for sub_dir in sub_dirs:
full_path = os.path.join(base_dir, sub_dir)
if not os.path.exists(full_path):
os.makedirs(full_path)
print(f"目录已创建: {full_path}")
使用示例:在D盘根目录下创建批次为BATCH_001的目录
create_archive_structure("D:/ArchiveData", "BATCH_001")
运行脚本后,系统会自动在 D:/ArchiveData 下生成包含原始、处理后、报告和隔离区的完整目录结构。
这是质量控制的核心环节。我们需要编写一个自动化脚本,对扫描生成的图片进行“四害”检测:模糊、黑边、分辨率不足、噪点。请安装依赖库:pip install opencv-python pillow numpy。
以下是一个完整的、可直接运行的质量检测类:
import cv2
import numpy as np
from PIL import Image
import os
class ImageQualityChecker:
def __init__(self, config):
self.min_dpi = config['quality_standards']['dpi']
self.min_variance = 100.0 模糊度阈值,越低越模糊
def check_dpi(self, image_path):
"""检查DPI是否符合标准"""
try:
with Image.open(image_path) as img:
dpi = img.info.get('dpi', (0, 0))
注意:有些JPG可能不包含DPI信息,此时默认为0
avg_dpi = (dpi[0] + dpi[1]) / 2 if dpi[0] > 0 else 0
if avg_dpi < self.min_dpi:
return False, f"DPI不足: {avg_dpi}"
return True, "DPI合格"
except Exception as e:
return False, f"DPI读取失败: {str(e)}"
def check_blur(self, image_path):
"""使用拉普拉斯方差检测模糊度"""
img = cv2.imread(image_path)
if img is None:
return False, "无法读取图像"
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
计算拉普拉斯方差
variance = cv2.Laplacian(gray, cv2.CV_64F).var()
if variance < self.min_variance:
return False, f"图像模糊 (方差: {variance:.2f})"
return True, f"清晰度合格 (方差: {variance:.2f})"
def check_blank_page(self, image_path):
"""检测是否为空白页(全黑或全白)"""
img = cv2.imread(image_path)
if img is None:
return False, "无法读取图像"
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
计算非零像素点比例
non_zero_pixels = cv2.countNonZero(gray)
total_pixels = gray.shape[0] gray.shape[1]
ratio = non_zero_pixels / total_pixels
如果非黑像素比例极低(接近全黑)或极高(接近全白),视为空白
if ratio < 0.05 or ratio > 0.98:
return False, f"疑似空白页 (像素比: {ratio:.4f})"
return True, "内容检测合格"
def run_full_check(self, image_path):
"""执行所有检查并返回结果字典"""
results = {
"filename": os.path.basename(image_path),
"path": image_path,
"status": "PASS",
"details": {}
}
checks = [
("DPI检查", self.check_dpi),
("清晰度检查", self.check_blur),
("空白页检查", self.check_blank_page)
]
for check_name, check_func in checks:
passed, msg = check_func(image_path)
results["details"][check_name] = msg
if not passed:
results["status"] = "FAIL"
return results
配置对象
config = {
'quality_standards': {
'dpi': 300
}
}
使用示例
checker = ImageQualityChecker(config)
result = checker.run_full_check("test_image.jpg")
print(result)
将上述代码保存为 quality_control.py。该脚本利用拉普拉斯算子计算图像方差,这是判断扫描件是否模糊的行业标准算法,能够精确识别手抖或对焦不准导致的图像质量问题。
有了单张图片的检测能力,接下来我们需要一个批处理脚本,遍历扫描文件夹,将不合格的文件自动移动到“04_Failed_Checks”目录,并生成CSV报告。

import csv
import shutil
def batch_process_directory(source_dir, report_dir, failed_dir, checker):
report_file = os.path.join(report_dir, "quality_report.csv")
准备CSV报告头
with open(report_file, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.writer(f)
writer.writerow(["文件名", "状态", "DPI检查",结果 = checker.run_full_check(file_path)
写入报告
writer.writerow([
result["filename"],
result["status"],
result["details"].get("DPI检查", ""),
result["details"].get("清晰度检查", ""),
result["details"].get("空白页检查", "")
])
如果不合格,则移动文件
if result["status"] == "FAIL":
dest_path = os.path.join(failed_dir, result["filename"])
shutil.move(file_path, dest_path)
print(f"[隔离] {result['filename']} 已移动至不合格区")
else:
print(f"[通过] {result['filename']} 质量合格")
执行批量处理
假设目录结构已由第二步脚本创建
base_path = "D:/ArchiveData/20231027_BATCH_001"
source = os.path.join(base_path, "01_Original_Scans")
failed = os.path.join(base_path, "04_Failed_Checks")
reports = os.path.join(base_path, "03_Quality_Reports")
确保目录存在
os.makedirs(source, exist_ok=True)
os.makedirs(failed, exist_ok=True)
os.makedirs(reports, exist_ok=True)
开始检查(请确保source目录下有图片文件)
batch_process_directory(source, reports, failed, checker)
该脚本会自动扫描 01_Original_Scans 文件夹,一旦发现模糊、DPI不足或空白页,立即将其移动到 04_Failed_Checks,并在 03_Quality_Reports 中生成详细的CSV日志,实现了“人防+技防”的闭环。
对于需要全文检索的档案,单纯的图像质量不够,还需要验证OCR识别率。我们需要引入 Tesseract OCR 引擎。
1. 安装 Tesseract:
下载 Windows 安装包:https://github.com/UB-Mannheim/tesseract/wiki
安装中文语言包:下载 chi_sim.traineddata 并放入 tessdata 目录。
安装 Python 绑定库:pip install pytesseract
2. OCR 识别率检测代码:
import pytesseract
请根据实际安装路径修改
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
def check_ocr_confidence(image_path, lang='chi_sim+eng'):
"""
获取OCR识别的平均置信度
"""
try:
获取详细数据,包括置信度
data = pytesseract.image_to_data(image_path, lang=lang, output_type=pytesseract.Output.DICT)
confidences = [int(c) for c in data['conf'] if int(c) > -1]
if not confidences:
return 0, "无识别内容"
avg_confidence = sum(confidences) / len(confidences)
设定阈值:平均置信度低于60视为不合格
if avg_confidence < 60:
return False, f"OCR识别率低: {avg_confidence:.2f}%"
return True, f"OCR识别率合格: {avg_confidence:.2f}%"
except Exception as e:
return False, f"OCR识别异常: {str(e)}"
将此方法集成到 ImageQualityChecker 类中即可完成全流程检测
通过引入OCR置信度检测,我们可以过滤掉那些虽然图像清晰但因反光、水印导致无法被OCR识别的文件,这是数字化档案质量控制的高级标准。
为了实现无人值守的扫描质检,建议将上述 Python 脚本打包为 Windows 可执行文件或使用 Linux Cron 任务。
打包命令(使用 PyInstaller):
pip install pyinstaller
pyinstaller --onefile --name ArchiveQualityGuard quality_control.py
打包完成后,将生成的 ArchiveQualityGuard.exe 放入扫描服务器,并配合 Windows 任务计划程序,设置为“当文件夹发生变化时触发”。这样,每当扫描仪生成一张新图,系统会在1秒内自动完成质检、归档或隔离,无需人工干预。