当前位置: 首页 > article >正文

答题卡检测

答题卡识别评分代码完整讲解1. 答题卡处理流程图1) 读取答题卡图像并进行灰度化、模糊处理和边缘检测2) 定位答题卡区域并进行透视变换3) 通过阈值处理和轮廓分析检测填涂的选项泡泡4) 将检测结果与标准答案对比计算得分。系统支持自定义参数调整包括泡泡最小尺寸、宽高比范围等能够处理不同形态的答题卡。5) 最终输出评分结果并在图像上标记正确/错误选项。2. Python 代码及详细讲解导入库import cv2import numpy as npimport matplotlib.pyplot as plt功能讲解cv2: OpenCV图像处理库用于图像处理numpy: 数值计算处理坐标和矩阵运算matplotlib.pyplot: 可视化用于绘制调试图像或流程图参数设置image_path rF:\project\pytorch_project\CV学习\image.pngANSWER_KEY {0:1, 1:4, 2:0, 3:3, 4:1}MIN_BUBBLE_W, MIN_BUBBLE_H 10, 10ASPECT_RATIO_MIN, ASPECT_RATIO_MAX 0.5, 1.5功能讲解image_path: 答题卡图片路径ANSWER_KEY: 正确答案索引字典MIN_BUBBLE_W/H: 泡泡最小尺寸过滤噪点ASPECT_RATIO_MIN/MAX: 宽高比范围过滤非圆形轮廓辅助函数显示图像def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()功能讲解用于显示图像窗口便于调试辅助函数轮廓排序def sort_contours(cnts, methodleft-to-right):# 根据指定方向排序轮廓并返回排序后的轮廓列表...功能讲解method可选: left-to-right, top-to-bottom, right-to-left, bottom-to-top辅助函数四点排序def order_points(pts):# 将四个角点按顺序排列为 top-left, top-right, bottom-right, bottom-left...功能讲解用于透视变换前整理角点顺序辅助函数透视变换def four_point_transform(image, pts):rect order_points(pts)(tl, tr, br, bl) rectwidthA 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]], dtypefloat32)M cv2.getPerspectiveTransform(rect, dst)warped cv2.warpPerspective(image, M, (maxWidth, maxHeight))return warped功能讲解将答题卡校正为俯视视角保证泡泡排列规则主流程读取图像并预处理img cv2.imdecode(np.fromfile(image_path, dtypenp.uint8), cv2.IMREAD_COLOR)gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)blurred cv2.GaussianBlur(gray, (5,5), 0)edged cv2.Canny(blurred, 75, 150)功能讲解读取图像灰度化高斯模糊去噪Canny边缘检测主流程检测答题卡轮廓cnts, hierarchy cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cnts sorted(cnts, keycv2.contourArea, reverseTrue)docCnt Nonefor 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]功能讲解泡泡为白色背景黑色主流程检测泡泡cnts, hierarchy cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)questionCnts []for c in cnts:(x, y, w, h) cv2.boundingRect(c)ar w / float(h)if w MIN_BUBBLE_W and h MIN_BUBBLE_H and ASPECT_RATIO_MIN ar ASPECT_RATIO_MAX:questionCnts.append(c)功能讲解根据尺寸和宽高比过滤噪点得到候选泡泡主流程排序泡泡questionCnts, _ sort_contours(questionCnts, methodtop-to-bottom)bubbles_per_row 5rows []for i in range(0, len(questionCnts), bubbles_per_row):row_cnts questionCnts[i:ibubbles_per_row]row_cnts, _ sort_contours(row_cnts, methodleft-to-right)rows.append(row_cnts)功能讲解先按行排序再按列排序主流程评分correct 0for q, row_cnts in enumerate(rows[:len(ANSWER_KEY)]):bubbled Nonefor j, c in enumerate(row_cnts):mask np.zeros(thresh.shape, dtypeuint8)cv2.drawContours(mask, [c], -1, 255, -1)mask cv2.bitwise_and(thresh, thresh, maskmask)total cv2.countNonZero(mask)if bubbled is None or total bubbled[0]:bubbled (total, j)k ANSWER_KEY[q]color (0,0,255)if bubbled and k bubbled[1]:color (0,255,0)correct 1cv2.drawContours(warped, [row_cnts[k]], -1, color, 3)功能讲解每行找到涂黑最多泡泡对比答案并标记正确/错误主流程输出分数score (correct / len(ANSWER_KEY)) * 100print(fScore: {score}%)cv2.putText(warped, fScore: {score:.2f}%, (10, 20),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)功能讲解计算总分并在图像上显示import cv2 import numpy as np import matplotlib.pyplot as plt # 参数设置 image_path rF:\project\pytorch_project\CV学习\image.png # 正确答案字典每题的索引对应答案位置 ANSWER_KEY {0:1, 1:4, 2:0, 3:3, 4:1} # 自动适配泡泡的最小宽高和宽高比范围 MIN_BUBBLE_W, MIN_BUBBLE_H 10, 10 ASPECT_RATIO_MIN, ASPECT_RATIO_MAX 0.5, 1.5 # 支持略长或略扁的泡泡 # 辅助函数 def cv_show(name, img): 显示图像 cv2.imshow(name, img) cv2.waitKey(0) cv2.destroyAllWindows() def sort_contours(cnts, methodleft-to-right): 对轮廓进行排序 method: left-to-right, top-to-bottom, right-to-left, bottom-to-top if len(cnts) 0: return [], [] reverse False i 0 # 0: x, 1: y if method in [right-to-left, bottom-to-top]: reverse True if method in [top-to-bottom, bottom-to-top]: i 1 # 获取轮廓的边界矩形 boundingBoxes [cv2.boundingRect(c) for c in cnts] # 按指定方向排序 (cnts, boundingBoxes) zip(*sorted(zip(cnts, boundingBoxes), keylambda b: b[1][i], reversereverse)) return list(cnts), list(boundingBoxes) def order_points(pts): 将四个点按顺序排列 [top-left, top-right, bottom-right, bottom-left] rect np.zeros((4,2), dtypefloat32) s pts.sum(axis1) rect[0] pts[np.argmin(s)] # top-left rect[2] pts[np.argmax(s)] # bottom-right diff np.diff(pts, axis1) rect[1] pts[np.argmin(diff)] # top-right rect[3] pts[np.argmax(diff)] # bottom-left return rect def four_point_transform(image, pts): 对答题卡进行透视变换得到俯视图 rect order_points(pts) (tl, tr, br, bl) rect # 计算宽度 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]], dtypefloat32) # 计算透视变换矩阵 M cv2.getPerspectiveTransform(rect, dst) warped cv2.warpPerspective(image, M, (maxWidth, maxHeight)) return warped # 主流程 # 1. 读取原图 img cv2.imdecode(np.fromfile(image_path, dtypenp.uint8), cv2.IMREAD_COLOR) if img is None: raise FileNotFoundError(f无法读取输入图像: {image_path}) cv_show(Original, img) # 2. 灰度化 高斯模糊 边缘检测 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blurred cv2.GaussianBlur(gray, (5,5), 0) # 去噪 cv_show(Blurred, blurred) edged cv2.Canny(blurred, 75, 150) # 边缘检测 cv_show(Edged, edged) # 3. 找最大四边形轮廓作为答题卡做透视变换 cnts, hierarchy cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts sorted(cnts, keycv2.contourArea, reverseTrue) docCnt None for c in cnts: peri cv2.arcLength(c, True) approx cv2.approxPolyDP(c, 0.02*peri, True) if len(approx) 4: docCnt approx break if docCnt is None: raise ValueError(未找到答题卡四边形轮廓) # 透视变换得到俯视图 warped four_point_transform(gray, docCnt.reshape(4,2)) cv_show(Warped, warped) # 4. 二值化反转OTSU thresh cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] cv_show(Threshold, thresh) # 5. 找轮廓 cnts, hierarchy cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 6. 筛选可能的泡泡轮廓 questionCnts [] for c in cnts: (x, y, w, h) cv2.boundingRect(c) ar w / float(h) if w MIN_BUBBLE_W and h MIN_BUBBLE_H and ASPECT_RATIO_MIN ar ASPECT_RATIO_MAX: questionCnts.append(c) # 7. 全局排序先 top-to-bottom questionCnts, _ sort_contours(questionCnts, methodtop-to-bottom) if len(questionCnts) 0: raise ValueError(未检测到有效 bubbles请检查图像质量或阈值) # 每行泡泡数量可修改 bubbles_per_row 5 rows [] for i in range(0, len(questionCnts), bubbles_per_row): row_cnts questionCnts[i:ibubbles_per_row] row_cnts, _ sort_contours(row_cnts, methodleft-to-right) rows.append(row_cnts) # 8. 评分 correct 0 for q, row_cnts in enumerate(rows[:len(ANSWER_KEY)]): bubbled None for j, c in enumerate(row_cnts): # 生成泡泡掩膜 mask np.zeros(thresh.shape, dtypeuint8) cv2.drawContours(mask, [c], -1, 255, -1) # 与二值化图像结合 mask cv2.bitwise_and(thresh, thresh, maskmask) total cv2.countNonZero(mask) # 统计白色像素数量 if bubbled is None or total bubbled[0]: bubbled (total, j) # 对比答案 k ANSWER_KEY[q] color (0,0,255) # 红色默认错误 if bubbled and k bubbled[1]: color (0,255,0) # 绿色表示正确 correct 1 # 绘制标记 cv2.drawContours(warped, [row_cnts[k]], -1, color, 3) # 9. 计算总分 score (correct / len(ANSWER_KEY)) * 100 print(fScore: {score}%) cv2.putText(warped, fScore: {score:.2f}%, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2) cv_show(Graded, warped)

