完整代码:

#导入工具包
import numpy as np
import argparse
import imutils
import cv2# 设置参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default="./images/test_03.png",help="path to the input image")
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")# 按顺序找到对应坐标0123分别是 左上,右上,右下,左下# 计算左上,右下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)
cv_show('blurred',blurred)
edged = cv2.Canny(blurred, 75, 200)
cv_show('edged',edged)# 轮廓检测
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
cv2.drawContours(contours_img,cnts,-1,(0,0,255),3)
cv_show('contours_img',contours_img)
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))
cv_show('warped',warped)
# Otsu's 阈值处理
thresh = cv2.threshold(warped, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cv_show('thresh',thresh)
thresh_Contours = thresh.copy()
# 找到每一个圆圈轮廓
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
cv2.drawContours(thresh_Contours,cnts,-1,(0,0,255),3)
cv_show('thresh_Contours',thresh_Contours)
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 = None# 遍历每一个结果for (j, c) in enumerate(cnts):# 使用mask来判断结果mask = np.zeros(thresh.shape, dtype="uint8")cv2.drawContours(mask, [c], -1, 255, -1) #-1表示填充cv_show('mask',mask)# 通过计算非零点数量来算是否选择这个答案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 += 1# 绘图cv2.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("Original", image)
cv2.imshow("Exam", warped)
cv2.waitKey(0)

test_03.png

运行效果:

python OpenCV 答题卡识别判卷相关推荐

  1. 深入学习OpenCV文档扫描OCR识别及答题卡识别判卷(文档扫描,图像矫正,透视变换,OCR识别)

    人工智能学习离不开实践的验证,推荐大家可以多在FlyAI-AI竞赛服务平台多参加训练和竞赛,以此来提升自己的能力.FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台.每周免费提供 ...

  2. OpenCV实战(二)——答题卡识别判卷

    代码见 https://github.com/skyerhxx/Answer-card-recognition-and-judgment 答题卡识别判卷 识别出考生选择的答案并能自动判分 Python ...

  3. opencv图像处理—项目实战:答题卡识别判卷

    哔站唐宇迪opencv课程--项目实战:答题卡识别判卷 [计算机视觉-OpenCV]唐宇迪博士教会了我大学四年没学会的OpenCV OpenCV计算机视觉实战全套课程(附带课程课件资料+课件笔记+源码 ...

  4. Opencv之答题卡识别判卷

    项目要求 提供一张答题卡图像,通过图像处理识别出答题卡上每个题的选项,与正确答案对比,得出分数并写在答题卡上. 代码实现过程 1.引入需要的库 import numpy as np import cv ...

  5. 17.答题卡识别判卷

    目录 1  项目介绍 2  代码分析 2.1  导入库 2.2  设置参数 2.3  设置正确答案 2.4  定义找到四个角点的函数 2.5  定义变换函数 2.6  定义 sort_contours ...

  6. 人工智能项目实战-使用OMR完成答题卡识别判卷

  7. opencv_python答题卡自动判卷

    opencv_python答题卡自动判卷 设定答题卡模板 该图像为答题卡的答题区域,黑色边框是为了能够在各种环境中轻易的检测,左部分和上部分的黑色矩形,是为能够定位到答题选项的坐标而设置,同时题目数量 ...

  8. 图像识别——(java使用opencv答题卡识别)

    具体算法实现:具体算法实现--opencvhttps://blog.csdn.net/qq_39246466/article/details/123819795 1.安装: 配置linux或windo ...

  9. 几步搞定!用Python实现答题卡识别!

    来源丨https://blog.csdn.net/qq_44805233?type=blog 大家好,我是辰哥~ 今天用Python对答题卡进行识别,答题卡素材图片如下: 思路 读入图片,做一些预处理 ...

最新文章

  1. python夹角余弦雷达图_性能可靠,可以全方位扫描的“千里眼”——先进的相控阵雷达...
  2. 徒手撸出一个类Flask微框架(三)根据业务进行路由分组
  3. 你想要的宏基因组-微生物组知识全在这(180801)
  4. fp格式图片_2020Pamp;I | 适马无反版100-400镜头亮相,fp全幅微单满足不同需求
  5. mui 打开openWindow新页面不读取缓存的设置/mui中h5清除缓存页面的办法
  6. 接口里面的方法都是抽象方法吗_单元格区域选取,竟然有这么多种方法,你都造吗?...
  7. eclipse的jsp第一行代码报错_机器学习之AdaBoost算法及纯python代码手工实现
  8. 梯度下降和随机梯度下降_梯度下降和链链接系统
  9. 每天一道算法题(39)——含有重复字符的全排列
  10. STM32学习及应用笔记一:SysTick定时器学习及应用
  11. dll注入工具_bypassUAC amp;amp; DLL劫持
  12. Vue脚手架组件开发常见问题
  13. Linux -- 查找文件内容或文件位置
  14. 《通信原理》用matlab实现加性高斯白噪声信道实验
  15. 前端如何来做权限管理?
  16. 计算机按()的程序进行工作,2016计算机一级考试WPS练习题及答案
  17. 新手指南:顶象验证码如何接入微信小程序?
  18. win32 打印机任务管理的 node 模块 (3)详解Win32 Spooler API 获取打印机列表及状态
  19. Ubuntu16 桌面卡死 重启桌面
  20. pandas排序csv文件并且按时间分类 python学习 pandas应用

热门文章

  1. 大学生职业规划的十大误区
  2. vnc连接后没桌子黑屏_vnc win10,vnc远程桌面黑屏只有光标
  3. (转)海量用户积分排名算法探讨
  4. 我的世界潜影盒计算机存储器,教程/潜影盒储存 _ 《我的世界》中文Minecraft Wiki:最详细的官方我的世界百科...
  5. 连扔1000次硬币 出现过连续10次正面的概率(递归问题求解)
  6. 国家大数据政策文件汇编(2022年)(附下载)
  7. KMP / EXKMP
  8. 【Java 28岁了】一个有趣的例子,再推荐一些经典好书(文末惊喜福利)
  9. 一曲相思用计算机弹,倩影留声玩家故事第44期:《谱一曲相思,弹一首缠绵,演绎最美流年》上集...
  10. 单元测试,驱动模块和桩模块的概念是什么?