基于Android和OpenCV的答题卡识别软件

1. 软件介绍

设计目标是可以添加不同的考试,在不同考试下可以设置模板,包括题目数量、答题卡样式、每题分值以及每题答案;扫描结果按列表显示,并讲识别出的图片展示处理,点击列表项也可以弹出识别结果。

扫描答题卡可以从相机或者相册中选择。


2.识别原理介绍

以下主要介绍两个核心部分:获取答题区域和识别用户填涂选项。

2.1获取答题区域及矫正

2.1.1总体流程介绍

获取答题区域,首先要对原始的彩色图像进行预处理操作,包括转灰度图像、高斯模糊、边缘检测等,然后从得到的图像寻找轮廓,并对轮廓进行一定的筛选,接着求出答题卡矩形顶点的坐标,利用坐标进行透视变换从而得到答题区域。总体流程图如图所示。

2.1.2 图像预处理

在获取答题区域之前,需要对图片进行预处理。首先将用户输入的原始图像转化为灰度图像,以减少后续对图像处理的运算复杂度。然后使用高斯滤波(3*3)对图像去噪,再利用Sobel算子分别求出图像在X和Y方向上的梯度,将他们进行叠加以获取边缘。

在进行叠加时,对两个图像的叠加权重适当加大,否则可能导致边缘不够清晰使甚至断开寻找轮廓失败。权重设置为1,可以理解为X、Y方向的图像进行叠加,可以看到矩形的右边缘不太清晰,在图片质量差的情况下可能会发生断裂不完整,使后续查找矩形轮廓时失败。 权重设置为5,可以理解为将X、Y方向的图像进行5次叠加,原本不太清晰的边缘经过多次叠加后变得清晰。

权重设置为1


权重设置为5

在完成边缘检测后,可以看到图像还是存在很多细小的噪点,为了更好的提取出答题卡,对边缘检测后的图像进行二值化处理,结果如图所示,可以看到噪点很好的被去除了,图片显得更清晰了。

二值化的图像

在二值化之后,还对该图像进行了一次腐蚀操作(3*3),原因是后续获取矩形坐标时是通过多边形拟合的方式,在实际测试时发现若边缘存在一些噪点,拟合的时候可能会导致拟合不出四边形导致获取矩形顶点坐标失败。而通过一次腐蚀操作可以避免这种情况。因此在图像预处理的最后增加了一次腐蚀操作。最终获得的图像如图所示。

预处理后的图像

图像预处理的整体流程图如图所示。

图 3 6 图像预处理流程图

2.1.3 寻找轮廓及计算坐标

在图像预处理之后,我们可以得到一张拥有比较清晰的答题卡轮廓的图像,但图像中还有一些与答题区域无关的部分,例如纸张外的部分、纸张的其他部分,我们只需要答题卡矩形方框那一部分。这一节将找到答题卡矩形的四个顶点的坐标。

首先我们需要找到图像中的所有轮廓,正如前文所说,图像中具有许多无关的部分,我们需要设定一个条件来筛选我们需要的轮廓。针对答题卡在图像中的特点,本文设定的筛选条件时轮廓的长>原图片长的1/2,轮廓的宽>原图片宽的1/4,当然这个条件在某些情况下可能会发生误判,例如题目数量较少时,矩形的宽可能不能大于原图片宽的1/4,因此在这种情况下输入图片时尽量利用软件的裁剪功能使答题区域占大部分;另一种改进方法是在设置模板时,根据题目数量和答题卡类型,动态设置筛选条件,本文没有实现这种做法,但理论上是可以做到的。
识别结果如图 所示,将筛选出的轮廓用蓝色线画出。

图 识别出的矩形边框

在得到了答题卡矩形轮廓后,需要计算出四个顶点的坐标,并确定四个顶点的相对位置。
计算坐标采用的是多边形拟合的方式,利用approxPolyDP方法将该轮廓拟合成一个多边形,判断拟合的结果顶点是否为4,若为4则说明成功拟合了一个四边形,该四边形的四个顶点的坐标可以认为是答题卡矩形轮廓的坐标。

