书名:计算机视觉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个选项按序号进行从左到右排序的结果。










网友评论