自动化测试框架:cv_resnet18_ocr-detection识别准确率回归测试
1. 背景与目标
随着OCR(光学字符识别)技术在文档数字化、证件识别、票据处理等场景中的广泛应用,模型的稳定性与准确性成为工程落地的关键指标。cv_resnet18_ocr-detection是由科哥构建的一款基于ResNet-18骨干网络的文字检测模型,具备轻量级、高推理速度和良好精度的特点,适用于边缘设备部署。
在持续迭代开发过程中,每次代码更新或模型微调都可能影响原有功能表现。因此,建立一套自动化回归测试框架,用于定期验证cv_resnet18_ocr-detection模型的识别准确率是否稳定,是保障系统可靠性的必要手段。
本文将详细介绍如何为该OCR模型设计并实现一个完整的识别准确率回归测试系统,涵盖测试数据管理、自动化执行流程、结果比对机制、阈值告警策略以及与WebUI系统的集成方案。
2. 回归测试框架设计
2.1 测试目标定义
本回归测试的核心目标包括:
- 验证模型输出一致性:确保新版本模型对相同输入图像的检测结果保持稳定。
- 评估识别准确率变化:通过标准测试集计算 Precision、Recall 和 F1-score,判断性能波动。
- 检测误检/漏检趋势:分析是否存在新增的误识别或关键文本遗漏问题。
- 支持多环境对比:可在 CPU/GPU 不同硬件环境下运行测试,评估平台差异影响。
2.2 整体架构设计
回归测试系统采用模块化设计,整体结构如下:
regression_test/ ├── test_data/ # 标准测试图像集 │ ├── doc_images/ # 文档类图片 │ ├── id_cards/ # 证件类图片 │ └── screenshots/ # 截图类图片 ├── ground_truth/ # 真实标注文件(JSON格式) ├── scripts/ │ ├── run_test.py # 主测试脚本 │ ├── evaluate.py # 准确率评估模块 │ └── report_generator.py # 报告生成器 ├── outputs/ │ └── report_latest.html # 最新测试报告 └── config.yaml # 测试参数配置2.3 关键组件说明
| 组件 | 功能 |
|---|---|
| test_data | 存放具有代表性的测试图像,覆盖清晰文档、模糊截图、复杂背景等多种场景 |
| ground_truth | 提供每张图像的标准检测框坐标与文本内容,作为评估基准 |
| run_test.py | 调用 WebUI 后端 API 或本地模型接口进行批量推理 |
| evaluate.py | 实现 IoU(交并比)匹配逻辑,统计 TP/FP/FN 并计算指标 |
| report_generator.py | 生成 HTML 可视化报告,包含图表与失败案例展示 |
3. 自动化测试流程实现
3.1 测试准备阶段
数据预处理
所有测试图像统一重采样至分辨率 1024×768,并保存为 PNG 格式以避免压缩失真。同时,使用标注工具确认每张图像的真实边界框信息,存储为 JSON 文件:
{ "image_path": "test_data/doc_images/contract_01.png", "texts": ["甲方:张三", "乙方:李四", "签署日期:2025年1月1日"], "boxes": [ [100, 200, 300, 200, 300, 230, 100, 230], [100, 250, 300, 250, 300, 280, 100, 280], [100, 300, 400, 300, 400, 330, 100, 330] ] }配置文件设置
config.yaml中定义测试参数:
model_name: cv_resnet18_ocr-detection test_dir: ./test_data gt_dir: ./ground_truth output_dir: ./outputs iou_threshold: 0.5 confidence_threshold: 0.2 device: cuda # or cpu batch_size: 13.2 执行推理测试
使用 Python 脚本调用模型服务(可通过 REST API 或直接加载 ONNX 模型):
import cv2 import onnxruntime as ort import json from pathlib import Path def run_inference(image_path, session): image = cv2.imread(str(image_path)) h, w = image.shape[:2] input_blob = cv2.resize(image, (800, 800)).astype(np.float32) / 255.0 input_blob = input_blob.transpose(2, 0, 1)[np.newaxis, ...] outputs = session.run(None, {"input": input_blob}) # 解码输出,转换为原始尺寸坐标 boxes, texts, scores = decode_outputs(outputs[0], (w, h)) return { "image_path": str(image_path), "texts": [[t] for t in texts], "boxes": boxes, "scores": scores, "success": True, "inference_time": 0.18 }注意:实际部署中建议封装为独立服务,便于远程调用。
3.3 结果评估算法
核心评估函数基于 IoU 判断预测框与真实框是否匹配:
def calculate_iou(box1, box2): poly1 = Polygon([(box1[i], box1[i+1]) for i in range(0, 8, 2)]) poly2 = Polygon([(box2[i], box2[i+1]) for i in range(0, 8, 2)]) if not poly1.is_valid or not poly2.is_valid: return 0.0 intersection = poly1.intersection(poly2).area union = poly1.union(poly2).area return intersection / union if union > 0 else 0.0 def evaluate(predictions, ground_truths): tp, fp, fn = 0, 0, 0 matched_gt = set() for pred_box, pred_text in zip(predictions['boxes'], predictions['texts']): best_iou = 0 best_idx = -1 for idx, (gt_box, gt_text) in enumerate(zip(ground_truths['boxes'], ground_truths['texts'])): if idx in matched_gt: continue iou = calculate_iou(pred_box, gt_box) if iou > best_iou and iou >= 0.5: best_iou = iou best_idx = idx if best_idx != -1: tp += 1 matched_gt.add(best_idx) else: fp += 1 fn = len(ground_truths['boxes']) - len(matched_gt) precision = tp / (tp + fp) if (tp + fp) > 0 else 0 recall = tp / (tp + fn) if (tp + fn) > 0 else 0 f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0 return {"precision": precision, "recall": recall, "f1": f1, "tp": tp, "fp": fp, "fn": fn}4. 回归测试报告生成
4.1 报告内容结构
每次测试完成后自动生成 HTML 报告,包含以下部分:
- 概览面板:F1-score 对比曲线、总耗时、成功率
- 详细指标表:按图像类别分组的 Precision/Recall 表格
- 失败案例展示:高亮显示漏检(红色框)和误检(蓝色框)区域
- 历史趋势图:过去 7 次测试的 F1 分数变化趋势
4.2 示例报告片段
<h3>测试结果汇总</h3> <table border="1"> <tr><th>测试集</th><th>图像数量</th><th>Precision</th><th>Recall</th><th>F1-score</th></tr> <tr><td>文档类</td><td>20</td><td>0.96</td><td>0.94</td><td>0.95</td></tr> <tr><td>证件类</td><td>15</td><td>0.92</td><td>0.89</td><td>0.90</td></tr> <tr><td>截图类</td><td>25</td><td>0.85</td><td>0.80</td><td>0.82</td></tr> </table> <img src="outputs/fail_cases_highlighted.png" alt="失败案例可视化">4.3 异常告警机制
当满足以下任一条件时触发告警:
- F1-score 下降超过 3%
- FP 数量增加超过 20%
- 单图推理时间增长超过 50%
告警方式支持:
- 控制台输出警告
- 发送微信消息(通过企业微信机器人)
- 记录日志到
alerts.log
5. 与 WebUI 系统集成
5.1 新增“回归测试”Tab页
在现有 WebUI 基础上扩展第五个功能页签:“回归测试”,提供图形化操作界面:
| 功能 | 描述 |
|---|---|
| 选择测试集 | 下拉菜单选择预设测试目录 |
| 设置阈值 | 调整 confidence 和 iou 阈值 |
| 开始测试 | 启动自动化测试流程 |
| 查看报告 | 内嵌 iframe 显示最新 HTML 报告 |
| 导出结果 | 下载 JSON 格式的完整测试数据 |
5.2 后端API接口设计
新增 Flask 路由支持测试控制:
@app.route('/api/run_regression', methods=['POST']) def api_run_regression(): data = request.json test_dir = data.get('test_dir') conf_thresh = data.get('conf_thresh', 0.2) result = run_regression_test(test_dir, conf_thresh) return jsonify(result) @app.route('/api/latest_report') def get_latest_report(): return send_file('outputs/report_latest.html')6. 定期执行与CI/CD集成
6.1 使用cron定时任务
每日凌晨自动执行一次完整测试:
# crontab -e 0 2 * * * cd /root/cv_resnet18_ocr-detection/regression_test && python run_test.py6.2 Git Hook 触发机制
在代码提交时触发快速测试(仅限关键文件变更):
# .git/hooks/pre-push #!/bin/bash if git diff --cached --name-only | grep -q "models\|inference"; then echo "检测到模型相关更改,正在运行快速回归测试..." python regression_test/run_test.py --quick if [ $? -ne 0 ]; then echo "回归测试失败,禁止推送!" exit 1 fi fi7. 总结
7. 总结
本文围绕cv_resnet18_ocr-detectionOCR文字检测模型,构建了一套完整的识别准确率回归测试系统。该系统具备以下核心能力:
- 标准化测试集管理:覆盖多种真实应用场景,确保测试代表性。
- 自动化推理与评估:通过脚本驱动实现无人值守测试,提升效率。
- 量化指标分析:基于 IoU 匹配机制计算 Precision、Recall 和 F1-score,客观反映模型性能。
- 可视化报告输出:生成可读性强的 HTML 报告,便于团队协作审查。
- 异常告警与CI集成:支持定时运行与代码提交拦截,防止劣化版本上线。
该回归测试框架已成功应用于科哥开发的 WebUI 系统中,显著提升了模型迭代过程中的质量控制水平。未来可进一步扩展支持多语言测试、对抗样本检测及模型漂移监控等功能。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。