v1.1.0 - 架构重构 + Q11/Q16 修复
答题卡智能识别系统 v1.1.0
在 v1.0.0 黄金模板法基础上完成架构重构与识别精度优化,为后续接入 YOLO/AI 识别器铺平道路。
✨ 新增功能
🔌 阶段 1: Recognizer 协议抽象 (#7)
将黄金模板法与差分法统一到 Recognizer 协议下:
- 新增
core/recognizer.py:Protocol +RecognizeContext+RecognizeResult+make_recognizer工厂 - 新增
core/recognizers/golden.py:黄金模板法适配器 - 新增
core/recognizers/differential.py:差分法适配器(自动重整"(多涂)"后缀) - 后续接入 YOLO / AI 评分只需新增一个适配器,零侵入
app.py
🎯 阶段 2: ScoreCalculator 集中化 (#3)
把散落在 app.py:810-825 的内联算分循环抽离到独立模块:
- 新增
core/score_calculator.py:calc_total_score/match_answer/round_score纯函数 - Excel 导出新增
_answers_json列:未来 ground truth 可直接从历史 Excel 提取 - 算分逻辑 100% 可测试(22 用例),微服务化时可零改动平移到 FastAPI/gRPC
🔀 阶段 7: 双识别器交叉验证 (#8)
黄金模板法 vs 差分法交叉验证,分歧题自动进 Tab3 人工核对:
- 新增
core/recognizer_manager.py:RecognizerManager+ 4 种agreement_typeall_empty/all_match/one_uncertain/disputed
- Tab2 新增
enable_cross_validate开关,默认关闭, 0 回归 - Tab3 高亮
disputed题 + 新增"分歧""一致率"汇总列 - N=1 降级:单识别器时不误判为
one_uncertain
🐛 Bug 修复
Q11/Q16 低对比度场景误判 empty (#9)
修复真实场景中浅填涂被错判为空题的 bug:
- 根因:
core/golden_template.py:301防线1 阈值best_delta < 8过于宽松,Q11/Q16 类浅填涂(best_val=210, best_delta=5-7)穿过所有防线被误判为 empty - 修复:阈值收紧到
best_delta < 4,提取_classify_answer静态方法便于单测 - 新增 13 个边界测试覆盖 Q11/Q16 真实场景 + 阈值上下界
📊 测试覆盖
| 测试套件 | 用例数 |
|---|---|
test_score_calculator.py |
60 |
test_recognizer.py |
55 |
test_recognizer_manager.py |
57 |
test_golden_template.py |
48 (含 13 个新增边界用例) |
| 合计 | 220 passed, 0 failed |
🚀 兼容性
- 完全向后兼容:Tab2 默认走原黄金模板识别路径,识别结果与 v1.0.0 一致
- 可选新功能:
- Tab2 勾选"启用交叉验证"开启双识别器对比
- Tab3 自动展示
disputed题高亮
📦 本次发布包含
- 4 个新模块(
core/recognizer.py/core/recognizers/*/core/recognizer_manager.py/core/score_calculator.py) - 4 份单元测试(合计 220 测试用例)
- 3 份设计文档(
docs/plans/2026-06-01-stage{1,2,7}-*-design.md) app.py改造:Tab2 走 Recognizer 协议入口 / Tab3 改用 ScoreCalculator / Tab2 交叉验证开关
🔗 快速开始
cd omr_demo
pip install -r requirements.txt
python -m streamlit run app.py