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

赣州市网站建设成都高新区规划国土建设局网站

赣州市网站建设,成都高新区规划国土建设局网站,网络推广加盟费多少,wordpress 显示文章分类目录 一、项目原理 二、环境准备 三、核心代码实现 1. 导入必要库 2. 定义关键函数 坐标点排序函数 透视变换函数 轮廓排序函数 图像显示函数 3. 主程序实现 图像预处理 轮廓检测与答题卡定位 透视变换矫正 答案识别与评分 四、实现效果 本文将介绍如何使用 Ope…

目录

一、项目原理

二、环境准备

三、核心代码实现

1. 导入必要库

2. 定义关键函数

坐标点排序函数

透视变换函数

轮廓排序函数

图像显示函数

3. 主程序实现

图像预处理

轮廓检测与答题卡定位

透视变换矫正

答案识别与评分

四、实现效果


本文将介绍如何使用 OpenCV 实现一个简单的答题卡识别与评分系统,通过图像处理技术自动识别考生答案并进行评分。


一、项目原理

答题卡识别的核心思路是通过图像处理技术定位答题卡区域,识别考生填涂的答案,再与标准答案对比进行评分。主要步骤包括:图像预处理、轮廓检测、透视变换、答案识别和自动评分。


二、环境准备

pip install numpy opencv-python

三、核心代码实现

1. 导入必要库

import numpy as np
import cv2

2. 定义关键函数

坐标点排序函数

用于对四边形的四个顶点进行排序(左上、右上、右下、左下):

def order_points(pts):# 一共有4个坐标点rect = np.zeros(shape=(4, 2), dtype="float32")  # 用来存储排序之后的坐标位置# 按顺序找到对应坐标0123分别是 左上,右上,右下,左下s = pts.sum(axis=1)  # 对pts矩阵的每一行进行求和操作,(x+y)rect[0] = pts[np.argmin(s)]rect[2] = pts[np.argmax(s)]diff = np.diff(pts, axis=1)  # 对pts矩阵的每一行进行求差操作,(y-x)rect[1] = pts[np.argmin(diff)]rect[3] = pts[np.argmax(diff)]return rect

透视变换函数

将倾斜的答题卡矫正为正视图:

def 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)

3. 主程序实现

图像预处理

# 读取图像
image = cv2.imread(r'./images/test_01.png')
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)[-2]
cv2.drawContours(contours_img, cnts, -1, (0, 0, 255), 3)docCnt = None# 根据轮廓大小进行排序,寻找答题卡轮廓(四边形)
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_t = four_point_transform(image, docCnt.reshape(4, 2))
warped_new = warped_t.copy()
warped = cv2.cvtColor(warped_t, cv2.COLOR_BGR2GRAY)# 阈值处理,将答案区域二值化
thresh = cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

答案识别与评分

# 找到每一个圆圈轮廓
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]questionCnts = []
# 筛选出符合条件的答案圆圈轮廓
for c in cnts:(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# 根据实际情况指定标准if w >= 20 and h >= 20 and 0.9 <= ar <= 1.1:questionCnts.append(c)# 按照从上到下进行排序
questionCnts = sort_contours(questionCnts, method="top-to-bottom")[0]
correct = 0
ANSWER_KEY = {0: 1, 1: 4, 2: 0, 3: 3, 4: 1}  # 正确答案# 每排有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表示填充# 通过计算非零点数量来判断是否选择这个答案thresh_mask_and = cv2.bitwise_and(thresh, thresh, mask=mask)total = cv2.countNonZero(thresh_mask_and)  # 统计灰度值不为0的像素数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_new, [cnts[k]], -1, color, 3)  # 绘制结果# 计算得分
score = (correct / 5.0) * 100
print("[INFO] score: {:.2f}%".format(score))# 显示得分
cv2.putText(warped_new, "{:.2f}%".format(score), (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
cv2.imshow("Original", image)
cv2.imshow("Exam", warped_new)
cv2.waitKey(0)

四、实现效果

程序会自动识别答题卡中的填涂区域,与标准答案对比后,用绿色标记正确答案,红色标记错误答案,并在图像上显示最终得分。

http://www.dtcms.com/a/568351.html

相关文章:

  • 网站建设开票内容些什么东莞企业网站建设设计
  • 做携程怎样的网站织梦网站图标更换
  • 易展 网站建设iis7创建网站
  • 建设企业网站的好处是什么军事新闻大事
  • 免费快速建站工具国家机构网站建设
  • 泉州网站建设托管263企业邮箱手机入口登录
  • 运城做网站哪家公司好wordpress cathy主题
  • 淘宝现在不能发布网站建设国外网页设计分享网站
  • 买模板做网站搬家网站怎么做
  • 网站建设阿里云网站服务器开发
  • 黑黑网站企业网站类型有哪些
  • 邳州做网站的公司python流星雨特效代码
  • 马云之前做的网站抖音代运营大概多少钱一个月
  • 建设外国商城网站城市宣传片制作公司
  • 云南省红河州蒙自建设局网站暴雪回归
  • 走出趣网站怎么做淮安经济技术开发区建设局网站
  • joomla! 1.5 网站建设基础教程网络营销公司注册找哪家
  • 网站后期维护管理黑龙江建设网查询平台
  • phpmysql网站开发实例重庆卓光科技有限公司
  • 更改网站模板内容网址在线生成短链接
  • 南昌金启网站建设郴州网站建设设计
  • 四川建设厅下载专区网站北京市企业网站建设
  • 网站右侧出现百度名片叫什么wordpress的页面和首页一样
  • 租车网站建设系统的设计知乎关键词搜索排名
  • 网络营销企业网站推广网店运营包括哪些
  • 网站后台怎么换图片建设专业网站哪家更专业
  • 开发网站广州wordpress如何导入
  • 网站建设制作要学什么中关村在线电脑网
  • 做一个介绍网站多少钱赣州金图网络科技有限公司
  • 网站管理建设落实报告烟台网站关键词推广