17.答题卡识别判卷

目录

1  项目介绍

2  代码分析

2.1  导入库

2.2  设置参数

2.3  设置正确答案

2.4  定义找到四个角点的函数

2.5  定义变换函数

2.6  定义 sort_contours()

2.7  定义展示函数 cv_show()

2.8  图像滤波

2.9  边缘检测

2.10  整体轮廓检测

2.11  处理轮廓

2.12  透视变换

2.13  二值处理

2.14  寻找轮廓并画出来

2.15  提取答题卡上的答案

2.16  对比正确答案

2.17  计算其余信息

3  新了解的方法


1  项目介绍

现在我有一张写好答案的答题卡并且我有一组答案

为我们把正确的结果标出来,然后得出正确率

2  代码分析

2.1  导入库

2.2  设置参数

2.3  设置正确答案

第0行的答案的B,第1行的答案是E,第2行的答案是A,第3行的答案是D,第4行的答案是B

2.4  定义找到四个角点的函数

  • 我觉得这个并不是很科学,我在该专栏的 11.提取图像内容区域 做过更改,我们可以使用我改过的函数

2.5  定义变换函数

在该专栏的 11.提取图像内容区域 有讲过,就不赘述了

2.6  定义 sort_contours()

这个是排序用的 在该专栏的 11.银行卡号识别 有讲过

2.7  定义展示函数 cv_show()

2.8  图像滤波

读取图片后复制一张,然后将原图转为灰度图,之后对其进行布尔滤波,然后展示出来

2.9  边缘检测

2.10  整体轮廓检测

2.11  处理轮廓

首先我们定义一个docCnt,这个变量用来存放我们轮廓的内容,之后如果我们检测到了轮廓就进入分支,进入分支后将轮廓按面积大小排序,之后遍历排序好的每一个轮廓对其进行轮廓近似(将每一个轮廓搞成多边形,大概是这样的),如果我近似后的结果多余四边形就将该轮廓近似后的结果赋值给docCnt()

我们下面看一下近似前与近似后的轮廓

  • 近似前

  • 近似后

可以看出来是差不多的,我们后面的遍历与近似是为了让代码也能更好的匹配别的图像

我们看一下docCnt的内容

2.12  透视变换

刚刚我们得到的docCnt就是内容区域的轮廓,现在我们使用docCnt提取图像内容(进行透视变换),首先我么们把docCnt降一维变成(4,2),然后执行four_point_transform()提取图像内容

2.13  二值处理

处理之后复制一张处理过的图片

2.14  寻找轮廓并画出来

由于图像是二值化的图像所以我们看不出来是红色,我们现在把轮廓在image上画验证一下

  • 这个只是验证灰度图上画轮廓不显示红色,在刚刚灰度图中画的轮廓不是上图红色的样子

2.15  提取答题卡上的答案

  • 如果答题卡涂成一个圆,我们也可以用霍夫变换来检测圆,但如果涂的不像是一个圆就没有办法检测出来了,下面这个图右边可以检测出来,左边这个检测不出来

首先我们创建一个空的列表用于存储 答题卡上答案 的轮廓

遍历图中的所有轮廓,对轮廓进行矩形近似,之后算出矩形的宽高比ar,之后进入判定,如果宽>=20,高>=20,宽高比在0.9-1.1之间,我们将轮廓加入questionCnts,这样我们就能筛选出来所有圈的轮廓了

之后使用上面定义的sort_contours对轮廓进行从上到下排序

我们现在看一下questionCnts,很长我就只截取头和尾了

然后定义correct用于记录正确的个数

下面涉及到了np.arange()这个方法,我们举个例子

import numpy as np
a = np.arange(3)
print(a)
print(type(a))

a = np.arange(1,5)
print(a)
print(type(a))

a = np.arange(1,5,2)
print(a)
print(type(a))

上面是三种加入参数的方式

  • 直接写一个整形进去,这样就会生成一个内容为从0到n-1的numpy.ndarray
  • 写两个整形进去,这样会生成内容为从a到b的numpy.ndarray
  • 写三个整形进去,这样会生成内容为从a到b,步长为c的numpy.ndarray

回到我们的代码,我们此时做了一个循环

q是我们np.arange的结果从0到25,步长为5,q的取值范围为[0,5),i是enumerate给的序号,一共25个,所以i的取值范围为[0,25)

进入循环后,把每5个圆形轮廓归为一堆,并以默认的方法排序(从左到右)这样我们就得出了一行的圆形轮廓,然后将bubble置为none

然后我们再上面的循环中进入一个小循环,这个循环是遍历我们同一行的轮廓,我们先用enumerate()对同一行的轮廓进行标号

之后我们创建全0(黑)掩膜,大小与图像内容大小图片相同,之后在mask上把轮廓画出来,第一个-1是全部都画出来(由于是遍历的,所以只有一个),第二个-1是填充,把轮廓内的值都置为255(白色),然后展示出来

一共展示25次,我们展示一下前几次的什么样子的

然后我们使用mask对图自身做与运算,这样可以把选中的答案筛选出来,涂过的会比没涂过的非0值更多,之后我们使用检测出非零值个数,如果多就覆盖掉,少就下一轮,这样我们就选出来了一行中涂过的答案轮廓

2.16  对比正确答案

之后我们小循环就结束了,然后定义一个红颜色,之后把正确答案赋值给k

  • ANSWER_KEY 我们之前定义过,是内容为正确答案的字典

如果判断正确,我们将颜色改为绿色,然后correct(正确数量)+1

然后把该轮廓画出来

2.17  计算其余信息

score是答题卡的得分,对一个20分,然后终端显示出来,之后在图上画出来,然后展示原图与最终的结果进行对比

由于我们搞的是灰度图,所以颜色就显示不出来了

如果我们要把颜色搞出来我们应该把图像的颜色通道变为3条,首先在大循环前复制,然后转换

然后在img上画

在img上写

展示img

3  新了解的方法

np.arange() 生成内容为顺序整形的numpy.ndarray

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Suyuoa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值