返回

拍屏识别不只看 RGB:从频域特征到 ONNX 推理

同一段文字,可能来自直接截图,也可能是手机对着显示器拍下的照片。压缩、反光和缩放会改变它们的外观,只看画面内容并不容易区分。opencv-screen-detector 研究的是自然照片、截图与拍屏图片的整图三分类,不是寻找屏幕位置的目标检测器。

三路输入,各自回答不同问题

模型把图像拆成空间和频域两类信息。RGB 分支使用 EfficientNet-B0 提取外观特征;FFT 分支将灰度图缩放后做二维傅里叶变换、频谱中心化和对数幅度处理;DWT 分支通过 Haar 小波分解得到低频与三个高频子带。频域分支经过卷积,分别归一化后与空间特征拼接,输出三个类别的 logits。

这套组合并不意味着频域一定优于普通分类器。它提供了可以做消融实验的结构:哪些信息有用,应由独立数据上的比较回答,而不是靠网络图判断。

这里还有一个容易漏掉的部署细节:FFT 和 DWT 在 Python 侧计算,不在 ONNX 图里。模型实际接收三组张量,只有模型文件并不足以复现服务。训练与推理共用 shared/fft_transform.py,就是为了避免同名特征在两端算出不同结果。

从模型概率到业务动作

推理服务采用 ONNX Runtime。原图与水平翻转图分别推理,平均概率后,再执行低置信度拒绝、拍屏阈值判断和置信度分级。输出除了类别,还包含概率与 accept、review、ignore 建议,为人工复核留下入口。

这些规则是服务行为的一部分。随机张量上的 PyTorch/ONNX 数值对比,只能说明模型计算接近,不能证明真实图片经过预处理、翻转和阈值之后,会得到同样的业务结论。

已落地的工程处理

训练依赖被拆到独立依赖组,推理环境不必安装完整的 PyTorch 训练栈。频域服务使用有界 LRU 缓存;模型会话开启图优化,并有空闲卸载逻辑。这些机制已经存在于代码中,但本文没有实测它们带来的速度或内存收益。

训练入口默认先冻结骨干,再解冻末尾部分阶段,结合 Focal Loss、标签平滑与 EMA。更重要的是,训练生成候选 checkpoint,不直接覆盖正式模型;validation 负责选优,Canary 用于拦截已知回归。将“训练结束”和“允许发布”分开,能减少一次实验意外改变现行推理行为的风险。

仍需补齐的证据

当前还不能把低置信度输出的 unknown 称为成熟的开放集识别。独立 challenge、真实未知分布样本和采集组隔离仍需要完善;阈值也应在独立校准集上选择,而不是看完最终评估结果后反复调整。

下一步值得优先做的是端到端评估:固定图片来源和划分,比较模型概率、拒绝结果与人工复核负担,再考虑发布。候选模型不等于已上线模型,代码机制也不等于性能承诺。

实现线索

核心结构见 trainer/model.py,服务决策见 inference/predictor.py。EfficientNet、PyTorch、timm 与 ONNX Runtime 均为第三方基础能力;这里记录的是组合建模与推理工程实践。本文依据源码整理,未执行训练或性能测试。



上一篇
小智 ESP32 扩展笔记:语音链路与 GPIO 之间还有什么
下一篇
DS 电商工程笔记:连接池、SKU 购物车与数据库迁移