计算机视觉知识点-答题卡识别

news/2024/11/16 6:34:39/

 

         之前跟同事聊过答题卡识别的原理,自己调研了一下,高考那种答题卡是通过一个专门的答题卡阅读器进行识别的,采用红外线扫描答题卡,被涂过2B碳的区域会被定位到,再加上一些矫正逻辑就能试下判卷的功能.这种方法的准确度很高.淘宝上查了下光标机的误码率是0.9999999(7个9).见下图.

准确率高的离谱,机器长这个样子

这台机器的价格是15000, 有些小贵.  如果我想用简单的视觉方法做这个任务,不用外红设备,我应该怎么做呢.是不是用万能的yolo来做, 检测方形或者圆形的黑点行吗?这个方案当然可以,但是比较费劲,且效果不一定好.

我今天要说的是采用传统的计算机视觉的方法来做,几行代码就能达到99%的准确率,虽然没有光标机的准确率高,但是我们只是玩一玩.我参考了这个这篇博客, 博主的名字叫Adrian, Adian的博客专注计算机视觉,推荐大家看看.

传统的方法大概有着几个步骤:

1 检测到答题纸的位置, 如下图

2 进行拉伸变化,把答题纸拉成矩形

3 检测黑色的区域和白色的区域

4 答案判定.

下面是一个python实现

