基于OpenCV的答题卡生成及批阅分析系统

2020-12-01 03:17韦溢辉刘汉英
电脑知识与技术 2020年29期

韦溢辉 刘汉英

摘要:为降低阅卷的人力成本,提高考试情况分析的准确率和效率,对答题卡模板生成以及答题卡识别的算法进行研究和设计。实现动态设置答题卡信息,用word文档形式生成答题卡模板,以图片形式读入实物答题卡,通过图像识别获取答题卡填涂内容,将识别结果与设定的答案信息进行比对,得出考试结果。系统运用OpenCV计算机视觉库对答题卡图片进行灰度化、降噪、模板匹配、透视变换、二值化等一系列图像处理,最终实现答题卡模板生成以及答题卡识别。

关键词:答题卡生成;答题卡识别;OpenCV图像处理;模板匹配

中图分类号:TP391.41 文献标识码:A

文章编号:1009-3044(2020)29-0023-05

1 背景

网上阅卷系统已经应用于中考、高考和国考等大规模考试,然而在复杂环境下的中小规模考试如月考和测试等,该系统并未得到广泛应用,基本上仍在进行手工阅卷[1]。本文以桂林理工大学的答题卡样式为例,设计一种可以根据使用者要求生成答题卡兼阅卷并对考试情况进行分析的软件,最大限度降低成本和軟件对设备的要求,如答题卡打印纸张采用普通A4纸即可,使用方式尽可能简单,以减轻教师的工作负担。

2 系统分析

答题卡生成与批阅分析系统可以依照使用者对答题卡信息、客观题题型和题数的设置生成相应的答题卡模板并导出word文档,提供答题卡批量识别功能,根据使用者预设的答案数据得出答题卡的填涂结果,并根据预设的知识点类型,统计每个知识点和每道题的得分率。

3 系统设计

3.1 系统功能设计

本系统的整体功能图如图1所示。

3.1.1新建答题卡模板

在新建答题卡模板的功能里,使用者可以自定义答题卡的基本信息,如题目数量、题目选项数量、题目分值、知识点数量等;根据使用者的设置,生成相应数量的文本框等控件让用户定义知识点、答案等,最后,以Word文档形式生成相应信息、题量的答题卡模板,以供使用者打印。

3.1.2已存答题卡模板

在已存答题卡的页面,显示使用者已创建的所有答题卡模板,可对答题卡模板进行“批量识别”“导出”“删除”等操作。

1)实现批量识别实物答题卡,将需要识别的答题卡单独拍照,然后全部导人程序进行识别,记录答题卡识别结果。

2)实现答题卡模板导出功能,使用者可以重复导出答题卡。

3)实现删除答题卡模板功能,使用者可以随时删除不需要的答题卡模板。

4)把实物答题卡识别结果与使用者定义的答案数据进行比较、判断,并输出每张实物答题卡的得分和每道题的正确率以及每个知识点的得分率。

3.2 标准答题卡模板设计

本系统所设答题卡标准模板如图2所示,图中黑色圆块作为整体定位锚点,最下边和最右边的黑色矩形作为学号区域和答题区的定位锚点,代表题目选项和学号选项位置的纵坐标和横坐标。将答题卡模板生成时需要插入内容的区域添加为书签。

4 系统实现

4.1 答题卡模板生成的实现

创建答题卡模板的流程如图3所示。

4.1.1 题目数量溢出判断

判断题目数量n是否超出限制,即题目数量是否在答题卡模板的题目容量范围。根据答题卡标准模板的设计,用于插入题目选项内容的区域共23行、19列,在每一行里,题号占一列,每个选项占一列,两道题间的间距占一列,所以每道题所占列数为选项数量s+2,特殊的,每行最后一题无须留出与下一题的

4.2 答题卡识别的实现

答题卡识别,是把答题卡以照片形式导人,通过对图片的一系列处理如转换灰度图、降噪、模板匹配、透视变换、区域投影、膨胀腐蚀、阈值判定等,从而得出答题卡的识别结果,再与标准答案数据比较,进行结果分析[2]。答题卡识别流程如图4所示。

4.2.1 模板匹配

根据答题卡模板的设计规则,把答题卡分割成左上、左下、右上、右下四个相等大小的区域时,每个区域上必然有且只有一个黑色圆点,分别对4个区域进行模板匹配,就可以得出4个整体定位锚点的坐标。在此以左上角的区域为例进行介绍。

在完成了对图像的灰度化、高斯滤波降噪、二值化后,进行模板匹配,算法主要流程如图5所示。