得到四个顶点坐标后,计算出四个顶点坐标的中心点. 通过比较每个点与中心点的x和y值来判断该顶点所在位置,例如A点x坐标小于O点x坐标,y坐标大于O点y坐标,则说明A点是左上顶点,其他点的确定同理。因此我们就获得了答题卡矩形轮廓四个顶点的坐标。

2.1.4 透视变换矫正图像

在获取答题卡的图片时,拍照角度很难保证刚好垂直纸张,导致会发生一定的倾斜,因此获得的答题卡区域有可能是倾斜甚至发生一定的形变的,我们需要对这种图片进行透视变换校正。

透视变换本质是将图像从一个平面投影到另一个平面,在这里就是将答题卡图像所在倾斜的平面投影到一个水平的平面中。我们知道了矩形四个顶点在倾斜平面的坐标,还需要四个在水平平面的坐标,将矩形的四个顶点投影到水平平面中,就可以得到校正后的图像。水平平面的坐标选取采用了轮廓的外接矩形的四个顶点坐标。
整个做法流程运行结果对比如图所示,可以看到成功提取出了答题区域和对该区域进行了校正,效果还不错。

图 原始图像

图 获取答题区域校正后图像

2.2 识别填涂答案

2.2.1 整体流程介绍

识别答题卡,判断一个选项是否被选中,有两个很重要的步骤,一是获得每道题每个选项的区域,例如某个范围内认定是第一题的A选项,另一个范围是第一题的B选项等;二是获得答题卡上被填涂的区域,就是用户实际涂写的区域;通过判断每个选项区域内用户涂写的部分占该区域的占比来判断该选项是否被选中。整体流程图如图所示,其中去噪和二值化与第三章类似,就不再赘述。

图 识别填涂答案整体流程

2.2.2 获取单个选项区域

因为本次答题卡设计每个选项采用的不是封闭的矩形,是“[ A ]”这样的结构,如果直接寻找轮廓会找到三个轮廓难以区分,因此可以先采取使用图像腐蚀和膨胀操作对其处理,具体实现有两种思路:

(1) 对图像进行膨胀操作,使每个选项的“[ ”、“A”、“]”三个部分变成一个部分,然后进行腐蚀操作,避免不同选项间连在一起。然后寻找所有的轮廓,理论上每一题应该能找到五个轮廓,题号加四个选项,对它们根据坐标进行排序从而就能够获取每个选项的区域。但是这种方式操作难度很大,在进行膨胀操作时不同选项间很容易存在粘连,再通过腐蚀去除粘连时,题号的区域很可能会变得很小甚至被消去,导致寻找轮廓时数量对不上,也难以过滤掉答题卡上的一些干扰区域。
如图所示,若腐蚀参数选的小,则很难分离出四个选项区域;若腐蚀参数选择过大,可能会导致序号区域被消去,或者选项三个部分没有达到我们的目的被膨胀成一块区域,同时对于答题卡上的一些干扰信息无法去除。

图 方法一
(2) 考虑到第一种方式很难去除选项中的粘连,那就考虑直接将选项膨胀参数调大,使四个选项变成同一个区域,再将该区域平均划分四部分,每部分对应一个选项。 本文中采取做法是先进行四次膨胀(5*1),然后进行一次腐蚀操作(1*5),最终效果如图 4 3所示,可以看到每题选项区域都被融合在一起,也能很好的区分题号和选项区域,以及过滤掉一些小的干扰。

图 方法二

获取到每道题选项区域后,还需要确定每个区域对应的题号,本文采取的策略是先对轮廓进行过滤,排除掉题号的轮廓区域、一些小的干扰项,之后按照轮廓左上顶点进行排序,排序策略是根据y值进行排序,若y相等或相差在10以内,则根据x值进行排序。Y值的排序策略意思是因为每个轮廓不一定y都相等,可能因为拍照角度会存在一定的误差,这里将y相差在10以内的轮廓都认为是同一行,从而对拍照角度有一定的容错率。

