美文网首页古今中外文史赏析
整张答题卡识别原理(将选项按照题目分组2)

整张答题卡识别原理(将选项按照题目分组2)

作者: 大龙10 | 来源:发表于2023-11-17 14:12 被阅读0次

书名:计算机视觉40例从入门到深度学习:OpenCV-Python
作者:李立宗
出版社:电子工业出版社
出版时间:2022-07-01
ISBN:9787121436857


第9章 答题卡识别

9.2 整张答题卡识别原理

9.2.4 将选项按照题目分组

1、规则排序

  • 在上节排序的基础上,还需要将每道题目的4个选项按照从左到右的顺序排列,确保每道题目各选项遵循如下规则:

    • A选项序号为0。
    • B选项序号为1。
    • C选项序号为2。
    • D选项序号为3。
  • 在具体实现中,根据各选项的坐标值,实现各选项按从左到右顺序排列。

2、程序


import cv2
import numpy as np

thresh =  cv2.imread("d:\\OpenCVpic\\thresh.bmp",-1)  
# cv2.imshow("thresh", thresh)

cnts, hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print("共找到各种轮廓",len(cnts), "个")

# =======构造载体=======
# thresh:在该图像内显示选项无序时的序号
# thresh 是灰度图像,将其转换至色彩空间是为了能够显示彩色序号
threshColor=cv2.cvtColor(thresh,cv2.COLOR_GRAY2BGR)
# result:在该图像内显示选项序号调整后的序号
result=threshColor.copy()


#===========用于存储筛选出的选项====
options =[]
font = cv2.FONT_HERSHEY_SIMPLEX
for (i,ci) in enumerate(cnts):
    
    #获取轮廓的矩形包围框
    x,y, w, h = cv2.boundingRect(ci)
    #计算纵横比
    ar = w / float(h)
    # 将满足长度、宽度大于 24 像素且纵横比介于[0.7,1.3]的轮廓加入 options 
    if w >= 24 and h>= 24 and ar >= 0.7 and ar <= 1.4:
        options.append(ci)
        #绘制序号
        cv2.putText(threshColor,str(i), (x-1,y-5),font,0.5,(0,0,255),2)

cv2.imshow("thresh", threshColor)
# 需要注意的是,此时得到了很多选项的轮廓,但是它们在 options 中是无规则存放的
print("共找到选项",len(options), "个")

# =====将找到的所有选项轮廓绘制出来==
color = (0,0,255) # 红色
cv2.drawContours(threshColor, options,-1, color, 2)

# cv2.imshow("threshColor",threshColor)


# ==将轮廓按照从上到下的顺序排列===
boundingBoxes = [cv2.boundingRect(c) for c in options]
(options, boundingBoxes) = zip(*sorted(zip(options,boundingBoxes),key=lambda b:b[1][1],reverse=False))

     
# =========将道题目的4个选项筛选出来=====
for (tn,i) in enumerate(np.arange(0,len(options), 4)):
    # 需要注意的是,取出的 4 个轮廓,对应某道题目的 4 个选项
    #这4个选项的存放是无序的
    #将轮廓按照坐标值实现自左向右顺次存放
    # 将选项 A、选项 B、选项 C、选项 D 按照坐标值顺次存放
    boundingBoxes =[cv2.boundingRect(c) for c in options[i:i + 4]]
    (cnts,boundingBoxes)= zip(*sorted(zip(options[i:i + 4], boundingBoxes),key=lambda x:x[1][0], reverse=False))     
    # 构造图像 image 用显示每道题目的4个选项
    image = np.zeros(threshColor.shape, dtype="uint8")
    #针对每个选项单独处理
    for (n,ni) in enumerate(cnts):
        x,y, w, h = cv2.boundingRect(ni)
        cv2.drawContours(image, [ni],-1, (255,255,255), -1)
        cv2.putText(image,str(n), (x+10,y-5),font,0.5,(0,0,255),2)
        
        #显示每道题目的 4个选项及对应序号
        cv2.imshow("result"+str(tn),image)     

cv2.waitKey()
cv2.destroyAllWindows()

图9-15 运行结果

3、结果分析

运行上述程序,输出结果如图9-15所示。从图9-15中可以看出,图9-15(a)是在提取的各个选项上绘制的原始序号,图9-15(b)~图9-15(f)是提取的各个不同题目的4个选项按序号进行从左到右排序的结果。

相关文章

  • SAT数学常见五大错误总结

    一、手残式错误 1. 做对但选错了选项 2. 选对选项但涂错了答题卡 3. 涂串答题卡 4. 应用题2/3涂成了3...

  • Rust语言编程实例100题-050

    Rust语言编程实例100题-050 题目:在 Rust 中,模块 Module 用于将函数或结构体按照功能分组。...

  • 打造高性能 Kafka队列

    一、原理简述 【1】Producer 将消息进行分组分别发送到对应 leader节点;【2】Leader将消息写入...

  • 分组密码DES

    分组密码的原理 DES是分组密码,分组密码将消息进行等长分组,使用同一密钥对每个分组进行加密。 DES算法 DES...

  • 70、Java API初步使用_员工管理案例:基于Java对员工

    需求:(1)首先按照country国家来进行分组(2)然后在每个country分组内,再按照入职年限进行分组(3)...

  • sql题

    题目描述 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。 CRE...

  • SQL进阶部分一

    分组查询 什么是分组查询 ​ 将查询结果按照1个或多个字段进行分组,字段值相同的为一组 分组使用 ​ ...

  • 排序(二):希尔排序、归并排序、快速排序

    希尔排序原理:1.选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组。2.对分好的每一组进行插入排序...

  • ThreeJS 案例-将2d元素附加到3d物体上

    原理:利用 CSS2DObject 将二维物体转为 threejs 可以识别的 3d 物品,然后利用 CSS2D...

  • 《金字塔原理》--MECE手绘

    为什么使用金字塔原理? 1,交流方便,必须将思想归类分组(观点,结论,要点,论点,论据,建议,行动,步骤) 2,将...

网友评论

    本文标题:整张答题卡识别原理(将选项按照题目分组2)

    本文链接:https://www.haomeiwen.com/subject/vywlwdtx.html