1) OpenCV提供模板匹配函数matchTemplate匹配模板块和输入图像[3],图6(a)是左上区域原始图像,获得匹配结果图像,越亮的点匹配度越高,左上区域模板匹配结果如图6(b)所小。

2)归一化是把数据经过处理后限制在需要的一定范围内,使得数据之间对比性明显[4]。OpenCV提供函数normalize进行归一化处理,图7为对模板匹配结果做归一化处理。

3)OpenCV提供函数minMaxLoc在给定矩阵中获取最大和最小值(包括它们的位置[5]。通过该函数可得匹配度最高的点的坐标,再经过计算得出该点在原图的坐标。

实现模板匹配获取4个整体定位锚点坐标的主要伪代码为[6]:

void getlmageTag(Mat匹配原图,Mat原图局部图片,Point2f坐标容器[])

f double宽}匹配原图.rows;

double长}匹配原图.cols;

double tmpLoc[4][4]={{0, 0},

{cols/2,0),{0,rows/2},

(cols/2,rows/2)};

Mat tmplmg[4]; //区域:0左上,1右上,2左下,3右下

Mat reslmg;

//匹配结果图

double minVal, maxVal;//最小,大匹配值

Point minLoc, maxLoc;//最小,大匹配值坐标

for (inti=0;i<4;i++)