4.3 获取填涂区域
获取填涂区域比较好操作,只需要通过腐蚀去除或者削弱一些没有填涂的选项和序号,使它们满足不了识别为选项的条件,即它们在选项区域的占比达不到要求即可,不需要完全消除这些部分,否则可能导致填涂的答案也被腐蚀的比较小。对此,经过多次实验测试,本文选择的方式是进行一次腐蚀(5*5),得到的效果如图所示。
可以看到填涂的区域比较明显。若采取多次腐蚀或增大腐蚀参数,可以消去其他未填涂的选项,但是填涂的部分面积也会变小,采用这种方式已经足够区分填涂和未填涂的部分了。

图 填涂区域

2.2.3 识别填涂答案

通过上述步骤我们可以获取每题选项的区域获取和填涂的区域,因此识别选项是否被标记,只需要**计算出每个选项区域内白色像素点的个数占该区域总像素的比例,提前设定好一个阈值,超过这个值就认为该选项被填涂,即可识别出填涂的选项。**为直观看出效果,将第二节识别的轮廓画在识别出的填涂区域中,如图 所示。将轮廓四等分再统计四个区域的像素值即可实现选项的识别。

图 识别填涂答案

三、测试结果

测试用例图片说明:按照图片处理顺序如下
- src: 原图
- sobel: 用sobel算子进行边缘检测后的结果
- threshold: 二值化
- dilate: 对二值化图像进行腐蚀,排除边界的噪音,防止拟合矩形失败
- sheetArea: 对识别出的轮廓进行透视变换和裁剪,得到的答题卡区域
- select: 获取填涂的选项
- ansArea: 腐蚀图片,获取每一题选项区域。对该区域划分四部分,每部分即对应的四个选项
- rect:将识别出的每题的选项区域标出,不是必要的,用于观察结果。
- result:将识别出的填涂的选项标记在图片中

部分测试结果如下: 以下测试均识别成功

  1. 正常拍摄
  2. 图片部分倾斜
  3. 纸面弯曲
  4. 存在折痕

四、局限

对于答题卡矩形的识别中,对轮廓的筛选采用了固定的方式,即长宽分别超过原图的一定比例,若题目数量少的答题卡可能会无法满足而导致答题卡的矩形被过滤,最终无法识别。后续可以考虑根据题目数量采用动态的过滤条件,避免这种误判。此外,因为对图像处理过程是固定的,可能不使用于所有情况,例如放大、缩小超出一定范围则会无法识别,后续可考虑使用动态的处理方式,根据答题卡具体情况选择对图像处理方式(例如对图像腐蚀的次数等)。

此外,改软件存在兼容性的问题,生成图片时因为采用的是固定像素,在不同手机上可能显示会出问题(例如题号溢出到方框外),精力有限没有去继续研究这部分了,但是识别应该是一样的。

欢迎批评指正交流,若留言没看见可以加微信:aaaalulala

