http://blog.devtang.com/blog/2013/10/19/the-tech-detail-of-ape-client-2/
本文涉及的技术细节是:答题卡扫描算法。
问题描述
我们在调研用户需求的时候,发现有些用户很喜欢我们的产品,因为我们会根据用户对当前课程的知识点掌握情况,智能地给他出题。但是部分用户还是习惯在纸上做题,所以我们提供了试卷打印功能。
但是,用户如果在纸上答题,无法方便地将答案上传到我们的服务器上。如果我们没有了用户做题数据,就无法根据他的成绩,做针对性的推荐和分析。所以,我们想到一种办法:用户像传统考试那样,将答题结果填涂在答题卡上,然后我们提供一种用手机摄像头采集填涂结果的答题卡扫描算法,方便用户上传答题数据。
上图是一个我们试验用的答题卡,通过手机摄像头获取,从中可以看到,该答题卡有以下问题:
- 由于手机摄像头无法完全正对答题卡,拍照角度有偏曲,答题卡在拍照后并不是完全的矩形。
- 用户填涂区域可能并不饱满和完整。
- 答题纸边缘可能有用户的草稿或其它干扰识别的信息。
技术解决方案
我们尝试了多种识别方案,最终采用的方案如下:
- 图象预处理,压缩图像大小,转彩色图像为灰度图像
- 识别答题卡区域
- 图象纠偏
- 答案区域识别
该方案及相关算法细节我们还在申请专利,由于专利还在申请过程中,所以我们这次仅展示上述主要步骤的示例图片。等专利完全申请结束后,我会在此将算法细节公开。
上述主要步骤的示例图如下:
原始图
识别答题卡区域
图象纠偏
答案区域识别
答案已标注在图片每个题号的右边位置:
算法质量
算法正确率和召回率
我们用收集来的1000套样本数据对算法进行评测,最终结果是:扫描题目准确率达到99.67%,召回率达到99.14%。主要识别失败的样本是:页面严重扭曲弯折的答题卡。我们也在一直改进算法,希望能够给用户提供更加精准的扫描结果。
算法执行时间
我们觉得让用户直接对着答题卡用拍摄的方式动态识别,比先拍一张照片再识别的方式更加方便。所以我们对答题卡识别算法的执行时间进行了一系列优化,最终保证每次识别时间小于0.1秒,这样的识别时间非常快,基本上用户把手机摄像头对准答题卡,扫描结果就出来了。
算法的调试和移植
由于我们整个技术团队都使用Mac电脑进行开发,所以我们对于算法的调试都是在Mac平台上完成的,我使用了开源的图象处理库OpenCV,在搭建OpenCV环境时遇到一些问题,最终完成环境搭建后,我将相关的经验总结在博文《在MacOS和iOS系统中使用OpenCV》中。
由于算法需要同时应用在iOS和Android平台,所以我主要用C++语言实现算法。Xcode可以很好地支持Objective-C语言和C++语言混编,只需要将相关的源文件扩展名从.m改为.mm即可。而Android平台所采用的Java语言,也支持通过JNI的方式来调用C++的代码。这样就可以方便地将识别算法移植到手机中了。
没有评论:
发表评论