{ tmplmgfil一匹配原图(Rect(tmpLoc[i] [0], tmpLoc[i] [1],cols/2,rows/2》;

matchTemplate(tmplmg[i],原图局部图片,reslmg,5);

normalize(reslmg, reslmg,0,l,NORM_MINMAX, -1,Mat0);

minMaxLoc(reslmg, &minVal, &maxVal, &minLoc, &max-Loc, Mat0);

坐标容器[i]= Point(maxLoc.x+ tmpLoc[i][O],maxLoc.y+tmp-LocLilIID;))

4.2.2透视变换

透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Map-ping)[7]。

透视变换的数学公式为:

OpenCV提供getPerspectiveTransform函数和warpPerspec-tive函数进行透视变换[8]。getPerspectiveTransform根据答题卡标准模板中4个整体定位锚点的坐标与前文模板匹配所得到的4个坐标计算出透视变换矩阵,warpPerspective根据所得透视变换矩阵对图片执行透视变换。透视变换效果如图8所示。

4.2.3区域投影计算

学号选项和答案选项的定位,是通过答题底部和最右侧的黑色矩形来确定坐标。

投影计算的思路是计算区域中每一行或每一列非零像素的数量,再通过判断阈值和区域连续确定每个黑色矩形的起始坐标[9]。

区域投影计算流程如图9所示。

以對底部黑色矩形区域的处理为例,根据模板匹配得到的整体定位锚点坐标,对底部黑色矩形区域进行裁剪。

为了方便计算像素灰度值,须将图片处理成只有零(黑色)和非零值(白色),可以通过图像二值化的方法实现。图像二值化就是将图像上的像素点的灰度值设置为两个值,一般为0,255或者指定的某个值,这样将使整个图像呈现出明显的黑白效果,从而能凸显出目标的轮廓[10]。

OpenCV提供了countNonZero函数获取非零像素点数,而需要进行识别的是黑色矩形(灰度值为0),所以先将图像使用大津法OTSU进行二值化,凸显黑色矩形区域。

再将图像用反二进制阈值法THRESH BINARY INV进行二值化,达到置目标区域灰度值非零,效果如图10所示。

对二值化处理后的图像以列为单位进行遍历,通过count-NonZero得出每一列的非零像素点数,并按顺序记录到容器,然后遍历容器里的数据,相邻两个数据做比较,设差异阈值为10,如两个数据存在差异,则视此处为边界,并记录数据。

实现投影计算的主要伪代码为[9]:

void getBordLocation (Mat源图片,vector&上沿坐标容器,vector&下沿坐标容器,int排列类型,int间距值)

{

Mat原图片←源图片.clone();

vector像素值记录容器;

int干扰线条最大宽度←10;//线条宽度影响

if0==排列类型then

{

fori一0to原图片列数

Mat单列数据←原图片.col(i);

int非零像素数量←countNonZero(单列数据);

像素值记录容器.push_back(非零像素数量);

else f

fori←0to原图片行数

{

Mat单行数据←原图片.row(i);

int非零像素数量←countNonZero(单行数据);

像素值记录容器.push_back(非零像素数量);

}

//整形,去除长度小于gap的零的空洞

if像素值记录容器.size0<=间距值then retum;

for i←0 to像素值记录容器.size0 间距值

{if像素值记录容器[i]>=干扰线条最大宽度&&像素值记录容器[i+间距值】>=干扰线条最大宽度then

{

f'or j ←i to i+间距值

{

像素值记录容器[i]=干扰线条最大宽度;

}

i=i+间距值-1;

}

//记录上下沿

for i←1 to像素值记录容器.size0

{

if(像素值记录容器[i一1]<干扰线条最大宽度&&像素值记录容器[i]>=干扰线条最大宽度)

上沿坐标容器.push_back(i);

if(像素值记录容器[i一1]>=干扰线条最大宽度&&像素值记录容器[i]<干扰线条最大宽度)

下沿坐标容器.push_back(i);)

if上沿坐标容器.size0<下沿坐标容器.sizeo then

上沿坐标容器.insert(上沿坐标容器.begin0,0);

}

4.2.4比较阈值判断是否填涂

经过对图片的一系列处理以及锚点坐标的获取,可以找到选项所在的区域,并判断是否填涂。要从答题卡获得的有学号信息和作答信息,在进行判断之前先把透视变换后的图片二值化,然后对图像进行膨胀和腐蚀,可以更进一步降噪,凸显目标区域[10]。如图11所示。

对于判断是否填涂所用阈值,规定填涂区域大于黑色矩形尺寸的1/4时即视为填涂。

5 系统测试

软件开发过程中对软件进行测试是必要的,在软件开发过程中需要进行多次测试,查明系统中的bug,然后分析和解决问题,以便最大限度地改善软件。

5.1答题卡模板生成测试

在答题卡模板的生成中,影响题目排序的关键数据是单选题数量、单选题选项数量、多选题数量、多选题选项数量、判断题数量,在不计较其他输入的情况下用表1的数据进行答题卡模板生成测试。测试效果显示,答题卡模板生成结果与理论预测结果一致。

5.2 答题卡识别测试

本系统总共进行了46次答题卡识别的实验,其中有37次完全识别;5次遗漏识别,原因是填涂模糊;4次无法识别,原因是照片阴影太重;0次误判识别,识别率80.4%。答题卡识别完成后会给出分析结果,可以根据设置的数据来验证结果是否正确,在此列举其中一次试验结果。

表2是测试答题卡预测结果數据,图12(a)是答题卡,图12(b)是答题卡识别效果,图13是答题卡识别分析结果图,其显示结果与表2测试答题卡预测结果数据表的相应数据完全一致,且在识别过程中对填涂区域的识别也非常准确。

6 结束语

本系统实现了用户自定义生成答题卡Word模板,通过对图片的一系列处理来识别答题卡,并对识别结果进行统计分析。由于是以拍照的形式获取答题卡图片,所以照片的完整性、清晰度越高,识别的准确率就越高。因此,在答题卡损坏、模糊的情况下,识别结果出错是难以避免的。抛开这些因素,系统生成答题卡方便,可以识别答题卡以及分析考试情况,能够极大程度上提高工作效率和准确率。

参考文献:

[1]孟超.网上阅卷系统中答题卡模板自动生成技术研究[D].长沙:湖南师范大学,2013.

[2]张站,刘政怡,吴建国,等.基于图像识别的阅卷系统的设计与实现[J].微型机与应用,2011,30(4):44-47.

[3] Laghrib A,Ezzaki M,El Rhabi M,et aI.Simultaneous deconvolu-tion and denoising using a second order variational approachapplied to image super resolution[J].Computer Vision and Im-age Understanding,2018,168:50-63.

[4]陈博华,戴少鹏.基于OpenCV的图像处理方法[J].电子技术与软件工程,2015(19):125.

[5]李华琛,基于opencv图像边缘检测技术[J].数字技术与应用,2016(11):40,42.

[6]唐良,何伟,秦波,等.一种基于OpenCV和MFC的图像输出方法[J].怀化学院学报,2018,37(5):61-65.

[7]刘培军,马明栋,王得玉.基于OpenCV图像处理系统的开发与实现[J].计算机技术与发展,2019,29(3):127-131.

[8]软件开发技术联盟.visuaIC++开发实例大全(基础卷)[M].北京:清华大学出版社,2016_

[9]软件开发技术联盟.Visual C++开发实例大全(提高卷)[M],北京:清华大学出版社,2016.

[10]望熙荣,望熙贵.OpenCV和Visual Studio图像识别应用开发[M].李强,译.北京:人民邮电出版社.2017.

【通联编辑:谢媛媛】

作者简介:韦溢辉(1996-),学士,主要研究方向为软件开发;刘汉英,高级实验师,硕士,主要研究方向为数字图像处理。