基于Android和OpenCV的答题卡识别软件相关推荐

  1. 用Python+OpenCV+PyQt开发的答题卡识别软件

    用Python+OpenCV+PyQt开发的答题卡识别软件 软件使用说明 软件设计思路 如何设置答案 界面风格 备注 这是一个可以识别定制答题卡的软件,它可以根据用户自定的答案来进行识别,校对正误并统 ...

  2. 基于MATLAB的答题卡识别软件设计

    基于 MATLAB 的答题卡识别软件设计 课题意义 随着教育技术的飞速发展,考试普遍使用答题卡来记录答案,采用计算机自动识别答案卡信息,计算考生的成绩,可以减少阅卷人的工作量.本文利用 Matlab ...

  3. Opencv之答题卡识别判卷

    项目要求 提供一张答题卡图像,通过图像处理识别出答题卡上每个题的选项,与正确答案对比,得出分数并写在答题卡上. 代码实现过程 1.引入需要的库 import numpy as np import cv ...

  4. 基于 Java 的答题卡识别系统

    这张答题卡想必伴随了大家的学生时代,不管是中考.高考.考研,都会用 2B 铅笔涂好卡上的红框框. 今天推荐一个基于 Spring MVC + OpenCV 的答题卡识别系统,OpenCV 是一个计算机 ...

  5. Java答题卡识别系统

    今天团长推荐的是一个基于 Spring MVC + OpenCV 的答题卡识别系统 效果展示 项目地址 https://github.com/ColorlibHQ/AdminLTE 如果觉得我的分享不 ...

  6. 基于MATLAB答题卡识别(GUI,论文)

    本课题为基于MATLAB的不变矩答题卡识别.可识别学号,学科,答案,并进行分数统计,以及判断是否及格.后台可设置标准excel答案.经过灰度变换形成灰度图像.二值化处理.图像滤波.边缘检测.hough ...

  7. 【答题卡识别】Hough变换答题卡识别【含Matlab源码 250期】

    ⛄一.获取代码方式 获取代码方式Q: 完整代码已上传我的资源:[答题卡识别]基于matlab Hough变换答题卡识别[含Matlab源码 250期] 获取代码方式2: 付费专栏图像处理(Matlab ...

  8. 基于 SpringMvc + OpenCV 实现的答题卡识别系统(附源码)

    点击关注公众号,实用技术文章及时了解 java_opencv 项目介绍 OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,它提供了一系列图像处理和计算机视觉方面很多通用算法.是研究图像 ...

  9. 基于 SpringMvc+OpenCV 实现的答题卡识别系统(附源码)

    java_opencv 项目介绍 OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,它提供了一系列图像处理和计算机视觉方面很多通用算法.是研究图像处理技术的一个很不错的工具.最初开始接 ...

最新文章

  1. 深蓝学院的深度学习理论与实践课程:第二章
  2. 前端面试-综合问题版
  3. 创建应用服务器连接客户端
  4. 某CTF比赛部分wp
  5. 机器学习中的范数规则化之(二)核范数与规则项参数选择以及RPCA
  6. mysql单向加密_MariaDB(Mysql)双向加密与单向加密 | 彬菌
  7. python 字典查询比列表快_为什么python字典要比列表快以及哈希查找解释。
  8. UIView动画设置
  9. 菜鸟也玩系统安装盘的集成(图文教程)
  10. python如何实现单例模式_用Python实现设计模式——单例模式
  11. 总结一些常用的C语言学习网站
  12. SpringBoot集成海康威视Linux版本
  13. matlab差分编码,差分编码FSK调制解调matlab源程序
  14. win10 SystemParametersInfo 设置屏保 不好使_火爆抖音的旋转时钟屏保,超酷超炫的...
  15. 嵌入式和单片机的区别到底在哪?
  16. c4d流体插件_C4D流体烟雾模拟插件TurbulenceFD C4D v1.0.1437支持R14R20
  17. DoS攻击服务器过程
  18. 鸿蒙Ability继承FractionAbility可以直接获取Fraction内的控件
  19. set的用法及短语_set的用法和例句
  20. 牛客小白月赛21 I I love you(dp的优化)

热门文章

  1. 读懂“人性”你会发现:高手毁掉一个人有多简单?只需要两个手段——“期望效应”,又称“罗森塔尔效应”、“皮格马利翁效应”
  2. mysql 数据操作类_MySql 数据操作类
  3. It’s Only Natural: An Excessively Deep Dive Into Natural Gradient Optimization
  4. c语言fscanf函数的用法,fscanf - C语言库函数
  5. nohup 后台运行
  6. java卡写入_写入SD卡的权限
  7. mysql io nio区别_Java NIO和IO的区别
  8. 男人读懂女人心必须知道6句话
  9. Unity 文字字体显示错误,全是小白快。
  10. java计算机毕业设计惠生活网站MyBatis+系统+LW文档+源码+调试部署