嗨害大家好鸭~我是小熊猫❤

随着现代图像处理和人工智能技术的快速发展,

不少学者尝试讲CV应用到教学领域,能够代替老师去阅卷

将老师从繁杂劳累的阅卷中解放出来,

从而进一步有效的推动教学质量上一个台阶。

传统的人工阅卷,工作繁琐,效率低下,

进度难以控制且容易出现试卷遗漏未改、登分失误等现象。

现代的“机器阅卷”,工作便捷、效率高、易操作,

只需要一个相机(手机),拍照即可获取成绩,

可以导入Excel表格便于存档管理。


下面我们从代码实现的角度来解释一下我们这个简易答题卡识别系统的工作原理。

第一步,导入工具包及一系列的预处理

import numpy as np
import argparse
import imutils
import cv2
# 设置参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default="test_01.png")
args = vars(ap.parse_args())
# 正确答案
ANSWER_KEY = {0: 1, 1: 4, 2: 0, 3: 3, 4: 1} #
def order_points(pts):# 一共4个坐标点rect = np.zeros((4, 2), dtype = "float32")# 按顺序找到对应坐标0,1,2,3分别是 左上,右上,右下,左下# 计算左上,右下s = pts.sum(axis = 1)rect[0] = pts[np.argmin(s)]rect[2] = pts[np.argmax(s)]# 计算右上和左下diff = np.diff(pts, axis = 1)rect[1] = pts[np.argmin(diff)]rect[3] = pts[np.argmax(diff)]return rectdef four_point_transform(image, pts):# 获取输入坐标点rect = order_points(pts)(tl, tr, br, bl) = rect# 计算输入的w和h值widthA = np.sqrt(((br[0]-bl[0])** 2) + ((br[1]-bl[1])**2))widthB = np.sqrt(((tr[0] -tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))maxWidth = max(int(widthA), int(widthB))heightA = np.sqrt(((tr[0]-br[0])**2)+((tr[1]-br[1])**2))heightB = np.sqrt(((tl[0]-bl[0])**2)+((tl[1]-bl[1])**2))maxHeight = max(int(heightA), int(heightB))# 变换后对应坐标位置dst = np.array([[0, 0],[maxWidth - 1, 0],[maxWidth - 1, maxHeight - 1],[0, maxHeight - 1]], dtype = "float32")# 计算变换矩阵M = cv2.getPerspectiveTransform(rect, dst)warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))return warped # 返回变换后结果def sort_contours(cnts, method="left-to-right"):reverse = Falsei = 0if method == "right-to-left" or method == "bottom-to-top":reverse = Trueif method == "top-to-bottom" or method == "bottom-to-top":i = 1boundingBoxes = [cv2.boundingRect(c) for c in cnts](cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),key=lambda b: b[1][i], reverse=reverse))return cnts, boundingBoxes
def cv_show(name,img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()image = cv2.imread(args["image"])
contours_img = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 75, 200)
# 轮廓检测
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[1]
cv2.drawContours(contours_img,cnts,-1,(0,0,255),3)
docCnt = None# 确保检测到了
if len(cnts) > 0:# 根据轮廓大小进行排序cnts = sorted(cnts, key=cv2.contourArea, reverse=True)for c in cnts: # 遍历每一个轮廓# 近似peri = cv2.arcLength(c, True)approx = cv2.approxPolyDP(c, 0.02 * peri, True)# 准备做透视变换if len(approx) == 4:docCnt = approxbreak
# 执行透视变换
warped = four_point_transform(gray, docCnt.reshape(4, 2))thresh = cv2.threshold(warped, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
thresh_Contours = thresh.copy()
# 找到每一个圆圈轮廓
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[1]
cv2.drawContours(thresh_Contours,cnts,-1,(0,0,255),3)
questionCnts = []
for c in cnts:# 遍历# 计算比例和大小(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# 根据实际情况指定标准if w >= 20 and h >= 20 and ar >= 0.9 and ar <= 1.1:questionCnts.append(c)
# 按照从上到下进行排序
questionCnts = sort_contours(questionCnts,method="top-to-bottom")[0]
correct = 0
# 每排有5个选项
for (q, i) in enumerate(np.arange(0, len(questionCnts), 5)):cnts = sort_contours(questionCnts[i:i + 5])[0]bubbled = Nonefor (j, c) in enumerate(cnts): # 遍历每一个结果# 使用mask来判断结果mask = np.zeros(thresh.shape, dtype="uint8")cv2.drawContours(mask, [c], -1, 255, -1) #-1表示填充# 通过计算非零点数量来算是否选择这个答案mask = cv2.bitwise_and(thresh, thresh, mask=mask)total = cv2.countNonZero(mask)# 通过阈值判断if bubbled is None or total > bubbled[0]:bubbled = (total, j)# 第二步,与正确答案进行对比color = (0, 0, 255)k = ANSWER_KEY[q]# 判断正确if k == bubbled[1]:color = (0, 255, 0)correct += 1cv2.drawContours(warped, [cnts[k]], -1, color, 3) #绘图#正确率的文本显示
score = (correct / 5.0) * 100
print("[INFO] score: {:.2f}%".format(score))
cv2.putText(warped, "{:.2f}%".format(score), (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
cv2.imshow("Input", image)
cv2.imshow("Output", warped)

最终实现的效果如下:



==没错我是在水文章~ ~ ~ ==

不知道要友友们爱看点啥~

我都不知道咋摸鱼啦

今天的文章就是这样啦

我是小熊猫,咱下篇文章再见啦(✿◡‿◡)

自动阅卷的原理很简单的,用python来简单解释一下工作原理❤相关推荐

  1. 听说你 ping 用的很 6 ?给我图解一下 ping 的工作原理!

    来自:小林coding 每日一句英语学习,每天进步一点点: 前言 在日常生活或工作中,我们在判断与对方网络是否畅通,使用的最多的莫过于 ping 命令了. "那你知道 ping 是如何工作的 ...

  2. 【java项目实践】具体解释Ajax工作原理以及实现异步验证username是否存在+源代码下载(java版)...

    一年前,从不知道Ajax是什么,伴随着不断的积累,到如今常常使用,逐渐有了深入的认识. 今天,假设想开发一个更加人性化,友好,无刷新,交互性更强的网页,那您的目标一定是Ajax. 介绍 在具体讨论Aj ...

  3. 均质机工作原理动画_3D动画演示:有刷直流电机的工作原理

    点上面蓝色字体直观学机械可长期订阅我们 法律顾问:赵建英律师 下面这张图是电机的分类,在看完这张图后,大家基本也就知道咱们今天说的有刷电机具体属于哪一类了. 下面这个是LearnEngineering ...

  4. 量子计算机工作原理如何解释,量子计算机工作原理

    量子计算机工作原理 量子计算机工作原理 当今的计算机厂商提供的强大计算处理能力仍不能满足 我们对运算速度和运算能力的渴求.1947 年,美国计算 机工程师霍华德·艾肯 (Howard Aiken) 曾 ...

  5. 电子计算机工作原理及设计思想为什么理论,动态偏振控制器的工作原理、系统设计及应用...

    1 引 言 偏振是量子光的一个重要和常用的性质.因此,在量子安全通信系统中,经常通过改变偏振态来进行编解码,而动态偏振控制器(DPC)作为一种改变输入光偏振态的光器件,直接参与传输数据的编解码,在量子 ...

  6. 如何根据原理图画封装_如何在短时间内,吃透三极管工作原理,开关导通和封装外形知识点?...

    一.了解三极管 三极管:是三个引脚的放大器件的统称:全称为半导体三极管,也称双极型晶体管.晶体三极管等:是电子电路的核心元件,具有电流放大作用,可通过放大微弱电信号:因此常被用作无触点开关. 二.组成 ...

  7. python简单成绩录入,python实现简单成绩录入系统

    学了一个多月的python,做了一个小程序:python实现简单成绩录入系统,实验一下 menu部分 from tkinter import*#这是一个python模块,python3中都有 impo ...

  8. python简单温度转换,python实现简单温度转换的方法

    本文实例讲述了python实现简单温度转换的方法.分享给大家供大家参考.具体分析如下: 这是一段简单的python代码,用户转换不同单位的温度,适合初学者参考 def c2f(t): return ( ...

  9. 动态磅是怎么原理_一看就懂的十种泵的工作原理动态图

    1.水环式真空泵动态原理图: 当水环式真空泵叶轮按图中顺时针方向旋转时,水被叶轮抛向四周,由于离心力的作用,水形成了一个决定于泵腔形状的近似于等厚度的封闭圆环. 水环的下部分内表面恰好与叶轮轮毂相切, ...

  10. 双时隙的工作原理_一文读懂跨阻放大器的工作原理

    跨阻放大器(TIA)是光学传感器(如光电二极管)的前端放大器,用于将传感器的输出电流转换为电压.跨阻放大器的概念很简单,即运算放大器(op amp)两端的反馈电阻(RF)使用欧姆定律VOUT= I × ...

最新文章

  1. Matlab编程与数据类型 -- 文本M文件
  2. 谁是全球最顶级AI实验室?
  3. 《剑指offer》-- 调整数组顺序使奇数位于偶数前面、顺时针打印矩阵、数字在排序数组中出现的次数
  4. Java 动态写轮眼 SharinganJPanel (整理)
  5. json添加元素 vue_详解通过JSON数据使用VUE.JS
  6. linux爬365租房没有数据,新手求助,LINUX下安装11G不能MOUNT数据库
  7. PS图片后期之超简易造光调色方法
  8. Java 简单五子棋程序的实现
  9. Oracle P6培训系列:01安装
  10. 机器学习之K均值聚类算法K-Means(python代码实现)
  11. jboss简单使用--刚开始接触,感觉还是比较详细的
  12. MOOC《Python语言程序设计》(第15次)Python计算生态概览(第九周)
  13. 英语常用的62个英语句型,学英语须掌握
  14. mmsegmentation导出onnx模型的问题
  15. java 快速开发平台
  16. 【python初级】创建一块纯色画布
  17. 单元测试界的高富帅,Pytest框架,手把手教学,从入门到精通(一)
  18. 跟同事杠上了,Apache Beanutils为什么被禁止使用?
  19. Opencv3.0 手写数字识别(Hog特征+SVM分类器)
  20. 网站上面无法显示woff、svg格式字体

热门文章

  1. STM32CubeIDE 下载与安装步骤(一)
  2. No package python27 available
  3. 西门子V90 PN伺服EPOS模式+FB284功能库使用示例教程(图文)
  4. lopatkin俄大神精简中文系统Windows 10 1607 Enterprise LTSB 2016 x86-x64 ZH-CN 2x1
  5. 常用游戏测试用例模板
  6. Java学习(1)——用显式转换显式字符在Unicode表中的位置
  7. 高校科研管理系统源代码_教育领域各大高校如何建设智慧校园?你的学校够数字化吗?...
  8. 主生产计划 操作教程 用友u8_【用友u8操作教程(用友财务软件u8实际操作教程)】免费在线试用_软件库_选软件网...
  9. c语言旋转bmp图片程序,C语言实现BMP图像处理(任意角度旋转)
  10. 蚂蚁区块链第17课 错误码指导大全