相关文章:

答题卡检测

答题卡识别评分代码完整讲解1. 答题卡处理流程图1) 读取答题卡图像并进行灰度化、模糊处理和边缘检测;2) 定位答题卡区域并进行透视变换;3) 通过阈值处理和轮廓分析检测填涂的选项泡泡;4) 将检测结果与标准答案对比计算得分。系统支持自定义参…...

程序员如何利用自然语言处理技术

程序员如何利用自然语言处理技术关键词:程序员、自然语言处理、技术应用、算法原理、实战案例摘要:本文旨在全面探讨程序员如何利用自然语言处理(NLP)技术。从自然语言处理的背景知识入手,详细阐述其核心概念、算法原理…...

简单的c语言分析 汇编代码

1、STR是ARM汇编中的内存访问指令:表示字数据写入,用于将一个32位的字数据写入到指令中指定的内存单元。 比如STR R0, [R1, #0x100]; 表示将R0中的字数据保存到内存单元(R10x100)中。2、 BL 指令BL 指令的格式为: BL{条…...

ALS(Approximate Logic Synthesis) 综述| Approximate Logic Synthesis: A Survey

记一下ALS的综述笔记。Introduction 讲近似电路计算的两种分类,大致介绍了怎么对误差建模。Method for error estimation 讲如何计算近似电路和精确电路的误差。包括: A. error matrix hamming distance (max & average)error rateapproximate effic…...

keil+Arm Visual Hardware(AVH)入门

1.准备 下载keil5,最新版本5.37(早期版本没有AVH),激活professional版本,plus和Essential版本不行 2.安装好keil后,建立VHT工程,此处以arm cortex-M4为例,按照下图选择设备3.配置标准接口,下面以…...

Google Earth Engine(GEE)——矢量数据集合和影像集合的连接join,给矢量集合添加到两景影像作为矢量集合的属性

本次教程主要是加载一个矢量集合,然后通过设定指定的时间条件和地理条件,和指定的时间窗口进行筛选应用于Landsat8 影像,最后将筛选出的影像加载到矢量集合中。 矢量数据集合: Feature Index Dy (Long) Hr (Long) Location N (String) Mo (Long) Year (Long) system:index…...

全球台锯:家具家装与建筑工程刚需驱动下的稳增扩容,2026-2032年CAGR3.8%,2032年规模9.6亿美元

在制造业与木工行业的蓬勃发展浪潮中,台锯作为核心工具,其市场表现备受瞩目。QYResearch调研显示,2025年全球台锯市场规模大约为7.41亿美元,预计2032年将达到9.6亿美元,2026-2032期间年复合增长率(CAGR&…...

解决报错:ORA-12541:TNS:无监听程序

1.重新配置监听 找到监听程序配置,右键已管理员身份运行 选择第二个:重新配置 这个一般没什么好选的 默认选定的协议TCP,继续下一步 默认的否 继续下一步,完成监听重新配置 之后进行测试看能否连上 2.本地Net服务名配置 …...

QT(二):Qt相关控件的使用和设置,Qt对话框的使用,画图事件的创建和设置,线程和锁的创建利用,网络编程,TCP和UDP客户端及服务器的创建,SQLITE数据库,QTableWidget控件的使用

一、相关控件及操作配置1、QPushButton & QtoolButton(按钮)setText(QString) ---- 设置按钮上的内容setFixedSize(int w, int h) --- 设置固定大小setFixedHeight(int) --- 设置固定高度setFixedwidth(int) --- 设置固定宽度setMaximumSize(…...

AF350标记α-银环蛇d素,AF350-a-Bungarotoxin核心功能与应用场景

α-Bungarotoxin AF350,AF350标记α-银环蛇d素,AF350-a-Bungarotoxin,AF350-α-BTX,银环蛇d荧光标记一、试剂本质与结构解析α-Bungarotoxin, AF350(以下简称“AF350-α-BTX”)是一种由台湾银环蛇d液中提取…...

10分钟上手SIMP:从安装到基础配置的快速入门指南

10分钟上手SIMP:从安装到基础配置的快速入门指南 【免费下载链接】SIMP A system automation and configuration management stack targeted toward operational flexibility and policy compliance. 项目地址: https://gitcode.com/gh_mirrors/si/SIMP SIMP…...

基于深度学习的本科毕业设计

1 适用对象 本科生关于目标检测、语义分割的毕业设计。 2 深度学习基础知识 2.1 深度学习理论 (1) 吴恩达深度学习视频(转载)https://www.bilibili.com/video/BV1Gm421u73z/?spm_id_from333.337.search-card.all.click&v…...

【亲测免费】 探索未来打印体验:ESP3D 智能3D打印机固件

探索未来打印体验:ESP3D 智能3D打印机固件 【免费下载链接】ESP3D FW for ESP8266/ESP8285/ESP32 used with 3D printer 项目地址: https://gitcode.com/gh_mirrors/es/ESP3D 项目介绍 ESP3D是一个创新的开源固件,专为ESP8266和ESP32芯片设计&am…...

探索Bunny项目:一个智能数据处理与分析的利器

探索Bunny项目:一个智能数据处理与分析的利器 【免费下载链接】Bunny A family of lightweight multimodal models. 项目地址: https://gitcode.com/gh_mirrors/bunny/Bunny 项目简介 是一款由BAAI-DCAI团队开发的开源项目,它旨在提供高效、灵活…...

IT从业人员能做哪些兼职-总有一款适合你(非常详细)零基础入门到精通,收藏这一篇就够了

作为IT从业者,在闲暇时间可以尝试以下一些兼职: 1. 程序员兼职:在各大IT招聘网站上,有很多针对IT从业者的兼职职位,可以根据自己的技能和时间情况选择相应的岗位,如开发小程序、网站等。 2. IT培训师&…...

TextAttack API详解:打造属于你的NLP对抗性训练框架

TextAttack API详解:打造属于你的NLP对抗性训练框架 【免费下载链接】TextAttack TextAttack 🐙 is a Python framework for adversarial attacks, data augmentation, and model training in NLP https://textattack.readthedocs.io/en/master/ 项目地…...

[特殊字符]现代机器人学课程:理论与实践的完美融合[特殊字符]

🤖现代机器人学课程:理论与实践的完美融合🚀 【免费下载链接】modern-robotics-course This repository is all the lessons for Modern Robotics Course. 项目地址: https://gitcode.com/gh_mirrors/mo/modern-robotics-course 在科…...

带你解开“人寿类商业保险”的真面目

本内容较浅显易懂的简述了保险险种的分类、查询、配置,以及保险中的掩藏项。主要以个人所购买的两款人寿类商业保险为例说明。持续更新,原创不易! 目录: 一、保险险种的分类 1、意外险 2、寿险 3、重疾险 4、医疗险 二、保…...

【亲测免费】 SCUT_thesis 开源项目使用教程

SCUT_thesis 开源项目使用教程 【免费下载链接】SCUT_thesis 华南理工大学硕博士学位论文LaTeX模板。Latex templates for the thesis of South China University of Technology 项目地址: https://gitcode.com/gh_mirrors/sc/SCUT_thesis 1. 项目的目录结构及介绍 SCU…...

win11+vs2019 解决qt界面中文乱码问题和linguist不识别或乱码问题

1.修改文档编码联机搜索下载插件。安装这个插件便于查看及修改当前文档编码。将你含有 tr("中文") 的文档编码全部换成UTF-8(BOM)(解决linguist不识别或乱码问题)。界面还是乱码的话,把编译选项也加上。项目 → 属性 → C/C → 命令…...

AperiSolve 开源项目教程

AperiSolve 开源项目教程 【免费下载链接】AperiSolve Steganalysis web platform 项目地址: https://gitcode.com/gh_mirrors/ap/AperiSolve 1. 项目的目录结构及介绍 AperiSolve 项目的目录结构如下: AperiSolve/ ├── app/ │ ├── __init__.py │…...

Deepagents中间件详解:如何自定义和扩展代理能力

Deepagents中间件详解:如何自定义和扩展代理能力 【免费下载链接】deepagents Deepagents is an agent harness built on langchain and langgraph. Deep agents are equipped with a planning tool, a filesystem backend, and the ability to spawn subagents - m…...

计算无人机巡逻覆盖地块数Java题解

问题描述 一块地用一个从 0 开始索引的二维二进制矩阵 block 表示,其中 0 表示空闲地块,1 表示放有障碍物的地块。在每个测试用例中,地的左上角永远是空闲的。一架无人机面向右侧,从左上角开始巡逻。无人机将一直前进,直到抵达的边界或遇到障碍物地块时,无人机将会顺时针…...

Tiny Wings 项目推荐

Tiny Wings 项目推荐 【免费下载链接】tiny-wings Remake of the popular iPhone game. 项目地址: https://gitcode.com/gh_mirrors/ti/tiny-wings 1、项目的基础介绍和主要的编程语言 Tiny Wings 是一个开源项目,旨在重现流行的 iPhone 游戏 Tiny Wings 的…...

java毕业设计下载(全套源码+配套论文)——基于java+JSP+J2EE的户籍管理系统设计与实现(毕业论文+程序源码)

基于javaJSPJ2EE的户籍管理系统设计与实现(毕业论文程序源码) 大家好,今天给大家介绍基于javaJSPJ2EE的户籍管理系统设计与实现,更多精选毕业设计项目实例见文末哦。 文章目录: 基于javaJSPJ2EE的户籍管理系统设计与…...

java毕业设计下载(全套源码+配套论文)——基于java+JSP+MyEclipse的网上订餐系统设计与实现(毕业论文+程序源码)

基于javaJSPMyEclipse的网上订餐系统设计与实现(毕业论文程序源码) 大家好,今天给大家介绍基于javaJSPMyEclipse的网上订餐系统设计与实现,更多精选毕业设计项目实例见文末哦。 文章目录: 基于javaJSPMyEclipse的网上…...

材料新人成长地图:福尔蒂应用工程师首年实战——从GMP取样到DOE设计

刚入行那会儿,我常被几个词绕得晕头转向:GMP取样是什么流程?DOE设计到底怎么搭实验?为什么客户一句“这个色差不稳定”,我就得翻三遍配方表、查两次干燥参数、再跑一趟车间复核喂料精度?直到加入青岛福尔蒂…...

Swagger2 自定义排序

分享一下SpringSwagger2在线文档自定义排序的代码。 这里参考swagger2 接口排序_swagger接口排序-CSDN博客提供的思路&#xff0c;并在此基础上做了优化。 1、引用pom信息 <!--swagger依赖(pojo注解)--><dependency><groupId>io.swagger</groupId>&l…...

C语言简易计算器程序的实现与优化

目录 一、基础版本&#xff1a;简单直接的功能实现 完整代码 版本分析 优点 缺点 二、进阶版本&#xff1a;函数指针数组优化 完整代码 版本分析 核心优化点 优点 三、改进版本&#xff1a;功能解耦与模块化 完整代码 版本分析 核心设计思想&#xff1a;模块化解…...

优秀堡垒机功能学习

用户管理 1. 用户&#xff0c;角色 2. 资产授权给角色&#xff08;用户&#xff09;资源管理 1. 新建&#xff1a;新建&#xff0c;导入&#xff0c;同步第三方云&#xff0c;同步用户自己的系统 2. 更新&#xff1a;定时同步&#xff0c;定时检测状态 3. Group&#xff1a;资源…...