# import the necessary packages
from imutils.perspective import four_point_transform
from imutils import contours
import numpy as np
import argparse
import imutils
import cv2
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default='image.jpg',help="path to the input image")
args = vars(ap.parse_args())
# define the answer key which maps the question number
# to the correct answer
ANSWER_KEY = {0: 1, 1: 4, 2: 0, 3: 3, 4: 1}# load the image, convert it to grayscale, blur it
# slightly, then find edges
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 75, 200)# find contours in the edge map, then initialize
# the contour that corresponds to the document
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
docCnt = None
# ensure that at least one contour was found
if len(cnts) > 0:# sort the contours according to their size in# descending ordercnts = sorted(cnts, key=cv2.contourArea, reverse=True)# loop over the sorted contoursfor c in cnts:# approximate the contourperi = cv2.arcLength(c, True)approx = cv2.approxPolyDP(c, 0.02 * peri, True)# if our approximated contour has four points,# then we can assume we have found the paperif len(approx) == 4:docCnt = approxbreak# apply a four point perspective transform to both the
# original image and grayscale image to obtain a top-down
# birds eye view of the paper
paper = four_point_transform(image, docCnt.reshape(4, 2))
warped = four_point_transform(gray, docCnt.reshape(4, 2))# apply Otsu's thresholding method to binarize the warped
# piece of paper
thresh = cv2.threshold(warped, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]# find contours in the thresholded image, then initialize
# the list of contours that correspond to questions
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
questionCnts = []
# loop over the contours
for c in cnts:# compute the bounding box of the contour, then use the# bounding box to derive the aspect ratio(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# in order to label the contour as a question, region# should be sufficiently wide, sufficiently tall, and# have an aspect ratio approximately equal to 1if w >= 20 and h >= 20 and ar >= 0.9 and ar <= 1.1:questionCnts.append(c)# sort the question contours top-to-bottom, then initialize
# the total number of correct answers
questionCnts = contours.sort_contours(questionCnts,method="top-to-bottom")[0]
correct = 0
# each question has 5 possible answers, to loop over the
# question in batches of 5
for (q, i) in enumerate(np.arange(0, len(questionCnts), 5)):# sort the contours for the current question from# left to right, then initialize the index of the# bubbled answercnts = contours.sort_contours(questionCnts[i:i + 5])[0]bubbled = None# loop over the sorted contoursfor (j, c) in enumerate(cnts):# construct a mask that reveals only the current# "bubble" for the questionmask = np.zeros(thresh.shape, dtype="uint8")cv2.drawContours(mask, [c], -1, 255, -1)# apply the mask to the thresholded image, then# count the number of non-zero pixels in the# bubble areamask = cv2.bitwise_and(thresh, thresh, mask=mask)total = cv2.countNonZero(mask)# if the current total has a larger number of total# non-zero pixels, then we are examining the currently# bubbled-in answerif bubbled is None or total > bubbled[0]:bubbled = (total, j)# initialize the contour color and the index of the# *correct* answercolor = (0, 0, 255)k = ANSWER_KEY[q]# check to see if the bubbled answer is correctif k == bubbled[1]:color = (0, 255, 0)correct += 1# draw the outline of the correct answer on the testcv2.drawContours(paper, [cnts[k]], -1, color, 3)# grab the test taker
score = (correct / 5.0) * 100
print("[INFO] score: {:.2f}%".format(score))
cv2.putText(paper, "{:.2f}%".format(score), (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
cv2.imshow("Original", image)
cv2.imshow("Exam", paper)
cv2.waitKey(0)

测试图片

代码运行方法:

python test.py --image images/test.jpg

需要注意的事:

1 为什么不用圆检测?

圆检测代码有些复杂,而且要是涂抹的不是圆,或者不像圆该就难办了.

2 如何扩展成多选题?

修改是否被涂黑的判定逻辑就可以.

传统的计算机视觉是不是很好玩,传统的计算机视觉算法在一些限定场景下,效果还是不错的,比如室内光照恒定的情况,相机角度固定的情况.

感慨:

刚才看了下,我的上一篇博客还是在2015年,5年过去了,物是人非啊.2015年的时候我换了一个城市工作,压力很大,几年来,有顺心的事,也有烦心的事,不过总体还不错,祝福一下自己.

最后的话:

我是一个工作10年的程序员,工作中经常会遇到需要查一些关键技术,但是很多技术名词的介绍都写的很繁琐,为什么没有一个简单的/5分钟能说清楚的博客呢. 我打算有空就写写这种风格的指南文档.CSDN上搜蓝色的杯子, 没事多留言,指出我写的不对的地方,写的排版风格之类的问题,让我们一起爱智求真吧.wisdomfriend@126.com是我的邮箱,也可以给我邮箱留言.

 


http://www.ppmy.cn/news/475252.html

相关文章

opencv项目实践一(答题卡识别)

答题卡素材图片 思路 读入图片&#xff0c;做一些预处理工作。进行轮廓检测&#xff0c;然后找到该图片最大的轮廓&#xff0c;就是答题卡部分。进行透视变换&#xff0c;以去除除答题卡外的多于部分&#xff0c;并且可以对答题卡进行校正。再次检测轮廓&#xff0c;定位每个…

毕业设计之 ---基于机器视觉的答题卡识别

简介 今天我们来介绍一个与机器视觉相关的毕业设计 基于机器视觉的答题卡识别系统 多说一句, 现在越来越多的学校以及导师选题偏向于算法类, 这几年往往做web系统的同学很难通过答辩, 仔细一想这也在情理之中, 毕业设计是大学四年技术水平的体现, 只做出个XXX管理系统未免太…

【计算机网络基础】第2章 习题

文章目录 选择题 选择题 下列说法正确的是( D ) A. 信道与通信电路类似&#xff0c;一条可通信的电路往往包含含一个信道 B. 调制是指把模拟数据转换为数字信号的过程 C. 信息传输速率是指通信信道上每秒传输的码元数 D. 在数值上&#xff0c;波特率等于比特率与每符号所含的比…

用于深度学习的硬件配置列表

自己2021年配制的一台深度学习机子&#xff0c;体验是水冷没必要&#xff08;主要是安装费劲&#xff09;。 注意电源功率一定要够&#xff0c;不然带不动显卡&#xff0c;最好是1000w左右。 1 处理器&#xff1a; 英特尔&#xff08;Intel&#xff09;i9-10900K 10核20线程 …

3900x做服务器性能怎么样,AMD Ryzen 9 3900X评测:向消费级性能王者宝座进发

原标题:AMD Ryzen 9 3900X评测:向消费级性能王者宝座进发 5月27日,AMD在台北电脑展2019上正式发布了锐龙三代处理器,最先发布的有R7 3700X、R7 3800X和R9 3900X,与芯处理器同期发布的还有X570芯片组,X570平台同样支持AM4插槽,支持第一代部分、第二代及第三代锐龙处理器。…

amd插帧技术如何开启_不要浪费那块屏幕,联想小新13 Pro AMD锐龙标压版视频插帧设置...

如果说AMD显卡有什么不错的地方,个人觉得视频补帧这个算是一个。什么是视频补帧?简简单的说,就是提升视频帧率。平时我们看的视频都是24帧的居多,而AMD视频补帧后可以达到60帧! 最近的真香机联想小新13 Pro锐龙标压版,有人说相比Intel版缩水了WIFI 6,没有那么香了,不过…

幽灵压力测试软件,玩机宝典:AMD Ryzen 2700X 锐龙处理器 原装幽灵风扇猫扇 风冷散热器 实际对比测试 参考报告...

前言 AMD Ryzen 锐龙系列处理的发布,确实引领了桌面 PC 多核多线的发展,且不说和 Intel 8700K 对比怎么样,至少现在能在同等的价格之上,用上更多的核心更多的线程,如果没有 Ryzen 的话,估计牙膏厂 4 核 8 线程还能玩几年,所以还是有必要支持一下农企。平民 U 靠它背锅、…

教你如何安装windows11

前言&#xff1a; 本次不需要 PE 系统&#xff01;&#xff01;&#xff01; 要求&#xff08;最好不要越级&#xff0c;不然电脑会有点卡&#xff09;&#xff1a; CPU&#xff1a;1GHz或更快&#xff0c;在兼容的64位处理器或片上系统(SoC)上具有两个或更多内核。对于Inte…