OPENCV中的批改答题卡

2023-10-27

@Fu Xianjun. All Rights Reserved.


前言

批改答题卡对于许多来说简直就是折磨,眼睛都看花了还要继续批改,还要保持正确率,实在是太费老师了,所以我们使用OPENCV来解决这个问题,自动批改答题卡


提示:以下是本篇文章正文内容,下面案例可供参考

一、为什么使用OPENCV?

不要问,问就是因为我只学了这个,好,下面开始了

二、使用步骤

1.引入库

代码如下(示例):

import cv2
import numpy as np

2.写入基本函数,这样打包好就可以套用了,多少方便不知道

代码如下(示例):

import cv2
import numpy as np

def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

def order_points(pts):
    rect = np.zeros((4,2),dtype= "float32")
    s =pts.sum(axis = 1)
    rect[0] = pts[np.argmin(s)]
    rect[2] = pts[np.argmax(s)]
    d = np.diff(pts,axis= 1)
    rect[1] = pts[np.argmin(d)]
    rect[3] = pts[np.argmax(d)]
    return rect
def four_point_transform(img,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((br[0]-tr[0])**2+(br[1]-tr[1])**2)
    heightB = np.sqrt((bl[0]-tl[0])**2+(bl[1]-tl[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)
    warp = cv2.warpPerspective(img,M,(maxWidth,maxHeight))
    return warp

def sort_contours(cnts,method= "left-to-right"):
    reverse = False
    i = 0 
    if method == "right-to-left" or method == "bottom-to-top":
        reverse = True
    if method == "top-to-bottom" or method == "bottom-to-top":
        i=1
    boundingBoxes = [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

3.导入图片利用上面的函数来进行处理,没错就是这么简单

img = cv2.imread("test_01.png")
contours_img= img.copy()
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gs = cv2.GaussianBlur(gray,(5,5),0)
edge = cv2.Canny(gs,75,200)
cnts = cv2.findContours(edge,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
cv2.drawContours(contours_img,cnts,-1,(255,255,0),2)
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 = approx
            break
warp = four_point_transform(gray,docCnt.reshape(4,2))

thresh = cv2.threshold(warp,0,255,cv2.THRESH_OTSU|cv2.THRESH_BINARY_INV)[1]
thresh_contours = thresh.copy()
cnts =cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
cv2.drawContours(thresh_contours,cnts,-1,(255,255,0),2)

question_Cnts=[]
ANSWER_KEY = {0:1,1:4,2:0,3:3,4:1}
for c in cnts:
    (x,h,w,h) = cv2.boundingRect(c)
    ar = w/float(h)
    if w >= 20 and h >= 20 and ar>=0.9 and ar<=1.1:
        question_Cnts.append(c)

question_Cnts = sort_contours(question_Cnts,method="top-to-bottom")[0]
correct =0
for (q,i) in enumerate(np.arange(0,len(question_Cnts),5)):
    cnts =sort_contours(question_Cnts[i:i+5])[0]
    bubbled = None
    for (j,c) in enumerate(cnts):
        mask = np.zeros(thresh.shape,dtype ="uint8")
        cv2.drawContours(mask,[c],-1,255,-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 +=1
        cv2.drawContours(warp,[cnts[k]],-1,color,3)
score = (correct/5.0)*100

cv_show("warp",warp)

下面是原图和效果图对比,简单明了


在这里插入图片描述
在这里插入图片描述

总结

非常的实用有没有,虽然有一点点的复杂,但这个是值得的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OPENCV中的批改答题卡 的相关文章

随机推荐

  • Cannot read property 'newLine' of undefined

    angularjs报错 ERROR in src main ts Module build failed TypeError Cannot read property newLine of undefined at Object getNe
  • GitLab(Gitee)配置SSH key

    1 我们已经有了gitlab的账户 项目组已经将我们添加到了group 2 打开git bash 输入命令 ls al ssh 如果显示如下图 则表示生成过key 可以去执行第4个步骤 否则的话执行第三个步骤生成key 3 输入命令 ssh
  • 快乐的强化学习1——Q_Learning及其实现方法

    快乐的强化学习1 Q Learning及其实现方法 学习前言 简介 Q Learning算法的实现 具体实现代码 GITHUB下载连接 学习前言 刚刚从大学毕业 近来闲来无事 开始了机器学习的旅程 深度学习是机器学习的重要一环 其可以使得机
  • 深入AMS源码(四)——ActivityManagerService的进程管理

    1 AMS中的进程管理 final ArrayList
  • 2023年大数据与计算国际会议 (WBDC 2023)

    会议简介 Brief Introduction 2023年大数据与计算国际会议 WBDC 2023 会议时间 2023年11月17 19日 召开地点 中国 西安 大会官网 www iwbdc org 2023年大数据与计算国际会议 WBDC
  • 机器翻译系统,主要划分为哪几大类型?

    直到20世纪80年代 一些机器翻译系统采用了两种方法 在这些方法中 源语言文本被分析转换成抽象表达形式 随后利用一些程序 通过识别词结构 词法分析 和句子结构 句法分析 解决歧义问题 其中有一种方法将抽象表达设计为一种与具体语种无关的 中间
  • Arduino学习笔记

    一 引脚 二 函数介绍 1 pinMode pin mode 引脚配置成输入或者输出 其中mode可以为INPUT或者OUTPUT 例如 pinMode 7 INPUT 将引脚7定义为输入接口 2 digitalWrite pin valu
  • OAuth2简介生成accessToken(一)

    1 OAuth3需要引入的依赖 版本号根据实际情况添加哦
  • HTTP中application/x-www-form-urlencoded字符说明

    一 概述 在学习ajax的时候 如果用post请求 需要设置如下代码 ajax setRequestHeader content type application x www form urlencoded 虽然知道需要这么做 但是不知道a
  • postman pre-request scripts 导入js文件_Postman 高级用法指南

    Postman是一款强大的API接口测试工具 有许多不容易发现的好用的功能 下面简单介绍其中一部分功能 详细内容可以参考文档 官方还有视频教程 非常方便入手 后续本博客会持续提供一些Postman使用的细节技巧 方便大家用Postman进行
  • strstr函数底层逻辑实现

    一 函数介绍 char strstr const char haystack const char needle 功能 在字符串haystack中查找字符串needle出现的位置 参数 haystack 源字符串首地址 needle 匹配字
  • C++读写txt文件(基本操作1)

    本博客主要写了用C 读写txt本文的基本操作 最简单的写入和读出两个基本操作 本程序的功能是向Test txt文件文件写入字符串 This is a Test12 和读取字符串 This is a Test12 并且将读取到的字符串存到te
  • python组件

    1 生成6位数字随机验证码 import random import string def num code length 6 生成长度为length的数字随机验证码 param length 验证码长度 return 验证码 return
  • STM32—ADC和DMA的应用之电流检测(第二部分:电流检测电路与数据处理)

    文章目录 前言 一 电流检测原理 1 霍尔效应 2 CC6902电流传感器 二 电流检测电路 三 数据处理 前言 前一部分介绍了如何配置ADC和DMA 这一部分介绍在硬件部分如何实现电流检测以及检测到电流后的数据处理 一 电流检测原理 1
  • QT-CSV文件读写

    QT CSV文件读写 前言 一 CSV文件初始化 二 CSV写入 三 CSV读取 四 程序链接 前言 csv文件之所以被用户推荐使用 我觉得即可以用excel打开 同时也是可以用文本编辑器打开 而且文本内容的显示也是比较有规律 用户查看起来
  • 2013中国数据库技术大会

    http www cn21 com cn meet 2013sjk yjjb html
  • Web 应用程序——我的心理备忘单

    介绍 本文是 持续交付 HTML 到 Kubernetes 的一部分 虽然我迫不及待地想深入了解分布式系统的细节 但我发现自己处于一个不愉快的境地 我认为最好从前端开始写 那是因为网络应用程序是当今的标准 在多个云中部署的 ArgoCD K
  • 图像增广:强化深度学习的视觉表现力

    目录 摘要 1 图像增广简介 2 图像增广的原理 3 常见的图像增广技术 4 如何在实际项目中应用图像增广 5 实际应用 摘要 当今 深度学习已经在计算机视觉领域取得了令人瞩目的成就 图像增广作为一种数据处理技术 让我们在使用有限的图像数据
  • Lipschitz常数、Lipschitz条件

    参考 https www zybang com question dd732fbc5a0224c6526bcdfba613b53c html https baike baidu com item lipschitz E6 9D A1 E4
  • OPENCV中的批改答题卡

    Fu Xianjun All Rights Reserved 文章目录 前言 一 为什么使用OPENCV 二 使用步骤 1 引入库 2 写入基本函数 这样打包好就可以套用了 多少方便不知道 3 导入图片利用上面的函数来进行处理 没错就是这么